@SessionAttributes与@ResponseBody同时使用的问题

遇到的错误如下:
java.lang.IllegalStateException: Cannot create a session after the response has been committed
解决这个错误之后,由于之前一直研究SessionAttributes,所以就决定一起写下来。


@SessionAttributes

为什么用到SessionAttributes,网上很多在springmvc中使用session都是在方法后面加一个参数HttpSession session来使用session,但是既然使用了框架,那就没必要再去使用原生的api,这会违背了框架的初衷,框架中肯定会帮你封装好,
而使用sessionAttributes的好处一是便于解耦合,二是便于单元测试。
至于怎么使用SessionAttributes,这里不详细描述可参考下面链接
http://blog.csdn.net/xwnxwn/article/details/46794331

# @SessionAttributes与@ResponseBody

先上测试代码


@Controller
@RequestMapping("/")
@SessionAttributes(value = {"user"})
public class UserController {


    @RequestMapping("/text1")
    public String text1(ModelMap map) {
        map.addAttribute("user", "存入session");
        return "存入完毕";
    }
    @RequestMapping("/text2")
    public String text2(ModelMap map ) {
        System.out.println(map.get("user"));
        return "取出完毕";
    }
}

这样用是没有问题的,但是现在为了前后端分离,一般都是返回一个json字符串到前端,所以,我们在类上加上一个注解@ResponseBody,其余不变。
现在用浏览器在url地址上输入 http://localhost:8080/text1 ,或者使用Postman来发送请求,注意不要用jsp页面发送表单,至于为什么后面会说,此时去看控制台。

java.lang.IllegalStateException: Cannot create a session after the response has been committed

最上面的错误应该是这一句

错误原因:我们把值存到map里面去后,当请求结束时springmvc会根据SessionAttributes注解标注的属性,对map中对应的值存到session中然后每次请求前也会根据SessionAttributes将session中对应属性值存到map中,而如果我们是用了ResponseBody注解,方法return之后是把json字符串响应到页面的,没有进行转发或者重定向,会导致springmvc无法创建session来存储map里面的属性值,导致错误出现。

解决方法:在return之前自己创建session,这样就不会报错了,
public String text1(ModelMap map, HttpSession session)
比如这样在进行测试,就可以完美解决了。

但是这样做似乎还是在我们的代码中使用了原生的api,问题不就回到了原点了么。当然是有其他办法解决的,这个解决办法也是我无意发现的。现在将HttpSession session 从方法中去掉,回到加上ResponseBody注解测试报错的版本。

此时我们写一个jsp表单

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html>
  <head>
    <title>My JSP 'text.jsp' starting page</title>
  </head>
  <body>
  <form action="text1" method="post">
      <input type="submit" value="提交">
  </form>
  </body>
</html>

进入该页面,点击提交访问text1,你会发现后台没有报错,再通过url访问text2这里写图片描述

后台的信息告诉我们,我们什么都没做,ResponseBody和SessionAttributes一起使用时的错误没有了。
好,接下来我们将jsp页面改一下

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" session="false" %>
<%

加上session=”false” 作用是jsp编译成servlet时不产生session,重启服务器,进入我们的jsp页面,点击提交,看一下控制台,还是那个熟悉的错误。

OK,告一段落,这个问题的解决办法我还没有实施,我觉得既然通过jsp编译成servlet时产生的session就可以避免这个错误,我们也可以在第一次接受请求之前自己写个拦截器或者其他之类的产生一个session,问题不就解决了么,这个问题以后解决了会继续更新。。

第一次写博客,有什么问题勿喷。。。。

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值