一, Swagger作用
-
- 前后端分离开发更加方便,有利于团队协作
-
- 接口文档在线自动生成,降低后端开发编写接口文档负担
-
- 功能测试
二, 导入依赖
(1) spring 2.x项目版本的依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
(2)spring 3.x项目版本的依赖
<!-- spring结合Swagger生成API依赖,适用于spring boot3.x项目 -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.0.2</version>
</dependency>
三, 解决启动问题,新建启动类
(1)spring 2.x项目版本,需要新建SwaggerConfiguration 类
package com.ceshiren.springtest.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;
@Configuration
//@EnableSwagger2 //开启swagger注解支持 有了这个注解,就可以去整体的项目下/controller包下扫描其他的swagger注解
public class SwaggerConfiguration {
@Bean
public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
}
return bean;
}
private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
List<T> copy = mappings.stream()
.filter(mapping -> mapping.getPatternParser() == null)
.collect(Collectors.toList());
mappings.clear();
mappings.addAll(copy);
}
@SuppressWarnings("unchecked")
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
try {
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
field.setAccessible(true);
return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
};
}
}
(2)spring 3.x项目版本无需配置启动类,直接启动服务即可访问。
四, 配置文件配置
(1)spring 2.x项目版本,在application.properties文件新增:
spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER
(2)spring 3.x项目版本,在application.properties文件新增:
# Swagger UI 路径
springdoc.api-docs.path=/v3/api-docs
springdoc.swagger-ui.path=/swagger-ui.html
五, 浏览器访问swagger-ui页面
六, 自定义配置信息
6.1 不同版本的配置信息
(1)spring 2.x版本在SwaggerConfiguration类添加配置信息
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
// 页面标题
.title("spring-test系统")
// 描述
.description("spring-test-lp 接口文档")
// 创建人信息
.contact(new Contact("demi", "", "liupan0721@gmail.com"))
// 项目API版本号
.version("1.0.0")
.build();
}
@Bean
public Docket docket() {
//Swagger 的配置主要围绕Docket bean 进行:
return new Docket(DocumentationType.OAS_30)
//配置是否启用Swagger,如果是false,在浏览器将无法访问,默认是true
.enable(true)
.groupName("spring-test interface")
.apiInfo(apiInfo())
// .globalRequestParameters(globalRequestParameters())
//在定义Docket bean 之后,它的select()方法返回一个ApiSelectorBuilder的实例,它提供了一种控制 Swagger 暴露的端点的方法
.select()
//any - 任何请求都扫描 ; none - 任何请求都不扫描 ; basePackage - 扫描指定对应的包名下的controller
// .apis(RequestHandlerSelectors.any())
.apis(RequestHandlerSelectors.basePackage("com.ceshiren.springtest"))
.paths(PathSelectors.any()).build();
//我们可以在RequestHandlerSelectors和PathSelectors的帮助下配置用于选择RequestHandler的谓词。对两者都使用any()将使我们的整个 API 的文档可以通过 Swagger 获得。
}
//生成全局通用参数
private List<RequestParameter> globalRequestParameters() {
List<RequestParameter> parameters = new ArrayList<>();
// 公共请求参数生成器-token
RequestParameter tokenParameter = new RequestParameterBuilder()
.in(ParameterType.HEADER)//在swagger里显示header
.name("token")//header的参数名为 token
.description("对应的token值")
.required(true)//对应参数是否为必传,如果不是必传参数则设置为false
.query(param -> param.model(model -> model.scalarModel(ScalarType.STRING)))
.build();
//为消费者提供帮助建立模型 更新标量类型
// 公共请求参数生成器-udid
RequestParameter udidParameter = new RequestParameterBuilder()
.in(ParameterType.QUERY)//在swagger里显示header
.name("udid")//header的参数名为 token
.description("设备的ID")
.required(false)//对应参数是否为必传,如果不是必传参数则设置为false
.query(param -> param.model(model -> model.scalarModel(ScalarType.STRING)))
.build();
parameters.add(tokenParameter);
parameters.add(udidParameter);
return parameters;
// Collections.singletonList(parameterBuilder.build());
}
(2)spring 3.x项目版本,新建SwaggerConfig类添加配置信息
package com.ceshiren.springtest.config;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("spring-api 接口文档")
.description("spring-test-api")
.contact(new Contact().name("demi").email("liupan0721@gmail.com"))
.version("1.0"));
}
}
6.2 Swagger四部分布局
- API分组:如果没有配置分组默认是default
- 基本描述:Swagger实例Docket的
apiInfo()
方法中的ApiInfo实例参数配置文档信息
- 请求接口列表:只要被Swagger扫描匹配到的请求都会出现
- 实体列表
6.3 Swagger2和 Swagger3的常用注解

(1) Swagger2:对应类和方法上的注解
@RestController
@Api(tags = "POST请求")
public class PostController {
@ApiOperation("register接口")
@PostMapping(path = "/{module}/register", produces = "application/json")
@ApiImplicitParams({
@ApiImplicitParam(name="module", value="模块名称"),
@ApiImplicitParam(name="desc", value="描述"),
@ApiImplicitParam(name="age", value="年龄")
})
String registerAndParam(@RequestBody UserDto userDto, @PathVariable String module,
@RequestParam String desc, @RequestParam int age){
return "用户登录成功!用户名:" + userDto.getUsername() + ", 密码:" +userDto.getPassword() + ", 模块:"+ module + ", 描述:" +desc + ", 年龄:" +age;
}
}
(2) Swagger2:实体类及属性上使用的注解实例
@Data
@ApiModel(value = "用户实体类",description = "请求参数的用户实体类")
public class UserDto {
@ApiModelProperty(value = "用户名称", example = "demi", required = true)
String username;
@ApiModelProperty(value = "用户密码", example = "123456", required = true)
String password;
}
(3) Swagger3:对应类和方法上的注解
package com.ceshiren.springtest.controller;
import com.ceshiren.springtest.dto.UserDto;
import com.ceshiren.springtest.dto.XmlDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
@Tag(name = "post请求 ")
@RestController
public class PostApiController {
// 登录请求路径:http://localhost:8080/login
// 接收请求参数为实体类,而非字符串,使用@RequestBody绑定前端传参和后端参数
//produces:申请传递参数的类型为json,如果不申明json,在postman请求时会报415
@Operation(summary = "login/user接口",description = "实表单格式数据")
@Parameters({
@Parameter(name = "username",description = "用户名"),
@Parameter(name = "password",description = "密码")
})
@PostMapping(value = "/login/user", produces = "application/json")
String loginAdmin(@RequestBody UserDto userDto) {
if(userDto.getUsername().equals("admin") && userDto.getPassword().equals("12345")){
return "登陆成功!用户名:"+userDto.getUsername() + "密码:" +userDto.getPassword();
}else{
return "登陆失败!用户名:"+userDto.getUsername() + "密码:" +userDto.getPassword();
}
}
@Operation(summary = "{module}/register接口",description = "json格式数据")
@PostMapping(value = "/{module}/register",produces = "application/json")
String registerAndParam(@PathVariable String module, @RequestParam String desc,
@RequestParam int age, @RequestBody UserDto userDto) {
return "用户登录成功!用户名:" + userDto.getUsername() + ", 密码:" +userDto.getPassword() + ", 模块:"+ module + ", 描述:" +desc + ", 年龄:" +age;
}
}
(4) Swagger3:实体类及属性上使用的注解实例
package com.ceshiren.springtest.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(title = "user实体类",description = "登陆信息")
@Data
public class UserDto {
@Schema(title= "用户名",pattern = "demi",required = true)
private String username;
@Schema(title= "密码",pattern = "123456",required = true)
private String password;
}