0

使用spring MVC,我需要将我的对象存储到会话中,并且我应该使用jstl在几个jsp页面中使用相同的对象。我试过这样:

ModelAndView modelAndView = new ModelAndView("admin/addproduct", "category", categorynameList);

但是我无法访问除addproductpage 之外的其他 jsp 页面的类别。

我怎样才能做到这一点?

4

4 回答 4

2

Spring MVC 提供了不止一种机制来隐藏对HttpSession您的普通使用。

查看@SessionAttributes注释,它允许您定义将由控制器存储在会话中的属性;此机制主要用于维护您的处理程序的会话状态,并且该状态通常在会话完成后被清除。

此外,您可以将 bean 定义为应用程序上下文中的会话范围,然后使用 ScopedProxyFactoryBean(只需<aop:scoped-proxy/>在 bean 定义中添加一个元素),从而能够将该 bean 注入您的单例控制器中。

于 2012-09-17T10:54:34.943 回答
1

您可以将会话直接传递给任何带注释的控制器方法:

@RequestMapping("somePathName")
public String someHandler(HttpSession session) {
  session.setAttribute(...
于 2012-09-17T10:48:37.877 回答
0

注释@SessionAttributes 用于类级别。通常它用于@Controller 类。它的 'value' 元素是 String[] 类型,其值是 @ModelAttribute 在方法级别或处理程序的方法参数级别上使用的匹配名称。

让我们考虑以下安排:

@Controller
@SessionAttributes("visitor")
@RequestMapping("/trades")
public class TradeController {

    @ModelAttribute("visitor")
    public Visitor getVisitor (....) {
        return new Visitor(....);
    }
  ....
}

在上面的代码中,当一个请求进来时,Spring首先会注意到@SessionAttributes('visitor'),然后尝试在javax.servlet.http.HttpSession中找到'visitor'的值。如果它没有找到该值,则将调用具有相同名称“访问者”的 @ModelAttribute 方法(方法 getVisitor())。这种方法的返回值将用于填充名称为“访问者”的会话。

现在 'visitor' 的值已经在 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("visitor") 时,Spring 将从会话中检索 'visitor' 的值,并将该值分配给 Visitor 参数并调用该方法。这一步,Spring并不关心session是如何填充'visitor'的,不管是最后的排列方式还是其他方式填充,都无所谓,Spring只需要注解@SessionAttributes('visitor') ,带有@ModelAttribute("visitor")的handler方法参数和HttpSession中'visitor'的值。如果 spring 在 session 中找不到它并且最后的安排不可用,则会抛出以下异常:

org.springframework.web.HttpSessionRequiredException:预期的会话属性“访客”

换句话说:当在给定会话中第一次调用目标处理程序方法时,将调用带有@ModelAttribute('visitor) 的方法,返回值填充到 HttpSession 中,并调用具有相同值的处理程序方法。对于同一个 HTTPSession 中的后续请求,Spring 从会话中检索相同的对象,直到会话结束才再次调用带有 @ModelAttribute('visitor') 的方法

以下是完整的控制器类:

@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 会话中用户访问的页面。我们使用通配符“/**”,以便所有以“trades”开头的请求都将映射到此控制器。

于 2017-12-24T06:01:16.263 回答
-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

于 2012-09-17T10:39:57.577 回答