gateway获取请求体和响应体

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);
			}
		}
	}
}

​

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
如果你想在Spring Cloud Gateway中根据响应的内容来判断是否进行转发请求或返回结果,可以使用Spring Cloud Gateway提供的GlobalFilter来实现。 具步骤如下: 1. 在Spring Cloud Gateway中定义一个GlobalFilter,例如: ``` @Component public class MyFilter implements GlobalFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { return chain.filter(exchange).then(Mono.fromRunnable(() -> { ServerHttpResponse response = exchange.getResponse(); HttpStatus statusCode = response.getStatusCode(); if (statusCode == HttpStatus.OK) { // 获取响应内容 byte[] bytes = ((DataBuffer) response.getBody()).asByteBuffer().array(); String responseBody = new String(bytes, StandardCharsets.UTF_8); // 判断响应内容是否需要转发请求 if (responseBody.contains("需要转发请求的关键字")) { // 构造新的请求URI URI newUri = UriComponentsBuilder.fromUri(exchange.getRequest().getURI()) .host("newhost") .path("newpath") .build() .toUri(); // 构造新的请求对象 ServerHttpRequest newRequest = exchange.getRequest().mutate().uri(newUri).build(); // 转发新的请求 chain.filter(exchange.mutate().request(newRequest).build()); } else { // 返回响应内容 response.getHeaders().setContentLength(responseBody.length()); DataBuffer buffer = response.bufferFactory().wrap(responseBody.getBytes(StandardCharsets.UTF_8)); return response.writeWith(Flux.just(buffer)); } } })); } } ``` 这个GlobalFilter会在每个请求响应之后执行,获取响应内容并根据内容判断是否需要转发请求或返回响应内容。 2. 在Spring Cloud Gateway的配置文件中配置这个GlobalFilter,例如: ``` spring: cloud: gateway: default-filters: - MyFilter ``` 这个配置将这个GlobalFilter添加到默认的过滤器列表中,使其在每个请求中都被执行。 注意:这个GlobalFilter的核心逻辑是根据响应内容来判断是否需要转发请求或返回响应内容。如果需要转发请求,可以构造新的请求URI和请求对象,然后使用GatewayFilterChain的filter方法来执行新的请求。如果需要返回响应内容,可以构造一个新的DataBuffer对象,并使用ServerHttpResponse的writeWith方法来返回响应内容。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yujiubo2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值