我对反应世界很陌生,现在我正在尝试创建两个 HttpServerFilters,它们将映射用 micronaut 编写的服务器中的响应。为了提出我的问题,我准备了简化的代码片段:
@Filter("/**")
public class FirstFilter implements HttpServerFilter {
@Override
public int getOrder(){
return ServerFilterPhase.FIRST.before();
}
@Override
public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
System.out.println("Returning publisher in FirstFilter!");
return Publishers.then(
chain.proceed(request),
mutableHttpResponse -> {
System.out.println("Mapping response in first filter!");
mutableHttpResponse.getBody(ServiceHttpResponse.class)
.ifPresent(resp -> mutableHttpResponse.status(resp.getStatus()));
});
}
}
@Filter("/**")
public class SecondFilter implements HttpServerFilter {
@Override
public int getOrder(){
return ServerFilterPhase.FIRST.after();
}
@Override
public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
System.out.println("Returning publisher in SecondFilter!");
return Publishers.then(
chain.proceed(request),
mutableHttpResponse -> {
System.out.println("Mapping response in second filter!");
mutableHttpResponse.getBody(ServiceHttpResponse.class)
.ifPresent(resp -> mutableHttpResponse.body(resp.format()));
});
}
}
执行请求后的日志如下:
Returning publisher in FirstFilter!
Returning publisher in SecondFilter!
Mapping response in second filter!
Mapping response in first filter!
从日志中我可以看到 doFilter 方法以正确的顺序调用,但是映射响应的反应流中的方法以相反的顺序调用。
在我的示例中,我尝试首先使用来自当前响应正文 (ServiceHttpResponse) 的信息设置响应状态,然后设置一个新的格式化正文,但是因为这些以相反的顺序执行,所以首先设置新正文并且有关响应状态的信息丢失。
是什么导致了这种行为?我使用 2 个以上的过滤器对其进行了测试,并且顺序总是颠倒的,所以它不是随机的。