春季明确会议范围豆

时间:2019-09-13 12:25:05

标签: java spring spring-mvc

我创建了一个会话范围如下的bean:

@Bean
@Scope(
    value = WebApplicationContext.SCOPE_SESSION,
    proxyMode = ScopedProxyMode.TARGET_CLASS)
public TodoList todos() {
    return new TodoList();
}

我已将bean添加为模型属性,并且可以在多个页面上显示bean。

@GetMapping("/todos.html")
public String list(Model model) {
    model.addAttribute("todos", todos);
    return "scopedproxytodos";
}

但是我不确定如何清除会话中的属性。

@PostMapping("/end")
public ModelAndView endSession(SessionStatus sessionStatus, Model model) {
    model.addAttribute("todos", new TodoList());
    sessionStatus.setComplete();
    return new ModelAndView("redirect:/");
}

1 个答案:

答案 0 :(得分:1)

  

我已经将bean添加为模型属性,并且可以显示   跨多个页面的Bean:

     

...

`model.addAttribute("todos", todos);`
     

...

不是。那只会在当前视图中添加属性。

要实现这一点,您应该使用TodoList来注释@SessionScope类,例如:

@SessionScope
@Component
public class TodoList {
    // ...
}

然后用todos注释需要对@SessionAttributes进行对话的作用域的控制器,并用@ModelAttribute注入它。未经测试,但类似的东西:

@Controller
@SessionAttributes("todos")
public class FooController { 

  @GetMapping("/todos.html")
  public String list(@ModelAttribute TodoList todos) {
    // set the todos value
    return "scopedproxytodos";
  }

}

您可以在带有@SessionAttributes("todos")的其他任何控制器中使用它。

要删除当前会话的todos,请像以前一样使用status.setComplete()
就您而言,您可以将其删除:

@PostMapping("/end")
public ModelAndView endSession(SessionStatus sessionStatus, Model model) {
    sessionStatus.setComplete();
    return new ModelAndView("redirect:/");
}

然后让具有会话作用域的控制器根据需要重新初始化它(FooController实际上就是这样)。
另一种方法是重新初始化而不是删除它。
例如:

@PostMapping("/end")
public ModelAndView endSession(@ModelAttribute TodoList todos) {
    todos.clear();
    return new ModelAndView("redirect:/");
}

此解决方案的优势:

  • 更整洁/不太冗长
  • 不需要为每个会话创建bean。就开销而言,Bean比会话中存储的值更昂贵。

More information here about that way of manipulate conversational attributes.


SessionStatus类管理spring会话的属性:

  

可以插入处理程序方法的简单接口,允许   他们以信号表明其会话处理已完成。处理程序   然后,调用者可以跟进适当的清理,例如会话   在此处理程序的过程中隐式创建的属性   处理

这意味着它将清除存储在Spring处理程序会话中的属性(与经典的HTTP会话不同),而不是清除存储在http请求中的属性,并且实际上您没有在spring会话属性中添加任何内容。 br /> 这样就没用了。