Spring mvc 如何在SpringMVC中使用会话属性

Spring mvc 如何在SpringMVC中使用会话属性,spring-mvc,session,servlets,Spring Mvc,Session,Servlets,你能帮我写这个代码的SpringMVC风格的模拟吗 session.setAttribute("name","value"); 以及如何将由@modeldattribute注释注释的元素添加到会话中,然后访问它?下面注释的代码将“value”设置为“name” 要在JSP中访问相同的内容,请使用 ${sessionScope.name} 对于@modeldattribute,如果您想在每次响应后删除对象,而不需要会话,请参见此 如果要在用户会话期间保留对象, 有一些方法: 直接向会话添加一个

你能帮我写这个代码的SpringMVC风格的模拟吗

 session.setAttribute("name","value");

以及如何将由
@modeldattribute
注释注释的元素添加到会话中,然后访问它?

下面注释的代码将“value”设置为“name”

要在JSP中访问相同的内容,请使用
${sessionScope.name}


对于
@modeldattribute
,如果您想在每次响应后删除对象,而不需要会话,请参见此

如果要在用户会话期间保留对象, 有一些方法:

  • 直接向会话添加一个属性:

    @RequestMapping(method = RequestMethod.GET)
    public String testMestod(HttpServletRequest request){
       ShoppingCart cart = (ShoppingCart)request.getSession().setAttribute("cart",value);
       return "testJsp";
    }
    
    您可以像这样从控制器获取它:

    ShoppingCart cart = (ShoppingCart)session.getAttribute("cart");
    
  • 使控制器会话的作用域为

    @Controller
    @Scope("session")
    
  • 作用域对象,例如,您有一个用户对象,每次都应该在会话中:

    @Component
    @Scope("session")
    public class User
     {
        String user;
        /*  setter getter*/
      }
    
    然后在您想要的每个控制器中注入类

       @Autowired
       private User user
    
    @Autowired
    private User user
    
    这样可以保证上课的时间

  • @Controller
    @SessionAttributes("personObj")
    public class PersonController {
    
        @RequestMapping(value="/person-form")
        public ModelAndView personPage() {
            return new ModelAndView("person-page", "person-entity", new Person());
        }
    
        @RequestMapping(value="/process-person")
        public ModelAndView processPerson(@ModelAttribute Person person) {
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("person-result-page");
    
            modelAndView.addObject("pers", person);
            modelAndView.addObject("personObj", person);
    
            return modelAndView;
        }
    
    }
    
  • AOP代理注入: 在spring-xml中:

    <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
    
      <bean id="user"    class="com.User" scope="session">     
          <aop:scoped-proxy/>
      </bean>
    </beans>
    
  • 5.将HttpSession传递给方法:

     String index(HttpSession session) {
                session.setAttribute("mySessionAttribute", "someValue");
                return "index";
            }
    
    6.通过@SessionAttributes(“ShoppingCart”)在会话中生成ModelAttribute:

    或者您可以将模型添加到整个控制器类,如

    @Controller
        @SessionAttributes("ShoppingCart")
        @RequestMapping("/req")
        public class MYController {
    
            @ModelAttribute("ShoppingCart")
            public Visitor getShopCart (....) {
                return new ShoppingCart(....); //get From DB Or Session
            }  
          }
    
    每一种都有优点和缺点:

    @会话可能会在云系统中使用更多内存,它会将会话复制到所有节点,而直接方法(1和5)的方法比较混乱,不利于单元测试

    访问会话jsp的步骤

    <%=session.getAttribute("ShoppingCart.prop")%>
    
    
    
    在Jstl中:

    <c:out value="${sessionScope.ShoppingCart.prop}"/>
    
    
    
    在Thymeleaf中:

    <p th:text="${session.ShoppingCart.prop}" th:unless="${session == null}"> . </p>
    


    使用
    @SessionAttributes

    见文件:

    “”还很好地概述了Spring MVC会话,并解释了如何/何时将
    @ModelAttribute
    s传输到会话中(如果控制器是
    @SessionAttributes
    注释的)


    这篇文章还解释说,最好在模型上使用
    @SessionAttributes
    ,而不是直接在HttpSession上设置属性,因为这有助于Spring MVC的视图不可知性。

    注释是最简单和直接的注释,而不是从请求和对象获取会话设置属性。 任何对象都可以添加到控制器中的模型中,如果其名称与
    @SessionAttributes
    注释中的参数匹配,则该对象将存储在会话中。
    在下面的示例中,
    personObj
    将在会话中可用

    @Controller
    @SessionAttributes("personObj")
    public class PersonController {
    
        @RequestMapping(value="/person-form")
        public ModelAndView personPage() {
            return new ModelAndView("person-page", "person-entity", new Person());
        }
    
        @RequestMapping(value="/process-person")
        public ModelAndView processPerson(@ModelAttribute Person person) {
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("person-result-page");
    
            modelAndView.addObject("pers", person);
            modelAndView.addObject("personObj", person);
    
            return modelAndView;
        }
    
    }
    
    当我尝试登录时(这是一个引导模式),我使用了@sessionattributes注释。但问题是当视图是重定向(“重定向:/home”)时,我在会话中输入的值会显示在url中。一些互联网消息来源建议遵循,但我使用了HttpSession。此会话将一直存在,直到您关闭浏览器。 下面是示例代码

            @RequestMapping(value = "/login")
            @ResponseBody
            public BooleanResponse login(HttpSession session,HttpServletRequest request){
                //HttpServletRequest used to take data to the controller
                String username = request.getParameter("username");
                String password = request.getParameter("password");
    
               //Here you set your values to the session
               session.setAttribute("username", username);
               session.setAttribute("email", email);
    
              //your code goes here
    }
    
    在视图方面,您不会更改特定的内容

    <c:out value="${username}"></c:out>
    <c:out value="${email}"></c:out>
    
    
    

    登录后,将上述代码添加到网站中的任何位置。如果会话设置正确,您将在那里看到值。确保正确添加了jstl标记和El表达式(这里是设置jstl标记的链接)

    这样不是最简单、最短的方法吗?我知道这一点,并对其进行了测试-在这里工作得非常完美:

    @GetMapping
    public String hello(HttpSession session) {
        session.setAttribute("name","value");
        return "hello";
    }
    
    p、 美国。 我来这里是为了寻找“如何在Spring mvc中使用会话属性”的答案,但是读了很多书,却没有看到我在代码中写的最明显的内容。我没有看到它,所以我认为它是错的,但不,它不是。因此,让我们用最简单的方法来解决主要问题,来分享这些知识。

    试试这个

    @Controller
    @RequestMapping("/owners/{ownerId}/pets/{petId}/edit")
    @SessionAttributes("pet")
    public class EditPetForm {
    
        @ModelAttribute("types")
    
        public Collection<PetType> populatePetTypes() {
            return this.clinic.getPetTypes();
        }
    
        @RequestMapping(method = RequestMethod.POST)
        public String processSubmit(@ModelAttribute("pet") Pet pet, 
                BindingResult result, SessionStatus status) {
            new PetValidator().validate(pet, result);
            if (result.hasErrors()) {
                return "petForm";
            }else {
                this.clinic.storePet(pet);
                status.setComplete();
                return "redirect:owner.do?ownerId="
                    + pet.getOwner().getId();
            }
        }
    }
    
    @控制器
    @请求映射(“/owners/{ownerId}/pets/{petId}/edit”)
    @会期贡献(“pet”)
    公共类编辑表单{
    @ModelAttribute(“类型”)
    公共集合populatePetTypes(){
    返回此.clinic.getPetTypes();
    }
    @RequestMapping(method=RequestMethod.POST)
    公共字符串processSubmit(@modeldattribute(“pet”)pet,
    BindingResult结果,SessionStatus状态){
    新的PetValidator().validate(pet,结果);
    if(result.hasErrors()){
    返回“petForm”;
    }否则{
    这个.clinic.storePet(pet);
    status.setComplete();
    return“重定向:owner.do?ownerId=”
    +pet.getOwner().getId();
    }
    }
    }
    
    使用此方法非常简单易用

    HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getNativeRequest();
    
                                                                request.getSession().setAttribute("errorMsg", "your massage");
    
    在jsp中使用一次,然后删除

    <c:remove var="errorMsg" scope="session"/>      
    

    在Spring4WebMVC中。您可以在方法中使用
    @SessionAttributes
    ,在控制器级别使用
    @SessionAttributes

    @Controller
    @SessionAttributes("SessionKey")
    public class OrderController extends BaseController {
    
        GetMapping("/showOrder")
        public String showPage(@SessionAttribute("SessionKey") SearchCriteria searchCriteria) {
         // method body
    }
    

    会话仅适用于同一控制器实例中的请求。如果需要将控制发送到另一个控制器,该怎么办?此会话将被销毁,并在必要时创建一个新会话。@larrytech怎么可能?我认为您刚刚忘记将SessionAttributes添加到第二个控制器如何利用SessionAttributes在控制器之间传输对象?3。如果控制器是单例的,则需要为具有会话作用域的注入组件定义proxyMode=ScopedProxyMode.TARGET_类@Scope(value=“session”,proxyMode=ScopedProxyMode.TARGET\u CLASS)将控制器会话设置为作用域是这里最糟糕的选项,尽管它一开始看起来简单易用。但是,如果您想在将来某个时候扩展应用程序,您将遇到麻烦,因为您可能需要一个分布式会话存储,如Redis(除非您使用粘性会话,为方便起见牺牲可用性)。因此,会话范围的bean通常应该是哑的可序列化POJO。通过这种方式,您可以在需要时进行扩展。RequestContextHolder呢?注入
    用户
    bean只有在类中调用该bean时才会起作用,该类也是
    会话
    作用域,否则,如果不存在会话,则会抛出异常,因为在我们注入时,context@runtime中不会有任何活动会话
    @Controller
    @SessionAttributes("SessionKey")
    public class OrderController extends BaseController {
    
        GetMapping("/showOrder")
        public String showPage(@SessionAttribute("SessionKey") SearchCriteria searchCriteria) {
         // method body
    }