当前位置:   article > 正文

Spring Boot整合Swagger2详解

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

  1. @Api:用在请求的类上,表示对类的说明(不配置默认是按类名驼峰变下划线显示)
  2. value:该参数没什么意义,在UI界面上也看到,所以不需要配置"
  3. tags:说明该类的作用,可以在UI界面上看到的注解
  4. description:对api资源的描述
  5. basePath:基本路径
  6. position:如果配置多个Api 想改变显示的顺序位置
  7. produces:如 “application/json, application/xml”
  8. consumes:如 “application/json, application/xml”
  9. protocols:协议类型,如: http, https, ws, wss.
  10. authorizations:高级特性认证时配置
  11. hidden:配置为true ,将在文档中隐藏
  12. @ApiOperation:用在请求的方法上,说明方法的用途、作用
  13. value:说明方法的用途、作用
  14. tags:如果设置这个值、value的值会被覆盖
  15. notes:方法的备注说明
  16. description:对api资源的描述
  17. @ApiImplicitParams:用在请求的方法上,表示一组参数说明
  18. @ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
  19. name:参数名
  20. value:参数的汉字说明、解释
  21. required:参数是否必须传
  22. paramType:参数放在哪个地方
  23. · header --> 请求参数的获取:@RequestHeader
  24. · query --> 请求参数的获取:@RequestParam
  25. · path(用于restful接口)--> 请求参数的获取:@PathVariable
  26. · div(不常用)
  27. · form(不常用)
  28. dataType:参数类型,默认String,其它值dataType="Integer"
  29. defaultValue:参数的默认值
  30. @ApiParam() 用于方法,参数,字段说明;表示对参数的添加元数据(说明或是否必填等)
  31. name:参数名
  32. value:参数说明
  33. required:是否必填
  34. @ApiResponses:用在请求的方法上,表示一组响应
  35. @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
  36. code:数字,例如400
  37. message:信息,例如"请求参数没填好"
  38. response:抛出异常的类
  39. @ApiModel:用于pojo类上,描述一个Model的信息
  40. (一般用在请求参数无法使用@ApiImplicitParam注解进行描述的时候,比如使用@RequestBody这样的场景)
  41. @ApiModelProperty:用在属性上,描述一个model的属性
  42. @ApiIgnore:注解类、参数、方法,注解后将不在Swagger UI中显示

二、Spring Boot整合Swagger2

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

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

1、引入 Swagger2依赖

创建项目引入 Swagger2依赖。

  1. <dependency>
  2. <groupId>io.springfox</groupId>
  3. <artifactId>springfox-swagger2</artifactId>
  4. <version>2.9.2</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>io.springfox</groupId>
  8. <artifactId>springfox-swagger-ui</artifactId>
  9. <version>2.9.2</version>
  10. </dependency>

2、添加 Swagger2配置类

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

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

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

基本配置如下:

  1. @EnableSwagger2
  2. @Configuration
  3. public class Swagger2Config {
  4. /**
  5. * 访问官方文档 UI界面:http://127.0.0.1:18080/swagger-ui.html
  6. * <p>
  7. * 增强版 UI界面:http://127.0.0.1:18080/doc.html
  8. */
  9. @Bean
  10. public Docket createRestApi() {
  11. return new Docket(DocumentationType.SWAGGER_2) // SWAGGER_2
  12. .apiInfo(apiInfo())
  13. .select()
  14. // 此处自行修改为自己的 Controller 包路径
  15. .apis(RequestHandlerSelectors.basePackage("com.charge.xxx.controller"))
  16. .paths(PathSelectors.any())
  17. .build()
  18. .globalOperationParameters(setGlobalParameters());
  19. }
  20. private ApiInfo apiInfo() {
  21. return new ApiInfoBuilder().title("XXX 项目接口文挡")
  22. .description("本文档描述 XXX平项目接口定义")
  23. .version("1.0")
  24. .termsOfServiceUrl("") //文档生成的主页地址
  25. .contact(new Contact("author", null, "xxxx@163.com"))
  26. .build();
  27. }
  28. /**
  29. * 设置全局参数
  30. *
  31. * @return
  32. */
  33. private List<Parameter> setGlobalParameters() {
  34. List<Parameter> globalParameterList = new ArrayList<>();
  35. //Header中必需 token参数。非必填,传空也可以,一般业务登录拦截器校验 token是否合法
  36. ParameterBuilder tokenBuilder = new ParameterBuilder();
  37. tokenBuilder.name("token").description("用户 TOKEN参数")
  38. .required(false)// 非必填
  39. .modelRef(new ModelRef("string"))
  40. .parameterType("header");
  41. globalParameterList.add(tokenBuilder.build());
  42. return globalParameterList;
  43. }
  44. }

3、给Controller添加Swagger注解

(1)controller

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

  1. @RestController
  2. @RequestMapping("/sys/user")
  3. @Api(value = "SysUserController", tags = {"用户管理相关操作接口"})
  4. public class SysUserController {
  5. @Autowired
  6. private SysUserService sysUserService;
  7. @PostMapping("/pageQuery")
  8. @ApiOperation(value = "用户分页查询接口", notes = "notes用户分页查询接口")
  9. public WebResult<BasePageResult<SysUserDTO>> pageQuery(@RequestBody SysUserPageQueryRequest pageQueryRequest) {
  10. BasePageResult basePageResult = sysUserService.pageQuery(pageQueryRequest);
  11. return WebResult.ok(basePageResult);
  12. }
  13. @DeleteMapping("/{id}")
  14. @ApiOperation("根据id删除用户的接口")
  15. @ApiImplicitParam(name = "id", value = "用户id", dataType = "Integer", defaultValue = "10", required = true)
  16. @ApiResponses({
  17. @ApiResponse(code = 200, message = "删除成功"),
  18. @ApiResponse(code = 500, message = "删除成功")
  19. })
  20. public void delete(@PathVariable Integer id) {
  21. System.out.println("删除成功:" + id);
  22. }
  23. @PutMapping("/update/{id}")
  24. @ApiOperation(value = "更新用户", notes = "根据用户id更新用户名接口")
  25. @ApiImplicitParams({
  26. @ApiImplicitParam(name = "id", value = "用户id", dataType = "Integer", defaultValue = "10", required = true),
  27. @ApiImplicitParam(name = "username", value = "用户名", dataType = "String", defaultValue = "lisi", required = true)
  28. })
  29. public User update(@PathVariable Integer id, String username) {
  30. User user = new User();
  31. user.setId(id);
  32. user.setUsername(username);
  33. return user;
  34. }
  35. }

(2)实体类

  1. @Data
  2. @ApiModel("系统用户分页查询请求体")
  3. public class SysUserPageQueryRequest extends BasePageRequest {
  4. //@Serial
  5. private static final long serialVersionUID = -7586253215056854970L;
  6. @ApiModelProperty("创建时间开始")
  7. @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
  8. private Date createTimeStart;
  9. @ApiModelProperty("创建时间结束")
  10. private Date createTimeEnd;
  11. }

4、访问 Swagger2的UI界面

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

5、替换官方 UI

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

  1. <dependency>
  2. <groupId>io.springfox</groupId>
  3. <artifactId>springfox-swagger2</artifactId>
  4. <version>2.9.2</version>
  5. </dependency>
  6. <!-- <dependency>-->
  7. <!-- <groupId>io.springfox</groupId>-->
  8. <!-- <artifactId>springfox-swagger-ui</artifactId>-->
  9. <!-- <version>2.9.2</version>-->
  10. <!-- </dependency>-->
  11. <!-- 常用 UI界面依赖 -->
  12. <dependency>
  13. <groupId>com.github.xiaoymin</groupId>
  14. <artifactId>swagger-bootstrap-ui</artifactId>
  15. <version>1.9.6</version>
  16. </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。

  1. @Bean
  2. public Docket createRestApi() {
  3. return new Docket(DocumentationType.SWAGGER_2) // SWAGGER_2
  4. .groupName("后端管理平台")
  5. .apiInfo(apiInfo())
  6. .select()
  7. // 此处自行修改为自己的 Controller 包路径
  8. .apis(RequestHandlerSelectors.basePackage("com.charge.xxx.controller"))
  9. .paths(PathSelectors.any())
  10. .build()
  11. .globalOperationParameters(setGlobalParameters());
  12. }
  13. @Bean
  14. public Docket createRestApi2() {
  15. return new Docket(DocumentationType.SWAGGER_2) // SWAGGER_2
  16. .groupName("后端管理平台2")
  17. .apiInfo(apiInfo())
  18. .select()
  19. // 此处自行修改为自己的 Controller 包路径
  20. .apis(RequestHandlerSelectors.basePackage("com.charge.xxx.controller"))
  21. .paths(PathSelectors.any())
  22. .build()
  23. .globalOperationParameters(setGlobalParameters());
  24. }

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

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

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

1、添加登录拦截器

  1. @Component
  2. @Slf4j
  3. public class LoginTokenInterceptor extends HandlerInterceptorAdapter {
  4. @Override
  5. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  6. log.info("LoginTokenInterceptor -> preHandle 请求方式={},url = {}, ", request.getMethod(), request.getRequestURI());
  7. String token = request.getHeader("token");
  8. if (StringUtils.isBlank(token)) {
  9. token = request.getParameter("token");
  10. }
  11. if (StringUtils.isBlank(token)) {
  12. log.info("token 为空");
  13. }
  14. log.info("token = {}", token);
  15. return super.preHandle(request, response, handler);
  16. }
  17. @Override
  18. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  19. log.info("LoginTokenInterceptor -> postHandle 请求方式={},url = {}, ", request.getMethod(), request.getRequestURI());
  20. super.postHandle(request, response, handler, modelAndView);
  21. }
  22. }

2、WebMvcConfig配置类

  1. @Configuration
  2. public class WebMvcConfig implements WebMvcConfigurer {
  3. @Autowired
  4. private LoginTokenInterceptor loginTokenInterceptor;
  5. /**
  6. * 配置登录拦截器
  7. *
  8. * @param registry
  9. */
  10. @Override
  11. public void addInterceptors(InterceptorRegistry registry) {
  12. registry.addInterceptor(loginTokenInterceptor)
  13. .addPathPatterns("/**")
  14. // Swagger2放行。 /doc.html/**为新UI路径放行。
  15. .excludePathPatterns("/swagger-resources/**", "/webjars/**",
  16. "/v2/**", "/swagger-ui.html/**", "/doc.html/**");
  17. }
  18. /**
  19. * 配置静态资源访问拦截
  20. *
  21. * @param registry
  22. */
  23. @Override
  24. public void addResourceHandlers(ResourceHandlerRegistry registry) {
  25. registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
  26. registry.addResourceHandler("swagger-ui.html")
  27. .addResourceLocations("classpath:/META-INF/resources/");
  28. registry.addResourceHandler("/webjars/**")
  29. .addResourceLocations("classpath:/META-INF/resources/webjars/");
  30. // swagger-bootstrap-ui依赖
  31. registry.addResourceHandler("doc.html")
  32. .addResourceLocations("classpath:/META-INF/resources/");
  33. }
  34. /**
  35. * 配置 CORS跨域问题
  36. *
  37. * @param registry
  38. */
  39. @Override
  40. public void addCorsMappings(CorsRegistry registry) {
  41. registry.addMapping("/**")
  42. .allowedOrigins("*")
  43. .allowedHeaders("*")
  44. .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
  45. .allowCredentials(true)
  46. .maxAge(3600);
  47. }
  48. }

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/939820
推荐阅读
相关标签
  

闽ICP备14008679号