@SessionAttributes和@ResponseBody不能一起工作



我创建了一个非常简单的"测试"控制器,它在会话中保持一个计数器,以打印调用请求处理程序的次数。

@Controller
@SessionAttributes("counter")
public class MyController {
    @ModelAttribute("counter")
    public Counter addCounter(){
        System.out.println("Counter added to model");
        return new Counter();
    }

    @RequestMapping("printCounter")
    @ResponseBody
    public String printCounter(Model model){
        Counter counter = (Counter)model.asMap().get("counter");
        int currVal = counter.getValue();
        System.out.println("Current value: " + currVal);
        counter.increment();

        return "hello-view";
    }
}

每件事都很好,但当我尝试在响应上使用@ResponseBody时,它失败了,并出现以下错误:

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

我找到了几件工作。我知道发生错误是因为spring在尝试将计数器添加到会话时已经刷新了响应。我不知道的是春天为什么会这样

既然这个问题已经存在了这么长时间,我想它是根据提议完成的。

有人知道以这种方式实施它的动机是什么吗?

如果方法返回正文内容,为什么我们可以在会话中存储数据,而如果它返回视图名称,我们可以存储数据?

提前谢谢。

@SessionAttribute不是SpringFramework中设计最好的概念(请参阅另一篇文章了解另一个警告)。

当您转发到一个视图时,Spring在调用视图之前有所有的时间来处理会话属性:在控制器方法返回时,没有向请求写入任何内容。但是,当您使用@ResponseBody时,方法的返回值会直接写入响应,并立即提交响应。因此,Spring创建一个会话来保存模型属性可能为时已晚。好吧,它本来可以被设计成一种没有必要的方式。但是因为您总是可以要求通过向控制器方法提供HttpSession参数来急切地创建会话,我想Spring fellows认为这已经足够了。

最新更新