Spring Boot整合Swagger2详解

一、Swagger概述

Swagger官网 :http://swagger.io/

1、Swagger简介

Swagger 是一个规范和完整的框架,用于生成、描述、功能调用测试和可视化 RESTful 风格的在线的接口文档工具。

Swagger 是一套基于 OpenAPI 规范(OpenAPI Specification,OAS)构建的开源工具。

Swagger 提供了一套通过代码和注解自动生成可视化的 RESTful 风格的API文档,符合 RESTful API设计的行业标准。

OAS本身是一个API规范,它用于描述一整套API接口,包括一个接口是哪种请求方式、哪些参数、哪些header等,都会被包括在这个文件中。它在设计的时候通常是YAML格式,这种格式书写起来比较方便,而在网络中传输时又会以json形式居多,因为json的通用性比较强。

2、Swagger主要提供了几种开源工具

  • Swagger Codegen:通过Codegen 可以将描述文件生成html格式和cwiki形式的接口文档,同时也能生成多钟语言的服务端和客户端的代码。支持通过jar包,docker,node等方式在本地化执行生成。也可以在后面的Swagger Editor中在线生成。
  • Swagger UI:提供了一个可视化的UI页面展示描述文件。接口的调用方、测试、项目经理等都可以在该页面中对相关接口进行查阅和做一些简单的接口请求。该项目支持在线导入描述文件和本地部署UI项目。
  • Swagger Editor:基于浏览器的编辑器,该编辑支持实时预览描述文件的更新效果。也提供了在线编辑器和本地部署编辑器两种方式。
  • Swagger Inspector:感觉和postman差不多,是一个可以对接口进行测试的在线版的postman。比在Swagger UI里面做接口请求,会返回更多的信息,也会保存你请求的实际请求参数等数据。
  • Swagger Hub:集成了上面所有项目的各个功能,你可以以项目和版本为单位,将你的描述文件上传到Swagger Hub中。在Swagger Hub中可以完成上面项目的所有工作,需要注册账号,分免费版和收费版。

3、Springfox介绍

由于 Spring的流行,Marty Pitt编写了一个基于 Spring的组件 swagger-springmvc,用于将 Swagger集成到 SpringMVC中来,而 Springfox则是从这个组件发展而来。

通常 Spring Boot项目整合 Swagger2需要用到两个依赖:springfox-swagger2和springfox-swagger-ui,用于自动生成swagger文档。

  • springfox-swagger2:这个组件的功能用于帮助我们自动生成描述API的json文件
  • springfox-swagger-ui:就是将描述API的json文件解析出来,用一种更友好的方式呈现出来

官方 UI很多人不太喜欢,觉得不太符合国人的使用习惯。通常我们通过引入 swagger-bootstrap-ui依赖来替换官方 UI。

4、Swagger常用注解

更多注解和使用说明,请查看Github:https://github.com/swagger-api/swagger-core/wiki/Annotations

@Api:用在请求的类上,表示对类的说明(不配置默认是按类名驼峰变下划线显示)
    value:该参数没什么意义,在UI界面上也看到,所以不需要配置"
    tags:说明该类的作用,可以在UI界面上看到的注解
    description:对api资源的描述
    basePath:基本路径
    position:如果配置多个Api 想改变显示的顺序位置
    produces:如 “application/json, application/xml”
    consumes:如 “application/json, application/xml”
    protocols:协议类型,如: http, https, ws, wss.
    authorizations:高级特性认证时配置
    hidden:配置为true ,将在文档中隐藏

@ApiOperation:用在请求的方法上,说明方法的用途、作用
    value:说明方法的用途、作用
    tags:如果设置这个值、value的值会被覆盖
    notes:方法的备注说明
    description:对api资源的描述

@ApiImplicitParams:用在请求的方法上,表示一组参数说明
    @ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
        name:参数名
        value:参数的汉字说明、解释
        required:参数是否必须传
        paramType:参数放在哪个地方
            · header --> 请求参数的获取:@RequestHeader
            · query --> 请求参数的获取:@RequestParam
            · path(用于restful接口)--> 请求参数的获取:@PathVariable
            · div(不常用)
            · form(不常用)    
        dataType:参数类型,默认String,其它值dataType="Integer"       
        defaultValue:参数的默认值

@ApiParam() 用于方法,参数,字段说明;表示对参数的添加元数据(说明或是否必填等)
    name:参数名
    value:参数说明
    required:是否必填

@ApiResponses:用在请求的方法上,表示一组响应
    @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
        code:数字,例如400
        message:信息,例如"请求参数没填好"
        response:抛出异常的类

@ApiModel:用于pojo类上,描述一个Model的信息
(一般用在请求参数无法使用@ApiImplicitParam注解进行描述的时候,比如使用@RequestBody这样的场景)

@ApiModelProperty:用在属性上,描述一个model的属性

@ApiIgnore:注解类、参数、方法,注解后将不在Swagger UI中显示

二、Spring Boot整合Swagger2

SpringBoot 2.3.12.RELEASE版本项目集成 Swagger2的步骤:

  • 引入 Swagger2依赖
  • 添加 Swagger2配置类
  • 项目中给Controller添加Swagger注解
  • 访问 Swagger2的UI界面

1、引入 Swagger2依赖

创建项目引入 Swagger2依赖。

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

2、添加 Swagger2配置类

在项目中开启了 Swagger的功能:添加一个@EnableSwagger2注解接口。可以添加在SpringBoot的启动类上或者Swagger2配置类上。

在config文件夹下,添加一个Swagger2Config类。

  • 添加 @EnableSwagger2注解。
  • 使用 @Bean,在启动时初始化,返回实例 Docket(Swagger API 摘要对象)配置相关映射路径和要扫描的接口的位置等信息。

基本配置如下:

@EnableSwagger2
@Configuration
public class Swagger2Config {

    /**
     * 访问官方文档 UI界面:http://127.0.0.1:18080/swagger-ui.html
     * <p>
     * 增强版 UI界面:http://127.0.0.1:18080/doc.html
     */
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2) // SWAGGER_2
                .apiInfo(apiInfo())
                .select()
                // 此处自行修改为自己的 Controller 包路径
                .apis(RequestHandlerSelectors.basePackage("com.charge.xxx.controller"))
                .paths(PathSelectors.any())
                .build()
                .globalOperationParameters(setGlobalParameters());
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("XXX 项目接口文挡")
                .description("本文档描述 XXX平项目接口定义")
                .version("1.0")
                .termsOfServiceUrl("") //文档生成的主页地址
                .contact(new Contact("author", null, "xxxx@163.com"))
                .build();
    }

    /**
     * 设置全局参数
     *
     * @return
     */
    private List<Parameter> setGlobalParameters() {
        List<Parameter> globalParameterList = new ArrayList<>();

        //Header中必需 token参数。非必填,传空也可以,一般业务登录拦截器校验 token是否合法
        ParameterBuilder tokenBuilder = new ParameterBuilder();
        tokenBuilder.name("token").description("用户 TOKEN参数")
                .required(false)// 非必填
                .modelRef(new ModelRef("string"))
                .parameterType("header");
        globalParameterList.add(tokenBuilder.build());

        return globalParameterList;
    }

}

3、给Controller添加Swagger注解

(1)controller

tags:tags不同,表示UI的主页下的接口归类目录不同。

@RestController
@RequestMapping("/sys/user")
@Api(value = "SysUserController", tags = {"用户管理相关操作接口"})
public class SysUserController {

    @Autowired
    private SysUserService sysUserService;

    @PostMapping("/pageQuery")
    @ApiOperation(value = "用户分页查询接口", notes = "notes用户分页查询接口")
    public WebResult<BasePageResult<SysUserDTO>> pageQuery(@RequestBody SysUserPageQueryRequest pageQueryRequest) {
        BasePageResult basePageResult = sysUserService.pageQuery(pageQueryRequest);
        return WebResult.ok(basePageResult);
    }


    @DeleteMapping("/{id}")
    @ApiOperation("根据id删除用户的接口")
    @ApiImplicitParam(name = "id", value = "用户id", dataType = "Integer", defaultValue = "10", required = true)
    @ApiResponses({
        @ApiResponse(code = 200, message = "删除成功"),
        @ApiResponse(code = 500, message = "删除成功")
    })
    public void delete(@PathVariable Integer id) {
        System.out.println("删除成功:" + id);
    }

    @PutMapping("/update/{id}")
    @ApiOperation(value = "更新用户", notes = "根据用户id更新用户名接口")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "用户id", dataType = "Integer", defaultValue = "10", required = true),
        @ApiImplicitParam(name = "username", value = "用户名", dataType = "String", defaultValue = "lisi", required = true)
    })
    public User update(@PathVariable Integer id, String username) {
        User user = new User();
        user.setId(id);
        user.setUsername(username);
        return user;
    }

}      

(2)实体类

@Data
@ApiModel("系统用户分页查询请求体")
public class SysUserPageQueryRequest extends BasePageRequest {
    //@Serial
    private static final long serialVersionUID = -7586253215056854970L;

    @ApiModelProperty("创建时间开始")
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTimeStart;

    @ApiModelProperty("创建时间结束")
    private Date createTimeEnd;

}

4、访问 Swagger2的UI界面

启动项目。Swagger2官方UI界面访问地址:http://ip:port/项目路径/swagger-ui.html

5、替换官方 UI

我们引入 swagger-bootstrap-ui依赖,移除官方 UI依赖。

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--        <dependency>-->
        <!--            <groupId>io.springfox</groupId>-->
        <!--            <artifactId>springfox-swagger-ui</artifactId>-->
        <!--            <version>2.9.2</version>-->
        <!--        </dependency>-->
        <!-- 常用 UI界面依赖 -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>swagger-bootstrap-ui</artifactId>
            <version>1.9.6</version>
        </dependency>

重新启动项目。替换官方 UI界面之后,新 UI界面访问地址:http://ip:port/项目路径/doc.html

6、API分组展示

在项目中,我们通过不同的包名来管理不同的 controller,达到对接口分层的目的。对我们查找接口非常方便。

Swagger也支持对 API分组展示的功能。其实很简单,

  • 我们只需要重新定义一个 Docket的 bean,在其中指定另外接口层的包路径即可。
  • 通过 groupName设置组名,默认是default。

注意:Docket和 Swagger注解中 tags的区别:

  • Docket:对不同接口层的包路径进行分组。
  • @Api(tags = {"用户管理相关操作接口"}):表示同一个组下,对请求接口类中方法的归类管理。

这里简单点,重新复制一个 Docket的配置信息,其他信息一样。重启项目访问 UI。

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2) // SWAGGER_2
                .groupName("后端管理平台")
                .apiInfo(apiInfo())
                .select()
                // 此处自行修改为自己的 Controller 包路径
                .apis(RequestHandlerSelectors.basePackage("com.charge.xxx.controller"))
                .paths(PathSelectors.any())
                .build()
                .globalOperationParameters(setGlobalParameters());
    }

    @Bean
    public Docket createRestApi2() {
        return new Docket(DocumentationType.SWAGGER_2) // SWAGGER_2
                .groupName("后端管理平台2")
                .apiInfo(apiInfo())
                .select()
                // 此处自行修改为自己的 Controller 包路径
                .apis(RequestHandlerSelectors.basePackage("com.charge.xxx.controller"))
                .paths(PathSelectors.any())
                .build()
                .globalOperationParameters(setGlobalParameters());
    }

三、项目使用拦截器之后配置调整

项目中我们经常会添加拦截器,所以需要对 Swagger相关资源进行放行。

通常添加一个 WebMvcConfig配置类,在里面添加一下 Swagger相关配置即可。

1、添加登录拦截器

@Component
@Slf4j
public class LoginTokenInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("LoginTokenInterceptor -> preHandle 请求方式={},url = {}, ", request.getMethod(), request.getRequestURI());
        String token = request.getHeader("token");
        if (StringUtils.isBlank(token)) {
            token = request.getParameter("token");
        }
        if (StringUtils.isBlank(token)) {
            log.info("token 为空");
        }
        log.info("token = {}", token);

        return super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("LoginTokenInterceptor -> postHandle 请求方式={},url = {}, ", request.getMethod(), request.getRequestURI());
        super.postHandle(request, response, handler, modelAndView);
    }

}

2、WebMvcConfig配置类

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private LoginTokenInterceptor loginTokenInterceptor;

    /**
     * 配置登录拦截器
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginTokenInterceptor)
                .addPathPatterns("/**")
                // Swagger2放行。 /doc.html/**为新UI路径放行。
                .excludePathPatterns("/swagger-resources/**", "/webjars/**",
                        "/v2/**", "/swagger-ui.html/**", "/doc.html/**");
    }

    /**
     * 配置静态资源访问拦截
     *
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");

        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
        //  swagger-bootstrap-ui依赖
        registry.addResourceHandler("doc.html")
                .addResourceLocations("classpath:/META-INF/resources/");
    }
    

    /**
     * 配置 CORS跨域问题
     *
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedHeaders("*")
                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
                .allowCredentials(true)
                .maxAge(3600);
    }

}

重新启动项目。新 UI界面访问地址:http://ip:port/项目路径/doc.html。测试接口OK。

-- 求知若饥,虚心若愚。

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
- chapter1:[基本项目构建(可作为工程脚手架),引入web模块,完成一个简单的RESTful API](http://blog.didispace.com/spring-boot-learning-1/) - [使用Intellij中的Spring Initializr来快速构建Spring Boot/Cloud工程](http://blog.didispace.com/spring-initializr-in-intellij/) ### 工程配置 - chapter2-1-1:[配置文件详解:自定义属性、随机数、多环境配置等](http://blog.didispace.com/springbootproperties/) ### Web开发 - chapter3-1-1:[构建一个较为复杂的RESTful API以及单元测试](http://blog.didispace.com/springbootrestfulapi/) - chapter3-1-2:[使用Thymeleaf模板引擎渲染web视图](http://blog.didispace.com/springbootweb/) - chapter3-1-3:[使用Freemarker模板引擎渲染web视图](http://blog.didispace.com/springbootweb/) - chapter3-1-4:[使用Velocity模板引擎渲染web视图](http://blog.didispace.com/springbootweb/) - chapter3-1-5:[使用Swagger2构建RESTful API](http://blog.didispace.com/springbootswagger2/) - chapter3-1-6:[统一异常处理](http://blog.didispace.com/springbootexception/) ### 数据访问 - chapter3-2-1:[使用JdbcTemplate](http://blog.didispace.com/springbootdata1/) - chapter3-2-2:[使用Spring-data-jpa简化数据访问层(推荐)](http://blog.didispace.com/springbootdata2/) - chapter3-2-3:[多数据源配置(一):JdbcTemplate](http://blog.didispace.com/springbootmultidatasource/) - chapter3-2-4:[多数据源配置(二):Spring-data-jpa](http://blog.didispace.com/springbootmultidatasource/) - chapter3-2-5:[使用NoSQL数据库(一):Redis](http://blog.didispace.com/springbootredis/) - chapter3-2-6:[使用NoSQL数据库(二):MongoDB](http://blog.didispace.com/springbootmongodb/) - chapter3-2-7:[整合MyBatis](http://blog.didispace.com/springbootmybatis/) - chapter3-2-8:[MyBatis注解配置详解](http://blog.didispace.com/mybatisinfo/) ### 事务管理 - chapter3-3-1:[使用事务管理](http://blog.didispace.com/springboottransactional/) - chapter3-3-2:[分布式事务(未完成)] ### 其他内容 - chapter4-1-1:[使用@Scheduled创建定时任务](http://blog.didispace.com/springbootscheduled/) - chapter4-1-2:[使用@Async实现异步调用](http://blog.didispace.com/springbootasync/) #### 日志管理 - chapter4-2-1:[默认日志的配置](http://blog.didispace.com/springbootlog/) - chapter4-2-2:[使用log4j记录日志](http://blog.didispace.com/springbootlog4j/) - chapter4-2-3:[对log4j进行多环境不同日志级别的控制](http://blog
spring boot 实践学习案例,与其它组件结合如 mybatis、jpa、dubbo、redis、mongodb、memcached、kafka、rabbitmq、activemq、elasticsearch、security、shiro等 #### Spring Boot 版本 - 2.0.3.RELEASE #### 模块说明 - springboot-basic - Spring Boot 基础知识,包括SpringBoot起步、配置详解、aop、filter、拦截器、监听、启动器、全局异常处理、外部Tomcat启动、HTTPS、监控 等。 - springboot-data - Spring Boot 数据库操作,包括SpringJDBC、JPA、Mybatis注解版 & XML版、MongoDB。其中,每个版本都有其对应的多数据源解决方案。 - springboot-caches - Spring Boot 缓存,包括redis、ehcache、spring-cache、memcached、使用redis实现session共享 等。 - springboot-templates - Spring Boot 模板,包括thymeleaf、freemarker、jsp、表单校验 等。 - springboot-docs - Spring Boot 文档生成工具,包括 SwaggerSpring RestDocs - springboot-bussiness - Spring Boot 业务应用,包括 定时任务、上传文件、发送邮件、Doc文档操作 等。 - springboot-ajax - Spring Boot AJAX 跨域,包括 JSONP、Node.js与SpringBoot集成使用反向代理 等。 - springboot-websockets - Spring Boot 使用 Websocket - springboot-webflux - Spring Boot 集成 WebFlux 开发反应式 Web 应用 - springboot-dubbo - Spring Boot 集成 Dubbo 的三种方式 - springboot-search - Spring Boot 集成 搜索引擎,包括 elasticsearch、solr - springboot-mq - Spring Boot 集成 消息队列,包括 kafka、rabbitmq、activemq、rocketmq、redismq - springboot-auth - Spring Boot 权限认证,包括 Apache Shiro、Spring Security - springboot-cloud - Spring Cloud 入门,包括 Eureka(服务注册与发现)、Config(配置中心)、Hystrix(断路器)、Bus(消息总线) 等

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值