1、新建一个filter,把请求体缓存起来,并把优先级设为最高

​@Component
public class RequestFilter implements GlobalFilter, Ordered{
    public static final String CACHE_REQUEST_BODY_OBJECT_KEY= "cachedRequestBody";
 
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){
        try{
            MediaType mediaType = exchage.getRequest().getHeaders().getContentType();
            if(mediaType != null && (mediaType.equals(MediaType.APPLICATION_JSON || mediaType.equals(MediaType.APPLICATION_JSON_UTF8)))){
                return DataBufferUtils.join(exchange.getRequest.getBody()).flatMap(dataBuffer -> {
                    DataBufferUtils.retain(dataBuffer);
                    Flux<DataBuffer> cachedFlux = Flux.defer(() -> 
                        Flux.just(dataBuffer.slice(0, dataBuffer.readableByteCount())
					));
                    ServerHttpRequest mutateRequest = new ServerHttpRequestDecorator(exchange.getRequest()){
                        @Override
                        public FLux<DataBuffer> getBody(){
                            return cachedFlux;
                        }
                    };
                    exchage.getAttributes().put(CACHE_REQUEST_BODY_OBJECT_KEY, cachedFlux);
 
                    return chain.filter(exchage.mutate().request(mutateRequest).buid()); 
                });
            }
        }catch(Exception ex){
        
	}
    
	return chain.filter(exchange);
    }

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

2、获取请求体缓存并解析,并获取响应体

@Component
public class AuthFilter implements GloablFilter, Ordered{
	@Override
	public int getOrder(){
		return HIGHEST_PRECEDENCE + 1;
	}
	
	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GateWayFilterChain chain){
		ServerHttpRequest request = exchange.getRequest();
		
		return chain.filter(exchange.mutate().request(recordRequestLog(exchange)).response(recordResponseLog(exchange)).build());
		
	}
	
	/**
	* 记录请求日志
	*/
	private ServerHttpRequest recordRequestLog(ServerWebExchange exchange){
		ServerHttpRequest request = exchange.getRequest();
		MediaType mediaType = request.getHeaders().getContentType();
		ServerHttpRequest.Builder mutate = request.mutate();
		
		Map(String, String) requestParams = new HashMap<String, String>();
		if(mediaType == null){
			requestParams = request.getQueryParams().toSingleValueMap();
		} else if(mediaType.equals(MediaType.APPLICATION_JSON) || mediaType.equals(MediaType.APPLICATION_JSON_UTF8)){
			Object cacheBody = exchange.getAttribute("cachedRequestBodyObject");
			String bodyStr = resolveBodyFromFlux(Flux<DataBuffer> cacheBody);
			// 根据结果处理自己的逻辑
		}
		
		return mutate.buid();
	}
	
	/**
	* 解析请求体
	*/
	private static String resolveBodyFromFlux(Flux<DataBuffer> body){
		if(body == null) return "";
		
		AtomicReference<String> rawRef = new AtomicReference<>();
		body.subscribe(buffer -> {
			byte[] bytes = new byte[buffer.readableByteCount()];
			buffer.read(bytes);
			DataBufferUtils.release(buffer);
			rawRefset(String.fromUTF8ByteArray(bytes));
		})
		
		return rawRef.get();
	}
	
	/**
	* 记录响应日志
	*/
	private ServerHttpResponseDecorator recordResponseLog(ServerWebExchange exchange){
		ServerHttpResponse response = exchange.getResponse();
		MediaType mediaType = request.getHeaders().getContentType();
		
		DataBufferFactory bufferFactory = response.bufferFactory();
		ServerHttpResponseDecorator decoratorResponse = new ServerHttpResponseDecorator(response){
			@Override
			public Mono<Void> writeWith(Publisher<? extends DataBuffer> body){
				if(body instanceof Flux){
					// 过滤上传附件请求
					if((mediaType != null && mediaType.equals(MediaType.MULTIPART_FORM_DATA)) || (MediaType != null && mediaType.equals(MediaType.APPLICATION_FORM_URLENCODED)){
						return super.writeWith(body);
					} 
					
					Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;
					return super.writeWith(fluxBody.map(dataBuffer -> {
						byte[] content =  new byte[dataBuffer.readableByteCount()];
						dataBuffer.read(content);
						String responseResult = new String(content, Charset.forName("utf-8"));
						// 根据结果处理自己的逻辑
						
						return bufferFactory.wrap(content);
					}));
				}
				
				return super.writeWith(body);
			}
		}
	}
}

​

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐