【springcloud】 gateway获取到请求里面的参数修改覆盖和响应里的值修改覆盖并修改【全局过滤器】

项目实战中用到全局过滤器,rsa进行加密解密操作,前置过滤器解密参数覆盖传入请求接口中,后置过滤器加密接口响应数据返回值;

获取请求参数RequestBody【可进行修改赋值替换】

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.szzz.pay.agilepaygateway.rsakey.entity.RsaKeyTable;
import com.szzz.pay.agilepaygateway.rsakey.mapper.RsaKeyMapper;
import com.szzz.pay.agilepaygateway.utils.EncryptUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.factory.rewrite.CachedBodyOutputMessage;
import org.springframework.cloud.gateway.support.BodyInserterContext;
import org.springframework.cloud.gateway.support.DefaultServerRequest;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserter;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;



@Component
@Slf4j
public class WrapperRequestGlobalFilter implements GlobalFilter, Ordered {//, Ordered
    @Autowired
    private RsaKeyMapper rsaKeyMapper;

    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        ServerRequest serverRequest = new DefaultServerRequest(exchange);
        //获取渠道id
        String channelId = exchange.getRequest().getHeaders().getFirst("channelId");
        if (channelId != null) {
            //查看是否存在
            RsaKeyTable rsaKeyTable = new LambdaQueryChainWrapper<>(rsaKeyMapper)
                    .eq(RsaKeyTable::getChannelId, channelId).one();
            if (rsaKeyTable != null) {
                Mono modifiedBody = serverRequest.bodyToMono(String.class)
                        .flatMap(body -> {
                            //加密String转json对象
                            JSONObject jsonObject = JSONObject.parseObject(body);
                            String data= jsonObject.getString("dataOne");//获取加密数据值
                            //获取渠道对应支付私钥(其他项目传来的是用渠道对应支付公钥加密值)
                            String privateKeyPay = rsaKeyTable.getRsaPrivatePayKey();
                            try {
                                //私钥解密
                                String sp = EncryptUtil.decryptByPrivateKey(data, privateKeyPay);
                                // 解密后的值json字符串
                                String newBody = sp;
                                //TODO 获取body内容去干你想做的事
                                return Mono.just(newBody);
                            } catch (Exception e) {
                                e.printStackTrace();
                                //只要有异常就返回方法不允许
                                response.setStatusCode(HttpStatus.METHOD_NOT_ALLOWED);
                                //禁止访问
                                return Mono.empty();
                            }
                        });


                BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class);
                HttpHeaders headers = new HttpHeaders();
                headers.putAll(exchange.getRequest().getHeaders());
                headers.remove(HttpHeaders.CONTENT_LENGTH);
                CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
                return bodyInserter.insert(outputMessage, new BodyInserterContext())
                        .then(Mono.defer(() -> {
                            ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(
                                    exchange.getRequest()) {
                                @Override
                                public HttpHeaders getHeaders() {
                                    long contentLength = headers.getContentLength();
                                    HttpHeaders httpHeaders = new HttpHeaders();
                                    httpHeaders.putAll(super.getHeaders());
                                    if (contentLength > 0) {
                                        httpHeaders.setContentLength(contentLength);
                                    } else {
                                        httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
                                    }
                                    return httpHeaders;
                                }

                                @Override
                                public Flux getBody() {
                                    return outputMessage.getBody();
                                }
                            };
                            return chain.filter(exchange.mutate().request(decorator).build());
                        }));
            }else {
                //如果rsaKeyTable==null 也不准访问
                return exchange.getResponse().setComplete();
            }
        }else {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //禁止访问
            return exchange.getResponse().setComplete();
        }
    }


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

获取响应值ResponseBody【可进行修改赋值替换】


import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.szzz.pay.agilepaygateway.rsakey.entity.RsaKeyTable;
import com.szzz.pay.agilepaygateway.rsakey.mapper.RsaKeyMapper;
import com.szzz.pay.agilepaygateway.utils.EncryptUtil;
import lombok.extern.slf4j.Slf4j;
import org.reactivestreams.Publisher;
import org.springframework.beans.factory.annotation.Autowired;
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.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
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.Charset;
import java.util.Map;

@Component
@Slf4j
public class WrapperResponseGlobalFilter implements GlobalFilter, Ordered {
    @Autowired
    private RsaKeyMapper rsaKeyMapper;

    @Override
    public int getOrder() {
        // -1 is response write filter, must be called before that
        return -1;
    }

    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
       log.info("===============过滤返回值加密=====================");
        ServerHttpResponse originalResponse = exchange.getResponse();
        DataBufferFactory bufferFactory = originalResponse.bufferFactory();
        ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
            @Override
            public Mono writeWith(Publisher body) {
                if (body instanceof Flux) {
                    Flux fluxBody = (Flux) body;
                    return super.writeWith(fluxBody.map(dataBuffer -> {
                        byte[] content = new byte[dataBuffer.readableByteCount()];
                        dataBuffer.read(content);
                        //释放掉内存
                        DataBufferUtils.release(dataBuffer);
                        String s = new String(content, Charset.forName("UTF-8"));
                        String channelId = exchange.getRequest().getHeaders().getFirst("channelId");
                        RsaKeyTable rsaKeyTable = new LambdaQueryChainWrapper<>(rsaKeyMapper)
                                .eq(RsaKeyTable::getChannelId, channelId).one();
                        //通过渠道id获取对应渠道的公钥
                        String channelPublicKey=rsaKeyTable.getRsaPublicKey();
                        //渠道私钥他们对应渠道自己有留存,不需要传||渠道对应的公私钥和支付项目的公私钥他们渠道那边都可以查到?根据渠道id,所以不需要传给他们,他们自己获取即可,我们传渠道公钥加密后的值就可以,他们那边用对应渠道私钥进行解密
                        System.out.println("过滤返回值明文:" + s);
                        String pubKeyEncrypt = "";
                        try {
                            pubKeyEncrypt = EncryptUtil.encryptByPublicKey(s, channelPublicKey);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        System.out.println("过滤返回值公钥加密:" + pubKeyEncrypt);
                        //TODO,s就是response的值,想修改、查看就随意而为了
                        byte[] uppedContent =   pubKeyEncrypt.getBytes();//new String(content, Charset.forName("UTF-8")).getBytes();
                        return bufferFactory.wrap(uppedContent);
                    }));
                }
                return super.writeWith(body);
            }
        };
        return chain.filter(exchange.mutate().response(decoratedResponse).build());
    }
}

附:
String转成JSON

依赖


        com.alibaba
        fastjson
        1.2.15
    

String转成JSON

String json = "{\"abc\":\"1\",\"hahah\":\"2\"}";
JSONObject jsonObject = JSONObject.parseObject(content);
想要取出值,可以对`jsonObject`进行操作:
jsonObject.getString("abc");
结果为:`1`

将String转为list后转为JSON

List list = new ArrayList();  
list.add("username");  
list.add("adress");  
list.add("age");  
JSONArray array = new JSONArray();  
array.add(list);  

将String转为map后转为JSON

Map map = new HashMap();
    map.put("abc", "abc");
map.put("def", "efg");
JSONArray array_test = new JSONArray();
array_test.add(map);
    JSONObject jsonObject = JSONObject.fromObject(map);

你可能感兴趣的:(springcloud,java,spring,cloud)