如何在 Spring-mvc 中使用 Session 属性
Posted
技术标签:
【中文标题】如何在 Spring-mvc 中使用 Session 属性【英文标题】:How to use Session attributes in Spring-mvc 【发布时间】:2013-09-18 10:56:37 【问题描述】:你能帮我写这段代码的spring mvc风格的模拟吗?
session.setAttribute("name","value");
以及如何将一个被@ModelAttribute
注解的元素添加到会话中,然后访问它?
【问题讨论】:
【参考方案1】:如果您想在不需要会话的每个响应后删除对象,
如果您想在用户会话期间保留对象, 有几种方法:
直接给session增加一个属性:
@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
让课堂保持在会话中。
AOP 代理注入: 在春天-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>
然后在你想要的每个控制器中注入类
@Autowired
private User user
5.将HttpSession传递给方法:
String index(HttpSession session)
session.setAttribute("mySessionAttribute", "someValue");
return "index";
6.在会话中通过@SessionAttributes("ShoppingCart")制作ModelAttribute:
public String index (@ModelAttribute("ShoppingCart") ShoppingCart shoppingCart, SessionStatus sessionStatus)
//Spring V4
//you can modify session status by sessionStatus.setComplete();
或者您可以将模型添加到整个控制器类,例如,
@Controller
@SessionAttributes("ShoppingCart")
@RequestMapping("/req")
public class MYController
@ModelAttribute("ShoppingCart")
public Visitor getShopCart (....)
return new ShoppingCart(....); //get From DB Or Session
各有优劣:
@session 可能会在云系统中使用更多的内存,它将会话复制到所有节点,直接方法(1 和 5)有混乱的方法,不适合单元测试。
访问会话jsp
<%=session.getAttribute("ShoppingCart.prop")%>
在 Jstl 中:
<c:out value="$sessionScope.ShoppingCart.prop"/>
在百里香中:
<p th:text="$session.ShoppingCart.prop" th:unless="$session == null"> . </p>
【讨论】:
3.如果您的控制器是单例的,那么您需要为具有会话范围的注入组件定义 proxyMode = ScopedProxyMode.TARGET_CLASS。 @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) 使控制器会话作用域是这里最糟糕的选择,尽管它起初看起来简单易用。但是,如果您想在未来某个时间扩展您的应用程序,您将遇到麻烦,因为您可能需要像 Redis 这样的分布式会话存储(除非您使用粘性会话,为了方便而牺牲可用性)。因此,会话范围的 bean 通常应该是哑可序列化 POJO。这样,您就可以在需要时进行横向扩展。 RequestContextHolder 呢? 注入User
bean 仅当您在同样为session
作用域的类中调用bean 时才有效,否则如果不存在会话,则会抛出异常,因为不会有任何活动当我们将user
bean 注入另一个类时,上下文@runtime 中的会话!!【参考方案2】:
试试这个...
@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();
【讨论】:
【参考方案3】:在 Spring 4 Web MVC 中。您可以在控制器级别使用@SessionAttributes
的方法中使用@SessionAttribute
@Controller
@SessionAttributes("SessionKey")
public class OrderController extends BaseController
GetMapping("/showOrder")
public String showPage(@SessionAttribute("SessionKey") SearchCriteria searchCriteria)
// method body
【讨论】:
【参考方案4】:使用这个方法很简单好用
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getNativeRequest();
request.getSession().setAttribute("errorMsg", "your massage");
在 jsp 中使用一次然后删除
<c:remove var="errorMsg" scope="session"/>
【讨论】:
【参考方案5】:这不是最简单和最短吗?我知道并且刚刚对其进行了测试 - 在这里完美运行:
@GetMapping
public String hello(HttpSession session)
session.setAttribute("name","value");
return "hello";
附言 我来这里是为了寻找“如何在 Spring-mvc 中使用 Session 属性”的答案,但是读了这么多,却没有看到我在代码中写的最明显的内容。我没有看到它,所以我认为它是错误的,但不,它不是。因此,让我们通过主要问题的最简单解决方案来分享这些知识。
【讨论】:
你是对的!这就是我的想法,因为当您在控制器方法(GET/POST 请求)中声明它们时,您可以直接访问我们需要的所有 Http 对象【参考方案6】:当我尝试登录时(这是一个引导模式),我使用了 @sessionattributes 注释。但问题是当视图是重定向(“redirect:/home”)时,我输入到会话中的值会显示在 url 中。一些互联网资源建议关注http://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/htmlsingle/#mvc-redirecting 但我使用了 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 标签的链接https://menukablog.wordpress.com/2016/05/10/add-jstl-tab-library-to-you-project-correctly/)
【讨论】:
【参考方案7】:SessionAttribute
注释是最简单直接的,而不是从请求对象和设置属性中获取会话。
任何对象都可以添加到控制器中的模型中,如果其名称与@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;
【讨论】:
会话仅适用于同一控制器实例中的请求。如果需要将控制权发送给另一个控制器怎么办,这个会话将被销毁并在必要时创建一个新的会话。 @larrytech 怎么可能?我认为您刚刚忘记将 SessionAttributes 添加到您的第二个控制器【参考方案8】:使用@SessionAttributes
查看文档:Using @SessionAttributes to store model attributes in the HTTP session between requests
“Understanding Spring MVC Model And Session Attributes”还很好地概述了 Spring MVC 会话,并解释了 @ModelAttribute
s 是如何/何时转移到会话中的(如果控制器是 @SessionAttributes
注释的)。
那篇文章还解释说,最好在模型上使用@SessionAttributes
,而不是直接在 HttpSession 上设置属性,因为这有助于 Spring MVC 与视图无关。
【讨论】:
如何利用 sessionAttributes 在 Controller 之间传输对象?【参考方案9】:以下带注释的代码会将“值”设置为“名称”
@RequestMapping("/testing")
@Controller
public class TestController
@RequestMapping(method = RequestMethod.GET)
public String testMestod(HttpServletRequest request)
request.getSession().setAttribute("name", "value");
return "testJsp";
要在 JSP 中访问相同的内容,请使用
$sessionScope.name
.
对于@ModelAttribute
,请参阅此link
【讨论】:
以上是关于如何在 Spring-mvc 中使用 Session 属性的主要内容,如果未能解决你的问题,请参考以下文章
如何在 spring-mvc 中将日志记录添加到 webflux 端点?
如何在没有 if else 的情况下处理 Spring-MVC 项目中的错误?