@H_404_1@当方法返回CompletionStage时,我遇到了一个问题,即我的过滤器运行了两次.从RequestMapping(here)上的文档中,它是受支持的返回值.
@H_404_1@
>如果是这种情况,为什么我的过滤器在每种情况下运行两次?如果过滤器的工作是设置某个特定于请求的上下文,那么如果无法访问CompletionStage,则再次运行它是没有意义的.
>为什么过滤器运行两次到底是哪种方式?
@H_404_1@A CompletionStage (implemented by CompletableFuture for example) which the application uses to produce a return value in a separate thread of its own choosing,as an alternative to returning a Callable.@H_404_1@由于项目非常复杂,并且有很多并发代码,因此我创建了一个新的简单的spring-boot项目.这是(唯一的)控制器: @H_404_1@
@Controller
public class BaseController {
@RequestMapping("/hello")
@ResponseBody
public CompletionStageCompletableFuture.supplyAsync(() -> "Hello World");
}
}
@H_404_1@还有一个过滤器:
@H_404_1@
@WebFilter
@Component
public class GenericLoggingFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,servletexception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
System.out.println(httpServletRequest.getmethod() + " " +
httpServletRequest.getRequestURI());
chain.doFilter(request,response);
}
}
@H_404_1@当我打电话curl http:// localhost:8080 / hello时,它会在控制台上打印两次GET / hello.当我更改控制器方法以返回String时:
@H_404_1@
@RequestMapping("/hello")
@ResponseBody
public String world() {
return "Hello World";
}
@H_404_1@它只打印一次.即使我将其更改为Callable也会出现此行为,Callable没有真正的并发意义(当然,spring本身可能会将此视为异步请求).
@H_404_1@因此,如果spring再次运行整个Web堆栈以获得请求上下文,那么即使这样也没有意义,因为以下内容:
@H_404_1@
@RequestMapping("/hello")
@ResponseBody
public CompletionStageCompletableFuture.supplyAsync(() -> {
System.out.println(RequestContextHolder.currentRequestAttributes());
return "Hello World";
});
}
@H_404_1@抛出异常:IllegalStateException:找不到线程绑定请求…
@H_404_1@令人惊讶的是,以下工作:
@H_404_1@
@RequestMapping("/hello")
@ResponseBody
public Callablestem.out.println(RequestContextHolder.currentRequestAttributes());
return "Hello World";
};
}
@H_404_1@所以,我不确定相当多的事情.
@H_404_1@>似乎Callable和CompletionStage在执行哪个线程的上下文中被区别对待.>如果是这种情况,为什么我的过滤器在每种情况下运行两次?如果过滤器的工作是设置某个特定于请求的上下文,那么如果无法访问CompletionStage,则再次运行它是没有意义的.
>为什么过滤器运行两次到底是哪种方式?
最佳答案
请用OncePerRequestFilter替换GenericFilterBean.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。