Only one connection receive subscriber allowed.

这个filter 中报Only one connection receive subscriber allowed.

主要是body体为null的情况

@Component
public class DecryptionFilter implements GlobalFilter, Ordered {

@SneakyThrows
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {

解决办法:
Only one connection receive subscriber allowed._第1张图片
参考:https://blog.csdn.net/weixin_37644979/article/details/115264027

完全代码:

package com.riocento.filter;


import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.ByteBufAllocator;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
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.DataBuffer;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.CoreSubscriber;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Iterator;

/**
 * 解密过滤器
 * 对请求的request进行解密
 */
@Slf4j
@Component
public class DecryptionFilter implements GlobalFilter, Ordered {

    @SneakyThrows
    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("request解密处理");
        //源request对象
        ServerHttpRequest request = exchange.getRequest();
        //获取请求方式
        HttpMethod method = request.getMethod();
        URI uri = request.getURI();
        log.info("请求方式:"+method);
        log.info("请求地址:"+uri);
        MultiValueMap queryParams = request.getQueryParams();
        log.info("所有参数:"+queryParams);
        //是否为加密参数
        Boolean isEncrypt = false;
        // GET请求解密
        if(HttpMethod.GET == method){
            if(queryParams.containsKey("isEncrypt")){
                isEncrypt = Boolean.valueOf(queryParams.get("isEncrypt").get(0));
            }
            if(isEncrypt){
                //加密参数
                String enParams = queryParams.get("enParams").get(0);
                //将参数解密
                String paramsStr = AESUtil.decrypt(enParams);
                //格式化参数
                String urlParams = formatUrlParams(paramsStr);
                //重新创建request
                URI plaintUrl = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), urlParams, uri.getFragment());
                ServerHttpRequest newRequest = request.mutate().uri(plaintUrl).build();
                return chain.filter(exchange.mutate().request(newRequest).build());
            }
        }
        //POST和PUT请求解密
        else if(HttpMethod.POST == method
                || HttpMethod.PUT == method) {
            if(queryParams.containsKey("isEncrypt")){
                isEncrypt = Boolean.valueOf(queryParams.get("isEncrypt").get(0));
            }
            if(isEncrypt){
                URI plaintUrl = null;
                //处理url参数
                if(queryParams.size() > 0 && queryParams.containsKey("enParams")){
                    //加密参数
                    String urlEnParams = queryParams.get("enParams").get(0);
                    //将参数解密
                    String urlParamsStr = AESUtil.decrypt(urlEnParams);
                    //格式化参数
                    String urlParams = formatUrlParams(urlParamsStr);
                    //重新创建uri
                    plaintUrl = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), urlParams, uri.getFragment());
                }else{
                    plaintUrl = uri;
                }

                //处理表单参数
                //获取表单信息
                Flux dataBufferFlux = request.getBody();
                //获取body中的数据
                String strBody = FilterRequestResponseUtil.resolveBodyFromRequest(dataBufferFlux);
                //获取加密参数
                String enParams = getEnParams(strBody);
                //将参数解密
                String paramsStr = AESUtil.decrypt(enParams);

                ServerHttpRequest newRequest = request.mutate().uri(plaintUrl).build();
                DataBuffer bodyDataBuffer = stringBuffer(paramsStr);
                if(paramsStr == null) {
                    newRequest = new ServerHttpRequestDecorator(newRequest) {
                        @Override
                        public Flux getBody() {
                            return Flux.just(bodyDataBuffer);
                        }
                    };
                    // 构建新的请求头
                    HttpHeaders headers = new HttpHeaders();
                    headers.putAll(exchange.getRequest().getHeaders());
                    // 重新设置CONTENT_LENGTH
                    int length = 0;
                    headers.remove(HttpHeaders.CONTENT_LENGTH);
                    headers.setContentLength(length);
                    newRequest = new ServerHttpRequestDecorator(newRequest) {
                        @Override
                        public HttpHeaders getHeaders() {
                            return headers;
                        }
                    };
                    return chain.filter(exchange.mutate().request(newRequest).build());
                }
                Flux bodyFlux = Flux.just(bodyDataBuffer);
                newRequest = new ServerHttpRequestDecorator(newRequest) {
                    @Override
                    public Flux getBody() {
                        return bodyFlux;
                    }
                };
                // 构建新的请求头
                HttpHeaders headers = new HttpHeaders();
                headers.putAll(exchange.getRequest().getHeaders());
                // 重新设置CONTENT_LENGTH
                int length = paramsStr.getBytes().length;
                headers.remove(HttpHeaders.CONTENT_LENGTH);
                headers.setContentLength(length);
                newRequest = new ServerHttpRequestDecorator(newRequest) {
                    @Override
                    public HttpHeaders getHeaders() {
                        return headers;
                    }
                };
                return chain.filter(exchange.mutate().request(newRequest).build());
            }
        }
        //DELETE等请求方式不做处理
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }

    /**
     * 格式化url参数
     * @param paramsStr 字符串参数
     */
    private String formatUrlParams(String paramsStr){
        StringBuilder stbResult = new StringBuilder();
        if(Strings.isNotEmpty(paramsStr)){
            if(paramsStr.startsWith("{")){
                JSONObject paramsJSON = JSONObject.parseObject(paramsStr);
                Iterator iterator = paramsJSON.keySet().iterator();
                while (iterator.hasNext()) {
                    String key = iterator.next();
                    String value = paramsJSON.getString(key);
                    if(stbResult.length() > 0){
                        stbResult.append("&");
                    }
                    stbResult.append(key).append("=").append(value);
                }
            }else{
                stbResult.append(paramsStr);
            }
        }

        return stbResult.toString();
    }

    /**
     * 获取加密字符串参数
     * @return
     */
    private String getEnParams(String paramsStr){
        String result = null;
        if(Strings.isNotEmpty(paramsStr)){
            if(paramsStr.startsWith("{")){
                //将字符串转换为JSON格式
                JSONObject jsonBody = JSONObject.parseObject(paramsStr);
                result = jsonBody.getString("enParams");
            }else if(paramsStr.indexOf("=") > 0){
                String[] paramsArr = paramsStr.split("=");
                result = paramsArr[1];
            }
        }
        return  result;
    }

    private DataBuffer stringBuffer(String value) {
        if(value == null) {
            NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
            DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(0);
            return buffer;
        }
        byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
        NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
        DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
        buffer.write(bytes);
        return buffer;
    }
}

你可能感兴趣的:(springboot,java,log4j,apache)