使用spring MVC,我需要将我的对象存储到会话中,我应该使用jstl在几个jsp页面中使用相同的对象。我试过这样的:
ModelAndView modelAndView = new ModelAndView("admin/addproduct", "category", categorynameList);
但我无法访问除addproduct
页面之外的其他jsp页面的类别。
我该怎么做?
答案 0 :(得分:1)
您可以将会话直接传递给任何带注释的控制器方法:
@RequestMapping("somePathName")
public String someHandler(HttpSession session) {
session.setAttribute(...
答案 1 :(得分:1)
Spring MVC提供了多种机制来隐藏HttpSession
的明显用法。
查看@SessionAttributes
注释,它允许您定义控制器将存储在会话中的属性;此机制主要用于维护处理程序的会话状态,并且通常在对话完成后清除该状态。
此外,您可以将bean定义为在应用程序上下文中作用域的会话,然后使用ScopedProxyFactoryBean(通过在bean定义中简单地添加<aop:scoped-proxy/>
元素),从而能够在您的bean中注入该bean单身控制器。
答案 2 :(得分:0)
注释 @SessionAttributes用于班级。通常它在@Controller类上使用。它的价值&#39; element的类型为String [],其值是@ModelAttribute在方法级别或处理程序的方法参数级别上使用的匹配名称。
让我们考虑以下安排:
@Controller
@SessionAttributes("visitor")
@RequestMapping("/trades")
public class TradeController {
@ModelAttribute("visitor")
public Visitor getVisitor (....) {
return new Visitor(....);
}
....
}
在上面的代码中,当一个请求进来时,Spring会做的第一件事是注意@SessionAttributes(&#39; visitor&#39;)然后尝试找到&#39; visitor&#39;的值。在javax.servlet.http.HttpSession中。如果它没有找到该值,那么具有@ModelAttribute的方法具有相同的名称&#39; visitor&#39; (方法getVisitor())将被调用。此方法返回的值将用于使用名称&#39; visitor&#39;填充会话。
现在,访客&#39;由于它的价值已经在HttpSession中,让我们考虑以下安排:
@Controller
@SessionAttributes("visitor")
@RequestMapping("/trades")
public class TradeController {
@RequestMapping("/**")
public String handleRequestById (@ModelAttribute("visitor") Visitor visitor,
Model model,
HttpServletRequest request) {
model.addAttribute("msg", "trades request, serving page " +
request.getRequestURI());
visitor.addPageVisited(request.getRequestURI());
return "traders-page";
}
.......
}
在目标处理程序方法中找到@ModelAttribute(&#34; visitor&#34;)后,Spring将检索&#39; visitor&#39;从会话中将值分配给Visitor参数,并将调用该方法。在这一步,Spring并不关心如何使用访问者来填充会话,无论是使用最后一种安排还是其他方式填充,它都不重要,Spring只需要注释@SessionAttributes(&#39; visitor&#39;),带有@ModelAttribute(&#34; visitor&#34;)的处理程序方法参数以及&#39; visitor&#39;的值。在HttpSession中。如果spring无法在会话中找到并且最后一个安排不可用,那么将抛出以下异常:
org.springframework.web.HttpSessionRequiredException:预期的会话属性&#39;访客&#39;
换句话说:当在给定会话中第一次调用目标处理程序方法时,调用带有@ModelAttribute(&#39; visitor)的方法,返回的值填充在HttpSession中,并且处理程序方法具有相同的处理方法调用值。对于同一HTTPSession中的后续请求,Spring从会话中检索相同的对象,并且不再使用@ModelAttribute(&#39; visitor&#39;)再次调用该方法,直到会话结束
以下是完整的控制器类:
@Controller
@SessionAttributes("visitor")
@RequestMapping("/trades")
public class TradeController {
@RequestMapping("/**")
public String handleRequestById (@ModelAttribute("visitor") Visitor visitor,
Model model,
HttpServletRequest request) {
model.addAttribute("msg", "trades request, serving page " +
request.getRequestURI());
visitor.addPageVisited(request.getRequestURI());
return "traders-page";
}
@ModelAttribute("visitor")
public Visitor getVisitor (HttpServletRequest request) {
return new Visitor(request.getRemoteAddr());
}
}
在上面的示例中,我们正在跟踪同一HTTP会话中的用户访问页面。我们正在使用通配符&#39; / **&#39;以便所有请求以&#39;交易开始将映射到此控制器。
答案 3 :(得分:-2)
将会话注入控制器类,将对象存储在那里并在需要时使用它,例如:
@Controller
public class SomeController {
//@Autowired
//private HttpSession session; This is not desired. See the discussion in the
//comments.
@RequestMapping("somePathName")
public String someHandler(HttpSession session) { //Session will be injected by
//Spring without any additional annotations.
//...
session.setAttribute("category", yourObject);
}
}
如果您需要在category
以外的其他网页上访问admin/addproduct
,则需要将其添加到相应的模型中,如下所示:
@RequestMapping("somePathName")
public String someHandler(Model model) {
//...
model.addAttribute("category", yourObject);
//...
return "yourPageName";
}
更新:根据ALex的评论,由于线程安全问题,我不希望将HttpSession
实例注入strongly
字段{{1}}。我已经分别更改了源代码。