ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SpringCloudGateway修改requestBody导致form-data不支持问题解决

2021-07-28 10:33:44  阅读:590  来源: 互联网

标签:traceId return form exchange restContext SpringCloudGateway requestBody new publ


0.修改requestBody旧方法

0.1 使用 ModifyRequestBodyGatewayFilterFactory

@Slf4j
@Component
public class GlobalFilterImpl implements GlobalFilter, Ordered {

    @Autowired
    GatewayComponent gatewayComponent;

    @Override
    public int getOrder() {
        return -999;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String traceId = MDC.get("traceId");
        exchange.getResponse().getHeaders().add("traceId", traceId);
        ModifyRequestBodyGatewayFilterFactory.Config cf = new ModifyRequestBodyGatewayFilterFactory.Config();
        cf.setRewriteFunction(Object.class, Object.class, gatewayComponent.getRewriteFunction());
        GatewayFilter customerFilter = new ModifyRequestBodyGatewayFilterFactory().apply(cf);
        return customerFilter.filter(exchange, chain);
   
    }

}

0.2 GatewayComponent 鉴权业务

@Slf4j
@Component
public class GatewayComponent {

  public RewriteFunction<Object, Object> getRewriteFunction() {
    return (serverWebExchange, body) -> {
      ServerHttpRequest request = serverWebExchange.getRequest();
		//鉴权逻辑
      LinkedHashMap bodyMap = (LinkedHashMap) body;
      RestContext restContext = new RestContext();
      restContext.setTokenUuid(tokenUuid);
      restContext.setUserId(userId);
      restContext.setProjectId(projectId);
      restContext.setCorpId(corpId);
      restContext.setUserType(userType);
      bodyMap.put("restContext", restContext);
      return Mono.just(bodyMap);
    };
  }

}

以上 存在contentType为multipart/form-data时会报错不支持。

1. 优化后的实现

1.1 全局过滤器 不变

@Slf4j
@Component
public class GlobalFilterImpl implements GlobalFilter, Ordered {

    @Autowired
    GatewayComponent gatewayComponent;

    @Override
    public int getOrder() {
        return -999;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String traceId = MDC.get("traceId");
        exchange.getResponse().getHeaders().add("traceId", traceId);
        return chain.filter(exchange);
    }

}

1.2 新增鉴权过滤器

@Slf4j
@Component
public class TokenFilter implements GlobalFilter, Ordered {

  @Override
  public int getOrder() {
    return -100;
  }

  @Override
  public Mono<Void> filter(
    ServerWebExchange exchange,
    GatewayFilterChain chain
  ) {
    ServerHttpRequest request = exchange.getRequest();
    MediaType mediaType = exchange.getRequest().getHeaders().getContentType();
    if (MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)) {
      ServerRequest serverRequest = ServerRequest.create(
        exchange,
        HandlerStrategies.withDefaults().messageReaders()
      );
      Mono<LinkedHashMap> modifiedBody = serverRequest
        .bodyToMono(LinkedHashMap.class)
        .flatMap(
          body -> {
            RestContext restContext = new RestContext();
            restContext.setTokenUuid(tokenUuid);
            restContext.setUserId(userId);
            restContext.setProjectId(projectId);
            restContext.setCorpId(corpId);
            restContext.setUserType(userType);
            body.put("restContext", restContext);
            return Mono.just(body);
          }
        );

      BodyInserter bodyInserter = BodyInserters.fromPublisher(
        modifiedBody,
        LinkedHashMap.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(
            () -> {
              ServerHttpRequest decorator = decorate(
                exchange,
                headers,
                outputMessage
              );
              return chain.filter(exchange.mutate().request(decorator).build());
            }
          )
        );
    }
    return chain.filter(exchange);
  }

  ServerHttpRequestDecorator decorate(
    ServerWebExchange exchange,
    HttpHeaders headers,
    CachedBodyOutputMessage outputMessage
  ) {
    return 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<DataBuffer> getBody() {
        return outputMessage.getBody();
      }
    };
  }
}

标签:traceId,return,form,exchange,restContext,SpringCloudGateway,requestBody,new,publ
来源: https://blog.csdn.net/codeLife1993/article/details/119171383

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有