OpenAPI 规范 - 版本 3.1.0 | Swagger - Swagger 中文
在之前的 Spring Cloud 微服务系列文章中,我整合了 Swagger 来实现接口文档功能。然而,在 DailyMart 项目中,由于使用的是 Spring Boot 3.x 版本,再次使用 Swagger 可能会遇到一些问题。目前 Spring Boot 3.x 将包 javax 下的所有内容迁移到了 jakarta 包下,例如 HttpServletRequest,而 Swagger 仍然使用的是 javax 包,导致不兼容的问题。因此,我们将使用 SpringDoc 来替代之前的 Swagger 组件。
在 Spring Boot 3.0 中,集成 SpringDoc 非常简单,只需要遵循以下几个步骤:
首先,在基础设施层的 dailymart-customer-infrastructure 模块的 pom.xml 文件中引入 SpringDoc 的依赖:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.0.4</version>
</dependency>
接下来,我们可以在项目的接口上添加相应的接口注解,以之前介绍的用户接口接口为例:
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
//@Validated
@Tag(name = "CustomerController",description = "C端用户管理")
public class CustomerUserController {
private final CustomerUserService customerUserService;
@Operation(summary = "用户注册接口")
@PostMapping("/api/customer/register")
public UserRegistrationDTO register(@RequestBody @Valid UserRegistrationDTO customerDTO){
return customerUserService.register(customerDTO);
}
@Operation(summary = "用户登录接口")
@Parameters(value = {
@Parameter(name = "loginType",description = "登录类型",example = "USERNAME_PASSWORD"),
@Parameter(name = "userName",description = "用户账号"),
@Parameter(name = "phone",description = "手机号码"),
@Parameter(name = "smsCode",description = "短信验证码"),
@Parameter(name = "email",description = "邮箱"),
@Parameter(name = "emailCode",description = "邮箱验证码")
})
@PostMapping("/api/customer/login")
public UserLoginRespDTO login(@RequestBody Map<String, String> parameters){
UserLoginDTO loginDTO = LoginDTOFactory.getLoginDTO(parameters);
return customerUserService.login(loginDTO);
}
}
以下是SpringDoc中常用的几个注解,大家可以自行测试
| 注解 | 含义 |
|---|---|
| @Tag | 用在Controller类上,描述此Controller的信息 |
| @Operation | 用在Controller的方法里,描述此Api的信息 |
| @Parameter | 用在Controller方法里的参数上,描述参数信息 |
| @Parameters | 用在Controller方法里的参数上 |
| @Schema | 用于DTO,以及DTO的属性上 |
| @ApiResponse | 用在Controller方法的返回值上 |
| @ApiResponses | 用在Controller方法的返回值上 |
| @Hidden | 用在各种地方,用于隐藏其api |
在之前的文章《DailyMart07:DDD 中统一返回格式与全局异常处理》中,我们实现了包装响应体的功能,使所有对外的接口自动返回 Result 包装类。然而,集成了 SpringDoc 后,我们需要过滤掉 SpringDoc 的接口包装,以避免异常。我们可以通过如下方式进行优化:
@Slf4j
@RestControllerAdvice
public class GlobalResponseBodyAdvice implements ResponseBodyAdvice<Object> {
@Autowired
private ObjectMapper objectMapper;
/**
* 此处可以通过判断决定哪些响应需要包装,有两种办法
* 1. 指定需要返回的接口,就DailyMart而言,接口项目包的地址前缀都是 com.jianzh5.dailymart
* 2. 如果返回的接口类型是springdoc的,则不转换,returnType.getDeclaringClass().getName().contains("springdoc")
*/
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
// boolean supports = returnType.getContainingClass().getPackage().getName().startsWith("com.jianzh5.dailymart");
// return supports;
log.info("supports package:{}",returnType.getDeclaringClass().getName());
boolean supports = returnType.getDeclaringClass().getName().contains("springdoc");
return !supports;
}
}
完成了上述步骤后,我们已经成功集成了 SpringDoc 文档。此时,在浏览器中访问 http://localhost:8081/swagger-ui/index.html,即可查看用户模块的接口文档。你还可以进入具体的接口页面进行调试,非常方便。