gateway过滤器获取请求参数及打印

第一个过滤器

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.*;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class RequestParamsFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String method = request.getMethodValue();
        if ("POST".equals(method)) {
            //如果body里空,这三行代码不能省
            DefaultDataBufferFactory defaultDataBufferFactory = new DefaultDataBufferFactory();
            DefaultDataBuffer defaultDataBuffer = defaultDataBufferFactory.allocateBuffer(0);
            Mono<DataBuffer> mono = Flux.from(exchange.getRequest().getBody().defaultIfEmpty(defaultDataBuffer)).collectList().filter(list -> true).map(list -> list.get(0).factory().join(list)).doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release);
            //读取后重新封装请求
            return mono.flatMap(dataBuffer -> {
                byte[] bytes = new byte[dataBuffer.readableByteCount()];
                dataBuffer.read(bytes);
                DataBufferUtils.release(dataBuffer);
                String body = new String(bytes, StandardCharsets.UTF_8);
                exchange.getAttributes().put("MY_PAYLOAD", body);
                //这是必须要重新封装一个请求, 因为body只能读一次,下游将无法读取,真操蛋
                Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
                    DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);
                    return Mono.just(buffer);
                });
                ServerHttpRequest newRequest = new ServerHttpRequestDecorator(request) {
                    @Override
                    public Flux<DataBuffer> getBody() {
                        return cachedFlux;
                    }
                };
                return chain.filter(exchange.mutate().request(newRequest).build());
            });
        } else if ("GET".equals(method)) {
            if("GET".equals(method)){
                Map<String, String> params = new HashMap<>();
                request.getQueryParams().forEach((k,v)-> params.put(k, v.get(0)));
                exchange.getAttributes().put("MY_PAYLOAD", JSON.toJSONString(params));
            }
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }

}

第二个过滤器

	private ServerHttpResponse getResponse(ServerWebExchange exchange, boolean isValid, String path, GatewayRequestHeader headerObj){
        long sts = System.currentTimeMillis();
        ServerHttpResponse response = exchange.getResponse();
        DataBufferFactory bufferFactory = response.bufferFactory();
        ServerHttpResponseDecorator responseNew = new ServerHttpResponseDecorator(response) {
            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                if (getStatusCode().equals(HttpStatus.OK) && body instanceof Flux) {
                    String originalResponseContentType = exchange.getAttribute(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR);
                    if (StringUtils.isNotBlank(originalResponseContentType) && originalResponseContentType.contains("application/json")) {
                        Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;
                        return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
                            String resp;
                            if(isValid){
                                //DefaultDataBufferFactory join 乱码的问题解决
                                DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
                                DataBuffer join = dataBufferFactory.join(dataBuffers);
                                // probably should reuse buffers
                                byte[] content = new byte[join.readableByteCount()];
                                join.read(content);
                                //释放掉内存
                                DataBufferUtils.release(join);
                                resp = new String(content, StandardCharsets.UTF_8);
                            }else {
                                Map<String, Object> map = new HashMap<>();
                                map.put("code", "401");
                                map.put("message", "UNAUTHORIZED");
                                resp = JSON.toJSONString(map);
                            }
                            logPrint(exchange, path, resp, sts, headerObj);
                            return bufferFactory.wrap(resp.getBytes());
                        }));
                    }
                }
                logPrint(exchange, path, "", sts, headerObj);
                return super.writeWith(body);
            }
        };
        return responseNew;
    }

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

posted @ 2023-02-27 09:18  码农记事本  阅读(592)  评论(0)    收藏  举报