所有分类
  • 所有分类
  • 未分类

Knife4j–解决整合@ControllerAdvice时访问失败的问题

简介

说明

本文介绍Knife4j在使用@RestControllerAdvice或@ControllerAdvice时访问失败的问题。

官网

快速开始 | knife4j

问题描述

若加了全局的响应的处理,则会报错,或者无法正常使用。比如:“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;
    }
}

0

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录