当前位置:

GateWay 通过拦截器获取请求参数

机器助手 |  2025-07-13
 101人浏览

通过自定义拦截器的方式拦截请求,并获取请求体参数。

  1. Spring Boot:2.7.12
  2. Spring Cloud: 2021.0.4.0
@Component
public class AuthorizeFilter implements Ordered, GlobalFilter {

    private static final Integer UNAUTHORIZED = 401;
    private static final String MSG = "系统异常";

    private static final String GET_METHOD = "GET";
    private static final String POST_METHOD = "POST";
    private static final String PATH = "XXXX";



    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String uri = request.getPath().value();
        String method = request.getMethodValue();
        HttpHeaders header = request.getHeaders();

        String contentType = header.getFirst("content-type");

        if (StringUtils.hasLength(contentType) && contentType.contains("multipart/form-data")) {
            return chain.filter(exchange);
        }

        if (POST_METHOD.matches(method) && PATH.equals(uri)) {
            return DataBufferUtils.join(exchange.getRequest().getBody())
                    .flatMap(dataBuffer -> {
                        byte[] bytes = new byte[dataBuffer.readableByteCount()];
                        dataBuffer.read(bytes);
                        String bodyString = new String(bytes, StandardCharsets.UTF_8);
                        exchange.getAttributes().put("POST_BODY", bodyString);
                        DataBufferUtils.release(dataBuffer);
                        RsaResponse rsaResponse = JSON.parseObject(bodyString, RsaResponse.class);

                        //TODO 验签
                        try {
                            //业务逻辑
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                        Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
                            DataBuffer buffer = exchange.getResponse().bufferFactory()
                                    .wrap(bytes);
                            return Mono.just(buffer);
                        });
                        //使用装饰器将请求包装,重写getBody方法。
                        //这样后面的过滤器中再使用exchange.getRequest().getBody()来获取body时,
                        //实际上就是调用的重载后的getBody方法,获取的最先的body数据。这样就能够实现body的多次读取了。
                        ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
                                exchange.getRequest()) {
                            @Override
                            public Flux<DataBuffer> getBody() {
                                return cachedFlux;
                            }
                        };
                        return chain.filter(exchange.mutate().request(mutatedRequest)
                                .build());
                    });
        } else {
            return chain.filter(exchange);
        }
    }

    /**
     * 数字越小,优先级越高
     *
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }

    private Mono<Void> invalidMono(ServerWebExchange exchange) {
        ResultMsg resultMsg = new ResultMsg(UNAUTHORIZED, MSG, null);
        return buildReturnMono(resultMsg, exchange);

    }

    private Mono<Void> buildReturnMono(ResultMsg resultMsg, ServerWebExchange exchange) {
        ServerHttpResponse response = exchange.getResponse();
        byte[] bits = JSON.toJSONString(resultMsg).getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bits);
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        response.getHeaders().add("Content-Type", "application/json;charset:utf-8");
        return response.writeWith(Mono.just(buffer));
    }
}

文章评论