我正在将Spring Cloud Gateway与Spring 5,Spring Reactor和Netty用于一个项目。对于发送到网关的每个请求,我想在响应发送到客户端之前做一些事情。我发现这样做的最好方法是使用beforeCommit方法为响应添加一个动作。
我首先尝试了这种方法:
exchange.getResponse().beforeCommit(() -> {
ServerHttpResponse response = exchange.getResponse();
try {
myActionDoneHere();
response.setStatusCode(OK);
return Mono.empty();
} catch (Exception ex) {
return Mono.error(new MyException(ex));
}
});
并尝试在异常处理程序中处理异常:
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
if (isMyException(ex)) {
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
exchange.getResponse().getHeaders().setContentLength(MSG.length());
exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8);
return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(MSG.getBytes())));
}
return Mono.error(ex);
}
当我这样做时,当我尝试修改内容长度时,我有一个例外。如果我了解情况。我无法在我的处理程序中修改响应,因为它已经提交了。所以我尝试了另一个解决方案并尝试在提交之前执行的操作中修改响应:
exchange.getResponse().beforeCommit(() -> {
ServerHttpResponse response = exchange.getResponse();
try {
myActionDoneHere();
response.setStatusCode(OK);
return Mono.empty();
} catch (Exception ex) {
response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
response.getHeaders().setContentLength(MSG.length());
response.getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8);
return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(MSG.getBytes())));
}
});
这次我没有任何异常,我可以修改内容长度,但我无法修改响应的正文。
有人知道是否可以这样做以及如何?
答案 0 :(得分:0)
我使用了WebClientWriteResponseFilter
内的技术
if (failedAuthorization) {
ServerWebExchangeUtils.setResponseStatus(exchange, HttpStatus.UNAUTHORIZED);
ServerWebExchangeUtils.setAlreadyRouted(exchange);
final Map<String, String> error = Map.of("error", "unauthorized");
return chain.filter(exchange).then(Mono.defer(() -> {
final ServerHttpResponse response = exchange.getResponse();
response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8.toString());
return response.writeWith(new Jackson2JsonEncoder().encode(Mono.just(error),
response.bufferFactory(),
ResolvableType.forInstance(error),
MediaType.APPLICATION_JSON_UTF8,
Hints.from(Hints.LOG_PREFIX_HINT, exchange.getLogPrefix()))
);
}));
}