简介
说明
本文介绍Knife4j在使用@RestControllerAdvice或@ControllerAdvice时访问失败的问题。
官网
问题描述
若加了全局的响应的处理,则会报错,或者无法正常使用。比如:“Knife4j文档请求异常”。
解决方法
需要将knife4j的接口数据忽略掉。配置如下:
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.example.common.entity.ResultWrapper; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.util.AntPathMatcher; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import java.util.Arrays; import java.util.List; @ControllerAdvice public class GlobalResponseBodyAdvice implements ResponseBodyAdvice<Object> { private List<String> KNIFE4J_URI = Arrays.asList( "/doc.html", "/swagger-resources", "/swagger-resources/configuration", "/v3/api-docs", "/v2/api-docs", "/webjars/**"); @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { // 若接口返回的类型本身就是ResultWrapper,则无需操作,返回false // return !returnType.getParameterType().equals(ResultWrapper.class); return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { if (body instanceof String) { // 若返回值为String类型,需要包装为String类型返回。否则会报错 try { ObjectMapper objectMapper = new ObjectMapper(); ResultWrapper<String> result = ResultWrapper.success().data(body); return objectMapper.writeValueAsString(result); } catch (JsonProcessingException e) { throw new RuntimeException("序列化String返回类型错误"); } } else if (body instanceof ResultWrapper) { return body; } else if (isKnife4jUrl(request.getURI().getPath())) { //如果是接口文档的uri,直接跳过 return body; } return ResultWrapper.success().data(body); } private boolean isKnife4jUrl(String uri) { AntPathMatcher pathMatcher = new AntPathMatcher(); for (String s : KNIFE4J_URI) { if (pathMatcher.match(s, uri)) { return true; } } return false; } }
请先
!