springcloud gateway中打印请求参数,请求路径和返回数据

该文章介绍了如何在SpringCloudGateway中创建自定义过滤器来打印请求参数、请求路径以及返回数据,以便于前后端联调时的问题定位。通过创建HttpRequestFilter和WrapperResponseGlobalFilter两个过滤器,分别处理POST和GET请求的参数打印,并实现返回参数的记录。代码示例展示了如何拦截请求和响应,读取并打印相关数据。
摘要由CSDN通过智能技术生成

请求参数,返回参数,请求路径日志打印

在平时前后端联调过程中,需要查询日志看到前端请求的接口,上送的参数,返回数据这样有利于我们定位问题;话不多说直接上代码。

打印请求路径、请求参数

在gateway模块中,新建一个filter的包,然后创建改类,即可在控制台和日志文件里面打印出请求参数,只写了常用的postget请求的方式;

/**
 * @author 
 * @date 2023/2/3 - 10:54
 * @描述 请求参数日志打印
 */
@Component
@Slf4j
@AllArgsConstructor
public class HttpRequestFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String method = request.getMethodValue();
        String contentType = request.getHeaders().getFirst("Content-Type");
        String url = JSONObject.toJSONString(request.getURI());
        log.info("网关请求路径: "+url);// 请求路径打印
        if ("POST".equals(method)) {
            return DataBufferUtils.join(exchange.getRequest().getBody())
                    .flatMap(dataBuffer -> {
                        byte[] bytes = new byte[dataBuffer.readableByteCount()];
                        dataBuffer.read(bytes);
                        try {
                            String bodyString = new String(bytes, "utf-8");
                            log.info("请求参数: "+bodyString);//打印请求参数
                            exchange.getAttributes().put("POST_BODY", bodyString);
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                        DataBufferUtils.release(dataBuffer);
                        Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
                            DataBuffer buffer = exchange.getResponse().bufferFactory()
                                    .wrap(bytes);
                            return Mono.just(buffer);
                        });
                        ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
                                exchange.getRequest()) {
                            @Override
                            public Flux<DataBuffer> getBody() {
                                return cachedFlux;
                            }
                        };
                        return chain.filter(exchange.mutate().request(mutatedRequest)
                                .build());
                    });
        }else if ("GET".equals(method)) {
            MultiValueMap<String, String> queryParams = request.getQueryParams();
            log.info("请求参数:" + queryParams);
            log.info("****************************************************************************\n");
            return chain.filter(exchange);
        }
        log.info("****************************************************************************\n");
        return chain.filter(exchange);
    }
    @Override
    public int getOrder() {
        return -200;
    }
}

返回参数打印


/**
 * @author 
 * @date 2023/2/3 - 10:54
 * @描述 返回参数日志打印
 */

@Component
public class WrapperResponseGlobalFilter implements GlobalFilter, Ordered {

    private static final Logger log = LoggerFactory.getLogger(WrapperResponseGlobalFilter.class);

    @Override
    public int getOrder() {
        // -1 is response write filter, must be called before that
        return -2;
    }

    private static Joiner joiner = Joiner.on("");

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpResponse originalResponse = exchange.getResponse();
        DataBufferFactory bufferFactory = originalResponse.bufferFactory();
        ServerHttpResponseDecorator response = new ServerHttpResponseDecorator(originalResponse) {
            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                if (getStatusCode().equals(HttpStatus.OK) && body instanceof Flux) {
                    // 获取ContentType,判断是否返回JSON格式数据
                    String originalResponseContentType = exchange.getAttribute(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR);
                    if (StringUtils.isNotBlank(originalResponseContentType) && originalResponseContentType.contains("application/json")) {
                        Flux<? extends DataBuffer> fluxBody = Flux.from(body);
                        //(返回数据内如果字符串过大,默认会切割)解决返回体分段传输
                        return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
                            List<String> list = Lists.newArrayList();
                            dataBuffers.forEach(dataBuffer -> {
                                try {
                                    byte[] content = new byte[dataBuffer.readableByteCount()];
                                    dataBuffer.read(content);
                                    DataBufferUtils.release(dataBuffer);
                                    list.add(new String(content, "utf-8"));
                                } catch (Exception e) {
                                    log.info("加载Response字节流异常,失败原因:{}", Throwables.getStackTraceAsString(e));
                                }
                            });
                            String responseData = joiner.join(list);

                            log.info("返回参数responseData:"+responseData);
                            //System.out.println("responseData:"+responseData);


                            byte[] uppedContent = new String(responseData.getBytes(), Charset.forName("UTF-8")).getBytes();
                            originalResponse.getHeaders().setContentLength(uppedContent.length);
                            return bufferFactory.wrap(uppedContent);
                        }));
                    }
                }
                return super.writeWith(body);
            }

            @Override
            public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
                return writeWith(Flux.from(body).flatMapSequential(p -> p));
            }
        };
        return chain.filter(exchange.mutate().response(response).build());
    }


}

结果演示

图片:
在这里插入图片描述

记录和帮助

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要在Spring Cloud Gateway添加POST请求参数,你需要使用Spring Cloud Gateway的过滤器。下面是一个示例: ```java @Component public class AddParameterGatewayFilterFactory extends AbstractGatewayFilterFactory<AddParameterGatewayFilterFactory.Config> { public AddParameterGatewayFilterFactory() { super(Config.class); } @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { ServerHttpRequest request = exchange.getRequest().mutate(). header(config.getHeaderName(), config.getHeaderValue()).build(); return chain.filter(exchange.mutate().request(request).build()); }; } public static class Config { private String headerName; private String headerValue; public String getHeaderName() { return headerName; } public void setHeaderName(String headerName) { this.headerName = headerName; } public String getHeaderValue() { return headerValue; } public void setHeaderValue(String headerValue) { this.headerValue = headerValue; } } } ``` 在这个示例,我们创建了一个过滤器工厂类 `AddParameterGatewayFilterFactory` 以添加POST请求参数。该过滤器将添加一个名为 `headerName` 的HTTP头和值为 `headerValue` 的HTTP头,这两个参数可以从配置文件或其他地方加载。 要使用此过滤器,请将以下内容添加到Spring Cloud Gateway的配置文件: ```yaml spring: cloud: gateway: routes: - id: add_parameter_route uri: http://example.com predicates: - Path=/example/** filters: - AddParameter=headerName=foo,headerValue=bar ``` 在这个示例,我们定义了一个名为 `add_parameter_route` 的路由,它将匹配所有以 `/example/` 开头的路径,并将其转发到 `http://example.com`。我们还将 `AddParameter` 过滤器添加到此路由,并将 `headerName` 设置为 `foo`,`headerValue` 设置为 `bar`。 现在,当客户端向Spring Cloud Gateway发送POST请求时,将自动添加 `foo: bar` HTTP头。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值