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