gateway网关转发get请求Post请求添加参数

5 篇文章 0 订阅
4 篇文章 0 订阅

在继承AbstractGatewayFilterFactory的过滤器中

GET请求添加参数

// 参考api文档中GatewapFilter中“添加请求参数拦截器”:AddRequestParameterGatewayFilterFactory.java
 
            //记录日志
            //logger.info("全局参数处理: {} url:{} 参数:{}",method.toString(),serverHttpRequest.getURI().getRawPath(),newRequestQueryParams.toString());
            // 获取原参数
            URI uri = serverHttpRequest.getURI();
            StringBuilder query = new StringBuilder();
            String originalQuery = uri.getRawQuery();
            if (org.springframework.util.StringUtils.hasText(originalQuery)) {
                query.append(originalQuery);
                if (originalQuery.charAt(originalQuery.length() - 1) != '&') {
                    query.append('&');
                }
            }
            // 添加查询参数
            query.append(ServiceConstants.COMMON_PARAMETER_ENTERPRISEID+"="+authenticationVO.getEnterpriseId()
                    +"&"+ServiceConstants.COMMON_PARAMETER_USERID+"="+authenticationVO.getUserId());
 
            // 替换查询参数
            URI newUri = UriComponentsBuilder.fromUri(uri)
                    .replaceQuery(query.toString())
                    .build(true)
                    .toUri();
 
            ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();
            return chain.filter(exchange.mutate().request(request).build());

POST请求添加参数

//从请求里获取Post请求体
                    String bodyStr = resolveBodyFromRequest(serverHttpRequest);
                    String userId = "123";
// 这种处理方式,必须保证post请求时,原始post表单必须有数据过来,不然会报错
                    if (StringUtils.isEmpty(bodyStr)) {
                        logger.error("请求异常:{} POST请求必须传递参数", serverHttpRequest.getURI().getRawPath());
                        ServerHttpResponse response = exchange.getResponse();
                        response.setStatusCode(HttpStatus.BAD_REQUEST);
                        return response.setComplete();
                    }

                    //application/x-www-form-urlencoded和application/json才添加参数
                    //其他上传文件之类的,不做参数处理,因为文件流添加参数,文件原格式就会出问题了
                   /* if (MediaType.APPLICATION_FORM_URLENCODED_VALUE.equalsIgnoreCase(contentType)) {
                        // 普通键值对,增加参数
                        bodyStr = String.format(bodyStr+"&%s=%s&%s=%s",ServiceConstants.COMMON_PARAMETER_ENTERPRISEID,authenticationVO.getEnterpriseId()
                                ,ServiceConstants.COMMON_PARAMETER_USERID,authenticationVO.getUserId());
                    }*/
                    // 新增body参数
                    if (MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(contentType)) {
                        JSONObject jsonObject = new JSONObject(bodyStr);
                        jsonObject.put("userId", userId);
                        bodyStr = jsonObject.toString();
                    }
                    //记录日志
                    logger.info("全局参数处理: {} url:{} 参数:{}", method.toString(), serverHttpRequest.getURI().getRawPath(), bodyStr);

                    //下面的将请求体再次封装写回到request里,传到下一级,否则,由于请求体已被消费,后续的服务将取不到值
                    URI uri = serverHttpRequest.getURI();
                    URI newUri = UriComponentsBuilder.fromUri(uri).build(true).toUri();
                    ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();
                    DataBuffer bodyDataBuffer = stringBuffer(bodyStr);
                    Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);

                    // 定义新的消息头
                    HttpHeaders headers = new HttpHeaders();
                    headers.putAll(exchange.getRequest().getHeaders());

                    // 添加消息头
//                    headers.set(ServiceConstants.SHIRO_SESSION_PRINCIPALS,GsonUtils.toJson(authenticationVO));

                    // 由于修改了传递参数,需要重新设置CONTENT_LENGTH,长度是字节长度,不是字符串长度
                    int length = bodyStr.getBytes().length;
                    headers.remove(HttpHeaders.CONTENT_LENGTH);
                    headers.setContentLength(length);

                    // 设置CONTENT_TYPE
                    if (StringUtils.isEmpty(contentType)) {
                        headers.set(HttpHeaders.CONTENT_TYPE, contentType);
                    }

                    // 由于post的body只能订阅一次,由于上面代码中已经订阅过一次body。所以要再次封装请求到request才行,不然会报错请求已经订阅过
                    request = new ServerHttpRequestDecorator(request) {
                        @Override
                        public HttpHeaders getHeaders() {
                            long contentLength = headers.getContentLength();
                            HttpHeaders httpHeaders = new HttpHeaders();
                            httpHeaders.putAll(super.getHeaders());
                            if (contentLength > 0) {
                                httpHeaders.setContentLength(contentLength);
                            } else {
                                // TODO: this causes a 'HTTP/1.1 411 Length Required' on httpbin.org
                                httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
                            }
                            return httpHeaders;
                        }

                        @Override
                        public Flux<DataBuffer> getBody() {
                            return bodyFlux;
                        }
                    };

                    //封装request,传给下一级
                    request.mutate().header(HttpHeaders.CONTENT_LENGTH, Integer.toString(bodyStr.length()));
                    return chain.filter(exchange.mutate().request(request).build());


   /**
     * 从Flux<DataBuffer>中获取字符串的方法
     * @return 请求体
     */
    private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {
        //获取请求体
        Flux<DataBuffer> body = serverHttpRequest.getBody();

        AtomicReference<String> bodyRef = new AtomicReference<>();
        body.subscribe(buffer -> {
            CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
            DataBufferUtils.release(buffer);
            bodyRef.set(charBuffer.toString());
        });
        //获取request body
        return bodyRef.get();
    }

/**
* 字符串转DataBuffer
* @param value
* @return
*/
private DataBuffer stringBuffer(String value) {
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
buffer.write(bytes);
return buffer;
}

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值