Java 弹簧启动启用<;支持异步>;就像在web.xml中一样
我对Spring引导配置有问题。我在一些应该使用套接字的移动设备上遇到异常:Java 弹簧启动启用<;支持异步>;就像在web.xml中一样,java,spring,spring-mvc,spring-boot,Java,Spring,Spring Mvc,Spring Boot,我对Spring引导配置有问题。我在一些应该使用套接字的移动设备上遇到异常: java.lang.IllegalArgumentException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-su
java.lang.IllegalArgumentException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-supported>true</async-supported>" to servlet and filter declarations in web.xml. Also you must use a Servlet 3.0+ container
at org.springframework.util.Assert.isTrue(Assert.java:65)
at org.springframework.http.server.ServletServerHttpAsyncRequestControl.<init>(ServletServerHttpAsyncRequestControl.java:59)
at org.springframework.http.server.ServletServerHttpRequest.getAsyncRequestControl(ServletServerHttpRequest.java:202)
at org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession.handleInitialRequest(AbstractHttpSockJsSession.java:202)
at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportHandler.handleRequestInternal(AbstractHttpSendingTransportHandler.java:66)
at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportHandler.handleRequest(AbstractHttpSendingTransportHandler.java:58)
at org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService.handleTransportRequest(TransportHandlingSockJsService.java:254)
at org.springframework.web.socket.sockjs.support.AbstractSockJsService.handleRequest(AbstractSockJsService.java:322)
at org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler.handleRequest(SockJsHttpRequestHandler.java:88)
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
...
java.lang.IllegalArgumentException:必须在servlet和异步请求处理中涉及的所有筛选器上启用异步支持。这是在Java代码中使用Servlet API完成的,或者通过向Servlet添加“true”并在web.xml中过滤声明来完成的。您还必须使用Servlet 3.0+容器
位于org.springframework.util.Assert.isTrue(Assert.java:65)
位于org.springframework.http.server.ServletServerHttpAsyncRequestControl。(ServletServerHttpAsyncRequestControl.java:59)
位于org.springframework.http.server.ServletServerHttpRequest.getAsyncRequestControl(ServletServerHttpRequest.java:202)
位于org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession.handleInitialRequest(AbstractHttpSockJsSession.java:202)
位于org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportorHandler.HandlerRequestInternal(AbstractHttpSendingTransportorHandler.java:66)
位于org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportorHandler.HandlerRequest(AbstractHttpSendingTransportorHandler.java:58)
位于org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService.HandletTransportRequest(TransportHandlingSockJsService.java:254)
位于org.springframework.web.socket.sockjs.support.AbstractSockJsService.HandlerRequest(AbstractSockJsService.java:322)
位于org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler.handleRequest(SockJsHttpRequestHandler.java:88)
位于org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51)
位于org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
位于org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
位于org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
位于org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
位于javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
位于org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
位于javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
...
从异常中可以看出,我必须通过在web.xml文件中添加true来启用异步处理。但这就是问题所在,因为我没有它——我们的项目使用SpringBoot
有没有办法像Spring Boot那样提供相同的功能?您只需要定义
dispatcherServlet
@Bean
:
@Bean
public ServletRegistrationBean dispatcherServlet() {
ServletRegistrationBean registration = new ServletRegistrationBean(
new DispatcherServlet(), "/");
registration.setAsyncSupported(true);
return registration;
}
它覆盖了DispatcherServletAutoConfiguration中的默认配置,可能值得一提的是Spring Boot默认为DispatcherServlet和所有过滤器启用了异步支持 引自: 我们自动将async supported设置为true 因为DispatcherServlet知道如何处理这些请求和 基本上是由各个控制器方法返回某些内容 就像一个推迟的结果。此外,我们还为 任何过滤器(通过getServletFilters提供)以及设置 要包含异步的每个筛选器的DispatcherType
至少我的实践证明了这一点即使我在晚会上迟到了,我还是要为后代发布我的工作方案 我也面临同样的问题,并尝试了@Artem Bilan提出的解决方案。但是在调试代码之后,我知道
servletRegistrationBean.isAsyncSupported()
默认情况下是true
代码块生成的实际错误来自方法org.springframework.web.context.request.async.StandardServletAsyncWebRequest.startAsync()
,当getRequest().isAsyncSupported()
为false
时,我们会收到此错误。尽管ServletRegistrationBean#asyncSupported
值为true
,HttpServletRequest#isAsyncSupported()
方法值对于所有API请求始终设置为false
代码块的执行
虽然没有明确的答案,但我已经为这个问题实现了一个变通方法。要总结所有需要的更改,如下所示:
request.setAttribute(Globals.ASYNC\u SUPPORTED\u ATTR,true)
这种做法包括在tomcat上部署Spring应用程序而不是独立应用程序吗?@Antoniosss我的答案是在将monolith Spring(不是Spring boot)应用程序迁移到一组独立Spring boot服务的过程中得出的。据我记忆所及,以前的单片非spring引导版本的应用程序必须启用显式支持的异步。事实证明并非如此。spring引导中的行为发生了变化?上述声明是由Spring Boot的作者在2014年发表的……我也这么说了,但这并不是胡编乱造的。我们必须在某个地方通过类似@EnableAsync的东西-记不清了,但这是一个单一注释的问题(乍一看与此无关)。我使用了这个过滤器,它解决了我的问题。注意,我没有将过滤器添加到过滤器链中。Spring正在自动处理这个问题。
Assert.state(getRequest().isAsyncSupported(),
"Async support must be enabled on a servlet and for all filters involved " +
"in async request processing. This is done in Java code using the Servlet API " +
"or by adding \"<async-supported>true</async-supported>\" to servlet and " +
"filter declarations in web.xml.");
specialAttributes.put(Globals.ASYNC_SUPPORTED_ATTR,
new SpecialAttributeAdapter() {
@Override
public Object get(Request request, String name) {
return request.asyncSupported;
}
@Override
public void set(Request request, String name, Object value) {
Boolean oldValue = request.asyncSupported;
request.asyncSupported = (Boolean)value;
request.notifyAttributeAssigned(name, value, oldValue);
}
});
@Component
public class AsyncSupportFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, true);
chain.doFilter(request, response);
}
}
@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AsyncSupportFilter asyncSupportFilter = null;
@Override
public void configure(HttpSecurity httpSecurity) {
httpSecurity.addFilter(asyncSupportFilter);
// we can add the filter before any filter like as httpSecurity.addFilterBefore(asyncSupportFilter , BasicAuthenticationFilter.class);
}
}