knife4j 3.0+ 集成到gateWay,调试请求子服务没有basePath解决方案

swagger2和openapi3(后面坚持v2/v3) 返回报文有部分差异,具体可以看报文,knife4j前端目前看支持v3有点问题,因为v3没有basePath这个字段了,而knife4j 去读取的basePath,因此调试时候,会出现没有basePath的问题,导致404.

因为不会前端,我目前解决方式修改后端返回的报文,在v3的json返回内容上,加入basePath字段。
目前我的做法是在 gateway加了一个过滤器,将/v3/api-docs的请求返回的报文进行拦截,通过修改response的内容 在v3的返回json上加上basePath属性,来解决这个问题。

/**
 * @author Duan Ran
 * @date 2022/2/25
 */

@Slf4j
@Component
public class SwaggerGlobalFilter implements GlobalFilter,Ordered {
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String path=exchange.getRequest().getPath().toString();
        if (!path.endsWith("/v3/api-docs")){
            return chain.filter(exchange);
        }
        String[] pathArray=path.split("/");
        System.out.println(pathArray);
        String basePath=pathArray[1];
        ServerHttpResponse originalResponse = exchange.getResponse();
        // 定义新的消息头
        HttpHeaders headers = new HttpHeaders();
        headers.putAll(exchange.getResponse().getHeaders());

        ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                if (getStatusCode().equals(HttpStatus.OK) && body instanceof Flux) {
                    Flux<? extends DataBuffer> fluxBody = Flux.from(body);
                    return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
                        List<String> list = new ArrayList<String>();
                        dataBuffers.forEach(dataBuffer -> {
                            byte[] content = new byte[dataBuffer.readableByteCount()];
                            dataBuffer.read(content);
                            DataBufferUtils.release(dataBuffer);
                            try {
                                list.add(new String(content, "utf-8"));
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        });
                        String s = listToString(list);
                        int length = s.getBytes().length;
                        headers.setContentLength(length);

                        JSONObject jsonObject=JSONUtil.parseObj(s);
//                        jsonObject.set("host","localhost:6400");
                        jsonObject.set("basePath",basePath);
                        s=jsonObject.toString();
                        return bufferFactory().wrap(s.getBytes());
                    }));
                }
                return super.writeWith(body);
            };
            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders httpHeaders = new HttpHeaders();
                httpHeaders.putAll(super.getHeaders());
                //由于修改了请求体的body,导致content-length长度不确定,因此使用分块编码
                httpHeaders.remove(HttpHeaders.CONTENT_LENGTH);
                httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
                return httpHeaders;
            }

            private String listToString(List<String> list){
                StringBuilder stringBuilder=new StringBuilder();
                for (String s:list){
                    stringBuilder.append(s);
                }
                return stringBuilder.toString();
            }
        };

        // replace response with decorator
        return chain.filter(exchange.mutate().response(decoratedResponse).build());
    }


    @Override
    public int getOrder() {
        return -2;
    }
}

filter的order 需要-2,-1 是nettywriteresponse。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值