我遇到Spring Boot配置问题。我在一些应该使用套接字的移动设备上遇到例外:
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)
...
从异常中可以看出,我必须通过在web.xml文件中添加true来启用异步处理。但这是问题,因为我没有它 - 我们的项目使用Spring Boot。
有没有办法在Spring Boot中提供相同的功能呢?
答案 0 :(得分:16)
您只需要定义dispatcherServlet
@Bean
:
@Bean
public ServletRegistrationBean dispatcherServlet() {
ServletRegistrationBean registration = new ServletRegistrationBean(
new DispatcherServlet(), "/");
registration.setAsyncSupported(true);
return registration;
}
它会覆盖DispatcherServletAutoConfiguration
中的默认值。
答案 1 :(得分:1)
也许值得一提的是,Spring Boot默认为调度程序servlet和所有过滤器启用了异步支持
来自github的报价:
我们自动将async-supported设置为true 因为DispatcherServlet知道如何处理这些请求和 它基本上取决于单个控制器方法来返回一些东西 像DeferredResult一样。此外,我们还设置了异步支持 任何过滤器(通过getServletFilters提供)以及设置 每个过滤器的DispatcherType包含ASYNC。
至少我的做法支持这个陈述
答案 2 :(得分:1)
即使我参加聚会迟到,我仍在为后代发布工作解决方案。
我也遇到过同样的问题,并尝试了@Artem Bilan建议的解决方案。但是在调试代码后,我知道servletRegistrationBean.isAsyncSupported()
默认为true
。
由代码块生成的实际错误是来自方法org.springframework.web.context.request.async.StandardServletAsyncWebRequest.startAsync()
的,当getRequest().isAsyncSupported()
为false
时,我们会收到此错误。尽管ServletRegistrationBean#asyncSupported
的值为true
,但所有API请求的HttpServletRequest#isAsyncSupported()
方法值始终设置为false
。
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.");
进一步分析时,我知道requestAttributes-> Globals.ASYNC_SUPPORTED_ATTR决定是否必须以异步方式处理请求。
在正常情况下,请求没有Globals.ASYNC_SUPPORTED_ATTR
requestAttribute,因此如果我们使用某些内容为所有请求手动将requestAttribute request.asyncSupported
值添加为true,则ASYNC_SUPPORTED_ATTR
将为false像过滤器一样,然后根据下面的代码块Code Reference
request#asyncSupported
的值设置为true
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);
}
});
尽管没有明确的答案,但我已经针对此问题实施了变通方法。要汇总所有必需的更改,请在下面列出:
request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, true)
@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);
}
}