1 介绍

swagger和市面上的禅道、RAP2等众多图形化接口文档非常类似,经过短时间的摸索,和大量的查阅各类博客,记录下swagger2的使用和理解。

pom角度上讲,springfox-swagger2-ui集成了前端页面,并且不需要我们去管理,并且还可以使用yml预先编写接口,然后在按照HTML页面上进行开发。

2 前言

个人学习了一个技术,就会进行记录,所以这篇博客也是学习多篇博客,复制出来的内容。没有什么好写,直接放代码。

Swagger2 入门 - 图1

2.1 pom

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.hikktn</groupId>
  7. <artifactId>my-swagger2-test</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. <parent>
  10. <groupId>org.springframework.boot</groupId>
  11. <artifactId>spring-boot-starter-parent</artifactId>
  12. <version>2.1.4.RELEASE</version>
  13. </parent>
  14. <dependencies>
  15. <dependency>
  16. <groupId>io.springfox</groupId>
  17. <artifactId>springfox-swagger2</artifactId>
  18. <version>2.9.2</version>
  19. </dependency>
  20. <dependency>
  21. <groupId>io.springfox</groupId>
  22. <artifactId>springfox-swagger-ui</artifactId>
  23. <version>2.9.2</version>
  24. </dependency>
  25. <!--fastjson-->
  26. <dependency>
  27. <groupId>com.alibaba</groupId>
  28. <artifactId>fastjson</artifactId>
  29. <version>1.2.51</version>
  30. </dependency>
  31. <!--测试包-->
  32. <dependency>
  33. <groupId>org.springframework.boot</groupId>
  34. <artifactId>spring-boot-starter-test</artifactId>
  35. </dependency>
  36. <dependency>
  37. <groupId>org.springframework.boot</groupId>
  38. <artifactId>spring-boot-starter-web</artifactId>
  39. </dependency>
  40. <!-- 文件处理器-->
  41. <dependency>
  42. <groupId>org.springframework.boot</groupId>
  43. <artifactId>spring-boot-configuration-processor</artifactId>
  44. <optional>true</optional>
  45. </dependency>
  46. </dependencies>
  47. </project>

2.2 application.yml

  1. #swagger 配置
  2. swagger:
  3. title: API示例
  4. desc: 基于springBoot编写的RESful-API
  5. version: 0.0.1.SNAPSHOT
  6. termsOfServiceUrl: javascript:void(0)
  7. license: Apache 2.0
  8. licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.html
  9. # 监听的包路径
  10. basePackage: com.hikktn.controller
  11. groupName: 默认API示例分组
  12. contactName: name
  13. contactUrl: url
  14. contactEmail: email
  15. #生产环境改为false(改为false后swagger-ui.html则无法访问)
  16. enable: true
  17. #解决Swagger2 异常 NumberFormatException:For input string:""
  18. logging:
  19. level:
  20. io:
  21. swagger:
  22. models:
  23. parameters:
  24. AbstractSerializableParameter: ERROR
  25. server:
  26. port: 8080
  27. servlet:
  28. context-path: /

2.3 Swagger2Application

  1. package com.hikktn;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. /**
  5. * @ClassName Swagger2Application
  6. * @Description 启动类
  7. * @Author lisonglin
  8. * @Date 2021/5/21 23:47
  9. * @Version 1.0
  10. */
  11. @SpringBootApplication
  12. public class Swagger2Application {
  13. public static void main(String[] args){
  14. SpringApplication.run(Swagger2Application.class,args);
  15. }
  16. }

2.4 SwaggerConfig

  1. package com.hikktn.config;
  2. import io.swagger.annotations.ApiOperation;
  3. import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  4. import org.springframework.boot.context.properties.ConfigurationProperties;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. import org.springframework.http.ResponseEntity;
  8. import org.springframework.web.bind.annotation.RequestMethod;
  9. import org.springframework.web.servlet.config.annotation.EnableWebMvc;
  10. import springfox.documentation.builders.*;
  11. import springfox.documentation.schema.ModelRef;
  12. import springfox.documentation.service.ApiInfo;
  13. import springfox.documentation.service.Contact;
  14. import springfox.documentation.service.Parameter;
  15. import springfox.documentation.service.ResponseMessage;
  16. import springfox.documentation.spi.DocumentationType;
  17. import springfox.documentation.spring.web.plugins.Docket;
  18. import springfox.documentation.swagger2.annotations.EnableSwagger2;
  19. import java.time.LocalDate;
  20. import java.util.ArrayList;
  21. import java.util.List;
  22. @Configuration
  23. @EnableSwagger2
  24. @EnableWebMvc
  25. @ConfigurationProperties(prefix = "swagger")
  26. /**
  27. * 生产环境禁用swagger2
  28. */
  29. @ConditionalOnProperty(name = "swagger.enable", havingValue = "true")
  30. /**
  31. * @ClassName SwaggerConfig
  32. * @Description swagger2配置
  33. * @Author lisonglin
  34. * @Date 2021/5/21 23:38
  35. * @Version 1.0
  36. */
  37. public class SwaggerConfig {
  38. private String title;
  39. private String desc;
  40. private String version;
  41. private String termsOfServiceUrl;
  42. private String license;
  43. private String licenseUrl;
  44. private String basePackage;
  45. private String groupName;
  46. private String contactName;
  47. private String contactUrl;
  48. private String contactEmail;
  49. /**
  50. * 增加API相关信息:包含作者、简介、版本、host、服务URL
  51. * @return
  52. */
  53. private ApiInfo apiInfo() {
  54. return new ApiInfoBuilder()
  55. //接口文档的标题
  56. .title(title)
  57. //文档描述
  58. .description(desc)
  59. //版本号
  60. .version(version)
  61. //服务条款URL
  62. .termsOfServiceUrl(termsOfServiceUrl)
  63. .licenseUrl(licenseUrl)
  64. //license 规范
  65. .license(license)
  66. // 开发文档的作者信息
  67. .contact(new Contact(contactName, contactUrl, contactEmail))
  68. .build();
  69. }
  70. @Bean
  71. public Docket swaggerApi() {
  72. // ==================== 需要的参数 START ====================
  73. List<Parameter> pars = new ArrayList<>();
  74. ParameterBuilder token = new ParameterBuilder();
  75. token.name("token").description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
  76. pars.add(token.build());
  77. // ==================== 需要的参数 END ====================
  78. return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).groupName(groupName)
  79. .directModelSubstitute(LocalDate.class, String.class).genericModelSubstitutes(ResponseEntity.class)
  80. .useDefaultResponseMessages(false)
  81. .globalResponseMessage(RequestMethod.POST, customerResponseMessage())
  82. .globalResponseMessage(RequestMethod.GET, customerResponseMessage())
  83. .forCodeGeneration(true).select()
  84. // api包扫描
  85. .apis(RequestHandlerSelectors.basePackage(basePackage))
  86. // 设置选择器
  87. .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
  88. .paths(PathSelectors.any())
  89. .build().globalOperationParameters(pars);
  90. }
  91. private List<ResponseMessage> customerResponseMessage() {
  92. List<ResponseMessage> list = new ArrayList<>();
  93. list.add(new ResponseMessageBuilder().code(200).message("请求成功").build());
  94. list.add(new ResponseMessageBuilder().code(201).message("资源创建成功").build());
  95. list.add(new ResponseMessageBuilder().code(204).message("服务器成功处理了请求,但不需要返回任何实体内容").build());
  96. list.add(new ResponseMessageBuilder().code(400).message("请求失败,具体查看返回业务状态码与对应消息").build());
  97. list.add(new ResponseMessageBuilder().code(401).message("请求失败,未经过身份认证").build());
  98. list.add(new ResponseMessageBuilder().code(405).message("请求方法不支持").build());
  99. list.add(new ResponseMessageBuilder().code(415).message("请求媒体类型不支持").build());
  100. list.add(new ResponseMessageBuilder().code(500).message("服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理").build());
  101. list.add(new ResponseMessageBuilder().code(503).message("服务器当前无法处理请求,这个状况是临时的,并且将在一段时间以后恢复").build());
  102. return list;
  103. }
  104. public String getTitle() {
  105. return title;
  106. }
  107. public void setTitle(String title) {
  108. this.title = title;
  109. }
  110. public String getDesc() {
  111. return desc;
  112. }
  113. public void setDesc(String desc) {
  114. this.desc = desc;
  115. }
  116. public String getVersion() {
  117. return version;
  118. }
  119. public void setVersion(String version) {
  120. this.version = version;
  121. }
  122. public String getTermsOfServiceUrl() {
  123. return termsOfServiceUrl;
  124. }
  125. public void setTermsOfServiceUrl(String termsOfServiceUrl) {
  126. this.termsOfServiceUrl = termsOfServiceUrl;
  127. }
  128. public String getLicense() {
  129. return license;
  130. }
  131. public void setLicense(String license) {
  132. this.license = license;
  133. }
  134. public String getLicenseUrl() {
  135. return licenseUrl;
  136. }
  137. public void setLicenseUrl(String licenseUrl) {
  138. this.licenseUrl = licenseUrl;
  139. }
  140. public String getBasePackage() {
  141. return basePackage;
  142. }
  143. public void setBasePackage(String basePackage) {
  144. this.basePackage = basePackage;
  145. }
  146. public String getGroupName() {
  147. return groupName;
  148. }
  149. public void setGroupName(String groupName) {
  150. this.groupName = groupName;
  151. }
  152. public String getContactName() {
  153. return contactName;
  154. }
  155. public void setContactName(String contactName) {
  156. this.contactName = contactName;
  157. }
  158. public String getContactUrl() {
  159. return contactUrl;
  160. }
  161. public void setContactUrl(String contactUrl) {
  162. this.contactUrl = contactUrl;
  163. }
  164. public String getContactEmail() {
  165. return contactEmail;
  166. }
  167. public void setContactEmail(String contactEmail) {
  168. this.contactEmail = contactEmail;
  169. }
  170. }

2.5 WebMvcConfig

  1. package com.hikktn.config;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.servlet.config.annotation.CorsRegistry;
  4. import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
  5. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  6. /**
  7. * @ClassName WebMvcConfigurer
  8. * @Description 前后端分离项目跨域访问
  9. * @Author lisonglin
  10. * @Date 2021/5/22 1:30
  11. * @Version 1.0
  12. */
  13. @Configuration
  14. public class WebMvcConfig implements WebMvcConfigurer {
  15. public WebMvcConfig() {
  16. }
  17. @Override
  18. public void addCorsMappings(CorsRegistry registry) {
  19. registry.addMapping("/**").allowedOrigins(new String[]{"*"});
  20. }
  21. @Override
  22. public void addResourceHandlers(ResourceHandlerRegistry registry) {
  23. registry.addResourceHandler("/**").addResourceLocations(
  24. "classpath:/static/");
  25. registry.addResourceHandler("swagger-ui.html")
  26. .addResourceLocations("classpath:/META-INF/resources/");
  27. registry.addResourceHandler("/webjars/**")
  28. .addResourceLocations("classpath:/META-INF/resources/webjars/");
  29. }
  30. }

2.6 UserController

  1. package com.hikktn.controller;
  2. import io.swagger.annotations.*;
  3. import org.springframework.http.ResponseEntity;
  4. import org.springframework.web.bind.annotation.*;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7. /**
  8. * @ClassName UserController
  9. * @Description 用户服务控制器
  10. * @Author lisonglin
  11. * @Date 2021/5/21 23:39
  12. * @Version 1.0
  13. */
  14. @RestController
  15. @RequestMapping("user")
  16. @Api(tags = "用户服务接口")
  17. public class UserController {
  18. @GetMapping("findAll")
  19. @ApiOperation(value = "查询所有用户信息", notes = "查询所有用户信息接口")
  20. public Map<String, Object> findAll() {
  21. Map<String, Object> map = new HashMap<>();
  22. map.put("success", "查询所有成功");
  23. map.put("state", true);
  24. return map;
  25. }
  26. @PostMapping("save")
  27. @ApiOperation(value = "保存用户信息", notes = "保存用户信息接口")
  28. @ApiImplicitParams({
  29. @ApiImplicitParam(name = "id", value = "用户id", dataType = "String", defaultValue = "21"),
  30. @ApiImplicitParam(name = "name", value = "用户名", dataType = "String", defaultValue = "zhangsan")
  31. })
  32. @ApiResponses({
  33. @ApiResponse(code = 404, message = "页面不存在"),
  34. @ApiResponse(code = 500, message = "服务器出错")
  35. })
  36. public Map<String, Object> sve(String id, String name) {
  37. Map<String, Object> map = new HashMap<>();
  38. map.put("success", "保存用户信息");
  39. map.put("state", true);
  40. return map;
  41. }
  42. @ApiOperation(value = "测试 - GET请求加入header参数")
  43. @ApiImplicitParams({
  44. @ApiImplicitParam(name = "token", value = "请求token", required = true, paramType = "header"),
  45. })
  46. @GetMapping
  47. public ResponseEntity<String> test(@RequestHeader String token) {
  48. return ResponseEntity.ok("token:" + token);
  49. }
  50. }

3 测试

http://localhost:8080/swagger-ui.html

Swagger2 入门 - 图2

4、Swagger注解总结

A.官方总结

Swagger相关注解官方说明地址
https://github.com/swagger-api/swagger-core/wiki/Annotations

B.常见总结

@Api()用于类

标识这个类是swagger的资源
  tags–表示分组说明标签

@ApiOperation()用于方法

表示一个http请求的操作
  value用于方法描述
  notes用于提示内容

@ApiModel()用于实体类

表示对类进行说明,用于参数用实体类接收
value–表示对象名
description–描述

@ApiModelProperty()用于实体类字段

表示对model属性的说明或者数据操作更改
  value–字段说明
  name–重写属性名字
  dataType–重写属性类型
  required–是否必填
  example–举例说明
  hidden–隐藏

@ApiImplicitParam() 用于 controller 方法

表示单独的请求参数
  name–参数ming
  value–参数说明
  dataType–数据类型
  paramType–参数类型
  example–举例说明

@ApiImplicitParams() 用于 controller 方法

包含多个 @ApiImplicitParam

@ApiIgnore()用于类或者方法上

可以不被swagger显示在页面上