swragger与@ControllerAdvice不兼容
时间: 2024-12-28 17:27:01 AIGC 浏览: 104
### 解析 Swagger 与 `@ControllerAdvice` 不兼容问题
在 Spring Boot 应用程序中,当集成 Swagger 进行 API 文档化时,可能会遇到与全局异常处理类(`@ControllerAdvice`)之间的冲突。这种不兼容主要体现在 Swagger UI 页面无法正常显示某些自定义异常响应。
#### 原因分析
Swagger 使用反射机制扫描控制器中的方法及其参数来构建文档模型。而 `@ControllerAdvice` 注解用于定义全局异常处理器或跨多个控制器共享的预处理逻辑。如果这些组件之间存在命名空间或其他配置上的冲突,则可能导致 Swagger 扫描不到预期的方法签名[^1]。
#### 解决策略
为了使两者能够和谐共存并有效工作,可以采取以下几种方式之一:
##### 方法一:调整包结构设计
确保所有带有 `@RestController` 或者其他 REST 控制器相关注解的类位于特定的基础包下,并通过设置 `Docket` Bean 来指定该基础包路径作为扫描起点。这样做的好处是可以精确控制哪些资源应该被纳入到 API 文档生成范围内。
```java
import org.springframework.context.annotation.Bean;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
@Configuration
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.controller")) // 设置基础包名
.paths(PathSelectors.any())
.build();
}
}
```
##### 方法二:排除不必要的接口
有时应用程序内部可能包含了不应该暴露给外部调用者的私有服务端点。此时可以通过修改 `Docket` 配置,在创建 API 文档时不考虑那些不需要公开的服务接口。
```java
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(Predicates.not(RequestHandlerSelectors.withClassAnnotation(RestController.class)))// 排除带 RestController 注解的类
.paths(PathSelectors.ant("/api/**"))
.build();
}
```
##### 方法三:定制错误响应序列化行为
对于由 `@ControllerAdvice` 处理后的异常返回对象,默认情况下它们不会自动成为 Swagger 文档的一部分。为此可以在相应的异常处理器内手动注册额外的信息描述符,以便让其也能出现在最终生成的 API 文档里。
```java
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
private final ObjectMapper objectMapper = new ObjectMapper();
@ExceptionHandler(value = {Exception.class})
protected ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request) throws JsonProcessingException {
ApiError apiError = new ApiError(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Unexpected error occurred");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
String jsonResult = objectMapper.writeValueAsString(apiError);
return handleExceptionInternal(ex, jsonResult ,headers,
HttpStatus.INTERNAL_SERVER_ERROR,request);
}
static class ApiError{
int status;
String message;
public ApiError(int status, String message){
this.status=status;
this.message=message;
}
}
}
```
以上三种策略可以根据实际需求灵活选用一种或多组合起来应用,从而实现 Swagger 和 `@ControllerAdvice` 的良好协作效果[^2]。
阅读全文
