【发布时间】:2018-10-10 14:55:33
【问题描述】:
我在一个项目中使用带有 Spring 5、Spring Reactor 和 Netty 的 Spring Cloud Gateway。对于发送到网关的每个请求,我想在响应发送到客户端之前做一些事情。我发现最好的方法是使用 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())));
}
});
这次我没有任何异常,我可以修改内容长度但我不能修改响应的正文。
那么有人知道是否可以这样做以及如何做吗?
【问题讨论】:
-
我使用调试器试图了解正在发生的事情,似乎正文是由最后一个过滤器 NettyWriteResponseFilter 编写的。所以就在提交之前已经太晚了,身体不再可用。但令人困惑的是我仍然可以访问标题。因此,如果有人有一个想法并且知道如何运行一段可以在响应被验证并发送给客户端之前修改响应的代码,我真的很想知道。
-
可能类似于stackoverflow.com/questions/48491098/…,但答案没有帮助,因为它只处理异常
标签: spring project-reactor spring-cloud-gateway