我对React式世界很陌生,现在我正试图创建两个HttpServerFilters,它们将Map用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方法是按正确的顺序调用的,但是React流中Map响应的方法是按相反的顺序调用的。
在我的示例中,我尝试首先使用当前响应主体(ServiceHttpResponse)中的信息设置响应状态,然后设置一个新的格式化主体,但由于这些主体以相反的顺序执行,因此首先设置新主体,有关响应状态的信息丢失。
是什么导致了这种行为?我测试了它使用2个以上的过滤器和顺序总是颠倒,所以它不是随机的。
1条答案
按热度按时间gwo2fgha1#
正如Jon Skeet所提到的,这是一个过滤器链。在这个链中,你的所有过滤器都按照给定的顺序排列。当链到达末端时,实际的控制器被调用。同样的过滤器链以相反的顺序被处理。
下面的图片说明了这个模式。它不是Micronaut所做的1:1,但它应该给予你一个印象,事情是如何工作的。
图片来源:https://www.informit.com/articles/article.aspx?p=1398619&seqNum=3