spring MVC session会话中的对象的存放,取出,删除

本文介绍了一个简单的购物车预添加功能实现方法,通过处理HTTP请求来完成商品预添加到购物车的过程,并利用AJAX返回购物车状态。代码展示了如何从请求中获取参数、创建购物车实例并保存到Session中。

 public void preAddToCart(HttpServletRequest request,HttpServletResponse response)throws ServletRequestBindingException, XmlAnnotationException,IOException {
  List<String> domains = Arrays.asList(ServletRequestUtils.getRequiredStringParameters(request, "domains"));
  HttpSession session = request.getSession();

  Cart cart = new Cart();
  request.getSession().setAttribute(Cart.PRE_REGISTER_SESSION_KEY, cart);

//以下为执行的ajax

  response.setContentType("text/xml");
  response.setCharacterEncoding("utf-8");
  XMLUtils.writeObject(cart, response.getWriter());
 }

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

public ModelAndView addToCart(HttpServletRequest request, HttpServletResponse response) throws Exception {
  HttpSession session = request.getSession();

 //根据key获得Session中的的对象,没有时该key时创建一个并初始化对象
 Cart cart = (Cart) WebUtils.getOrCreateSessionAttribute(session, Cart.PRE_REGISTER_SESSION_KEY, Cart.class);
  List<String> domains = Arrays.asList(ServletRequestUtils.getRequiredStringParameters(request, "domains"));

//去掉Key为:Cart.PRE_REGISTER_SESSION_KEY的session中的对象
//  session.removeAttribute(Cart.PRE_REGISTER_SESSION_KEY);
  return new ModelAndView(new RedirectView("cart.do"));
  }

<think>我们使用Spring Test框架中的MockMvc来测试Controller时,模拟用户会Session)主要有两种方式: 1. 在测试方法中通过`request`对象设置Session属性 2. 使用`@SessionAttributes`注解配合测试设置 下面分别给出具体实现代码和解释。</think>### 在 Spring MVC 测试中模拟用户会Session)的完整指南 #### 核心实现代码 ```java import org.junit.Test; import org.springframework.mock.web.MockHttpSession; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; // 方法1:使用 MockHttpSession 对象 @Test public void testSessionWithObject() throws Exception { // 创建并填充会对象 MockHttpSession session = new MockHttpSession(); session.setAttribute("user", new User("john", "ROLE_ADMIN")); // 存储用户对象 mockMvc.perform(get("/dashboard") .session(session)) // 注入会 .andExpect(status().isOk()) .andExpect(view().name("dashboard")) .andExpect(model().attribute("welcomeMsg", "Hello, john!")); } // 方法2:直接在请求中设置会属性 @Test public void testSessionWithAttribute() throws Exception { mockMvc.perform(get("/profile") .sessionAttr("theme", "dark") // 设置会属性 .sessionAttr("locale", "en_US")) .andExpect(status().isOk()) .andExpect(jsonPath("$.theme").value("dark")); } // 方法3:测试会属性验证 @Test public void testSessionValidation() throws Exception { // 未登录场景 mockMvc.perform(get("/account")) .andExpect(status().is3xxRedirection()) .andExpect(redirectedUrl("/login")); // 已登录场景 MockHttpSession authSession = new MockHttpSession(); authSession.setAttribute("authToken", "xyz123"); mockMvc.perform(get("/account") .session(authSession)) .andExpect(status().isOk()) .andExpect(content().string("Account Details")); } // 方法4:测试会失效 @Test public void testSessionInvalidation() throws Exception { MockHttpSession session = new MockHttpSession(); session.setAttribute("user", "testUser"); mockMvc.perform(post("/logout") .session(session)) .andExpect(status().isOk()) .andExpect(request().sessionAttributeDoesNotExist("user")); // 验证会属性被移除 } ``` #### 关键方法解析 1. **`MockHttpSession` 对象** - **作用**:完整模拟 Servlet 会 - **适用场景**:需要复杂会状态时(如存储对象) - **核心方法**: ```java session.setAttribute("key", value); // 设置属性 session.getAttribute("key"); // 获取属性 session.invalidate(); // 使会失效 ``` 2. **`.sessionAttr()` 方法** - **作用**:快速设置单个会属性 - **适用场景**:简单键值对会数据 - **链式调用**: ```java .sessionAttr("key1", value1) .sessionAttr("key2", value2) ``` 3. **会验证方法** - `request().sessionAttribute("key", value)`:验证会属性存在且匹配 - `request().sessionAttributeDoesNotExist("key")`:验证属性不存在 - `request().sessionAttributeExists("key")`:仅验证属性存在 #### 常见场景解决方案 **场景1:测试需要登录的Controller** ```java @Test public void testAuthenticatedAccess() throws Exception { // 创建认证会 MockHttpSession authSession = new MockHttpSession(); authSession.setAttribute("authToken", "secureToken123"); // 测试受限访问 mockMvc.perform(get("/admin") .session(authSession)) .andExpect(status().isOk()) .andExpect(content().string("Admin Dashboard")); } ``` **场景2:测试会超时处理** ```java @Test public void testSessionTimeout() throws Exception { // 创建过期的会 MockHttpSession expiredSession = new MockHttpSession(); expiredSession.setMaxInactiveInterval(1); // 1秒超时 Thread.sleep(1500); // 等待超时 mockMvc.perform(get("/checkout") .session(expiredSession)) .andExpect(status().isUnauthorized()) .andExpect(content().string("Session expired")); } ``` **场景3:测试多步骤会流程(购物车示例)** ```java @Test public void testShoppingCartFlow() throws Exception { MockHttpSession session = new MockHttpSession(); // 步骤1:添加商品 mockMvc.perform(post("/cart/add") .param("item", "P123") .param("qty", "2") .session(session)) .andExpect(request().sessionAttribute("cart", hasItem("P123"))); // 步骤2:检查购物车 mockMvc.perform(get("/cart") .session(session)) .andExpect(jsonPath("$.items[0].code").value("P123")) .andExpect(jsonPath("$.items[0].quantity").value(2)); // 步骤3:结账 mockMvc.perform(post("/checkout") .session(session)) .andExpect(status().isOk()) .andExpect(request().sessionAttributeDoesNotExist("cart")); // 清空购物车 } ``` #### 最佳实践建议 1. **会复用**:在测试类初始化时创建基础会 ```java private MockHttpSession userSession; @Before public void setupSession() { userSession = new MockHttpSession(); userSession.setAttribute("userRole", "MEMBER"); } ``` 2. **会隔离**:使用`@DirtiesContext`避免测试间污染 ```java @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) public class SessionControllerTest { // 每个测试后重置会状态 } ``` 3. **加密会测试**:使用真实`HttpSession`实现测试加密属性 ```java @Test public void testEncryptedSession() { HttpSession realSession = new StandardSession(); realSession.setAttribute("encryptedData", encrypt("sensitive")); // 验证解密逻辑 } ``` 4. **分布式会测试**:集成Redis等会存储 ```java @Test public void testRedisSession() throws Exception { // 启用Redis会存储 @Autowired private RedisTemplate<String, Object> redisTemplate; // 验证会同步逻辑 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值