我试图设置并获取会话属性,但要么我误解了它是如何工作的,要么我做错了什么.
请有人解释为什么这不起作用.
我有以下简单的Spring Web MVC控制器
@Controller
@SessionAttributes("sessid")
@RequestMapping("sesstest")
public class SessTest
{
@RequestMapping("in")
@ResponseBody
public String in(ModelMap model){
String uuid = UUID.randomUUID().toString();
model.addAttribute("sessid", uuid);
return uuid;
}
@RequestMapping("out")
@ResponseBody
public String out(@ModelAttribute("sessid") String sesid){
return sesid;
}
}
这个类应该在调用/ sesstest / in时设置一个会话变量,然后在调用/ sesstest / out时调用它
但是在调用/ in时会出现以下异常
(堆栈跟踪显示在控制台上,Web输出正常)
java.lang.IllegalStateException: Cannot create a session after the response has been committed
at org.apache.catalina.connector.Request.doGetSession(Request.java:2872)
at org.apache.catalina.connector.Request.getSession(Request.java:2249)
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:895)
at org.springframework.web.context.request.ServletRequestAttributes.getSession(ServletRequestAttributes.java:111)
at org.springframework.web.context.request.ServletRequestAttributes.setAttribute(ServletRequestAttributes.java:161)
at org.springframework.web.bind.support.DefaultSessionAttributeStore.storeAttribute(DefaultSessionAttributeStore.java:55)
at org.springframework.web.method.annotation.SessionAttributesHandler.storeAttributes(SessionAttributesHandler.java:124)
at org.springframework.web.method.annotation.ModelFactory.updateModel(ModelFactory.java:232)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.getModelAndView(RequestMappingHandlerAdapter.java:879)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:782)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
谢谢!
解决方法:
正式这“按设计工作”.
在这种情况下,各种解决方法是:
>手动启动会话
>使用过滤器确保会话
当下
>使用模型中的视图渲染.
The scenario is somewhat unusual since typically model attributes are used for rendering with views (e.g. HTML template). For @ResponseBody only the return value is used to render the response. That said the use of @ResponseBody doesn’t preclude the use of @SessionAttributes. The error has to do with trying to create the session for the first time too late. Normally the use of something like Spring Security with a Filter to store authentication in the session ensures there is always an HTTP session. In the absence of that you could add your own Filter or HandlerInterceptor that simply calls request.getSession(true). That’s enough to ensure a session is present.
无法与之争辩.
标签:java,spring-mvc,spring,session
来源: https://codeday.me/bug/20190623/1274915.html