在Java Web开发中,JSON数据交互、自动化测试和会话管理是构建稳定可靠Web应用的核心能力。本文通过实际案例,系统讲解JSON解析、JUnit单元测试框架以及Cookie/Session的协同工作机制,帮助开发者掌握从数据层到会话层的完整开发链路。
Java标准库提供了
org.json和
javax.json两种原生JSON处理方式,但实际开发中更推荐使用Jackson或Gson库。以Jackson为例:
java1// 添加Maven依赖2<dependency>3 <groupId>com.fasterxml.jackson.core</groupId>4 <artifactId>jackson-databind</artifactId>5 <version>2.15.2</version>6</dependency>78// 对象转JSON9ObjectMapper mapper = new ObjectMapper();10User user = new User("Alice", "alice@example.com");11String jsonStr = mapper.writeValueAsString(user);12// 输出: {"name":"Alice","email":"alice@example.com"}1314// JSON转对象15User parsedUser = mapper.readValue(jsonStr, User.class);
处理嵌套JSON和集合时,需定义对应的Java类结构:
java1// 订单DTO示例2public class Order {3 private String orderId;4 private List<OrderItem> items;5 <"www.lvliang.gov.cn.a-8.cn"> <"www.gujiao.gov.cn.a-8.cn"> <"www.linfen.gov.cn.a-8.cn"> // getters/setters省略6}78public class OrderItem {9 private String productId;10 private int quantity;11}1213// 解析嵌套JSON14String orderJson = "{\"orderId\":\"ORD123\",\"items\":[{\"productId\":\"P100\",\"quantity\":2}]}";15Order order = mapper.readValue(orderJson, Order.class);
通过
@JsonSerialize注解实现特殊格式处理:
java1public class CustomDateSerializer extends JsonSerializer<LocalDate> {2 @Override3 public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider provider) throws IOException {4 gen.writeString(value.format(DateTimeFormatter.ISO_DATE));5 }6}78public class Event {9 @JsonSerialize(using = CustomDateSerializer.class)10 private LocalDate eventDate;11}
使用
@Test注解标记测试方法,结合断言验证结果:
java1import org.junit.jupiter.api.Test;2import static org.junit.jupiter.api.Assertions.*;34public class CalculatorTest {5 <"www.jiexiu.gov.cn.a-8.cn"><"www.huairen.gov.cn.a-8.cn"> <"www.gaoping.gov.cn.a-8.cn"> @Test6 public void testAddition() {7 Calculator calc = new Calculator();8 assertEquals(5, calc.add(2, 3), "Addition should return correct sum");9 }1011 @Test12 public void testDivisionByZero() {13 Calculator calc = new Calculator();14 assertThrows(ArithmeticException.class, () -> calc.divide(10, 0));15 }16}
使用
@ParameterizedTest避免重复测试代码:
java1@ParameterizedTest2@CsvSource({3 "1, 1, 2",4 "5, 7, 12",5 "-3, 4, 1"6})7public void testAddWithParameters(int a, int b, int expected) {8 assertEquals(expected, new Calculator().add(a, b));9}
使用Mockito模拟依赖对象:
java1@Test2public void testOrderService() {3 // 创建mock对象4 InventoryService mockInventory = Mockito.mock(InventoryService.class);5 when(mockInventory.checkStock("P100")).thenReturn(true);6 7 OrderService orderService = new OrderService(mockInventory);8 boolean result = orderService.placeOrder("ORD123", "P100", 2);9 10 assertTrue(result);11 verify(mockInventory, times(1)).checkStock("P100");12}
在Servlet中操作Cookie:
java1// 设置Cookie2protected void doGet(HttpServletRequest request, HttpServletResponse response) {3 Cookie userCookie = new Cookie("user_id", "U1001");4 userCookie.setMaxAge(7 * 24 * 60 * 60); // 7天有效期5 userCookie.setPath("/");6 response.addCookie(userCookie);7 8 // 读取Cookie9 Cookie[] cookies = request.getCookies();10 if (cookies != null) {11 for (Cookie cookie : cookies) {12 if ("user_id".equals(cookie.getName())) {13 System.out.println("User ID: " + cookie.getValue());14 }15 }16 }17}
使用HttpSession存储用户状态:
java1// 登录处理2protected void doPost(HttpServletRequest request, HttpServletResponse response) 3 throws ServletException, IOException {4 5 String username = request.getParameter("username");6 String password = request.getParameter("password");7 8 if (authenticate(username, password)) {9 HttpSession session = request.getSession();10 session.setAttribute("currentUser", username);11 session.setMaxInactiveInterval(1800); // 30分钟超时12 response.sendRedirect("dashboard.jsp");13 } else {14 request.setAttribute("error", "Invalid credentials");15 request.getRequestDispatcher("login.jsp").forward(request, response);16 }17}1819// 访问控制20protected void doGet(HttpServletRequest request, HttpServletResponse response) {21 HttpSession session = request.getSession(false); // 不创建新session22 if (session == null || session.getAttribute("currentUser") == null) {23 response.sendRedirect("login.jsp");24 return;25 }26 // 正常业务逻辑...27}
在集群环境中使用Redis存储Session:
java1// Spring Boot配置示例2@Configuration3@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)4public class SessionConfig {5 @Bean6 public LettuceConnectionFactory connectionFactory() {7 return new LettuceConnectionFactory(new RedisStandaloneConfiguration("localhost", 6379));8 }9}1011// 存储对象到Session12@RestController13public class UserController {14 @GetMapping("/profile")15 public ResponseEntity<?> getProfile(HttpSession session) {16 UserProfile profile = (UserProfile) session.getAttribute("profile");17 if (profile == null) {18 return ResponseEntity.status(401).body("Please login first");19 }20 return ResponseEntity.ok(profile);21 }22}
java1// 登录DTO2public class LoginRequest {3 <"www.yongji.gov.cn.a-8.cn"> <"www.hejin.gov.cn.a-8.cn"> @NotBlank4 private String username;5 6 @Size(min=8)7 private String password;8 9 private boolean rememberMe;10 // getters/setters11}1213// 控制器层14@RestController15@RequestMapping("/api/auth")16public class AuthController {17 @Autowired18 private UserService userService;19 20 @PostMapping("/login")21 public ResponseEntity<?> login(@Valid @RequestBody LoginRequest request, 22 HttpServletRequest httpRequest) {23 24 User user = userService.authenticate(request.getUsername(), request.getPassword());25 if (user == null) {26 return ResponseEntity.badRequest().body("Invalid credentials");27 }28 29 // 创建Session30 HttpSession session = httpRequest.getSession();31 session.setAttribute("user", user);32 33 // 处理RememberMe34 if (request.isRememberMe()) {35 Cookie rememberCookie = new Cookie("remember", user.getId().toString());36 rememberCookie.setMaxAge(30 * 24 * 60 * 60); // 30天37 rememberCookie.setHttpOnly(true);38 httpRequest.getResponse().addCookie(rememberCookie);39 }40 41 return ResponseEntity.ok(new LoginResponse(user.getId(), "Login successful"));42 }43 44 @GetMapping("/logout")45 public ResponseEntity<?> logout(HttpServletRequest request) {46 request.getSession().invalidate();47 return ResponseEntity.ok("Logged out successfully");48 }49}
java1@SpringBootTest2@AutoConfigureMockMvc3public class AuthControllerTest {4 @Autowired5 private MockMvc mockMvc;6 7 @MockBean8 private UserService userService;9 10 @Test11 public void testLoginSuccess() throws Exception {12 User mockUser = new User(1L, "testuser", "password");13 when(userService.authenticate("testuser", "password")).thenReturn(mockUser);14 15 mockMvc.perform(post("/api/auth/login")16 .contentType(MediaType.APPLICATION_JSON)17 .content("{\"username\":\"testuser\",\"password\":\"password\",\"rememberMe\":true}"))18 .andExpect(status().isOk())19 .andExpect(jsonPath("$.message").value("Login successful"));20 }21 22 @Test23 public void testLoginFailure() throws Exception {24 when(userService.authenticate("invalid", "user")).thenReturn(null);25 26 mockMvc.perform(post("/api/auth/login")27 .contentType(MediaType.APPLICATION_JSON)28 .content("{\"username\":\"invalid\",\"password\":\"user\"}"))29 .andExpect(status().isBadRequest());30 }31}
掌握JSON数据处理、单元测试和会话管理技术,是构建高质量Java Web应用的基础。通过Jackson库实现高效的数据转换,利用JUnit和Mockito构建可靠的测试体系,结合Cookie/Session机制管理用户状态,开发者能够构建出既稳定又易于维护的Web系统。随着微服务架构的普及,这些基础技能将进一步延伸到RESTful API开发、JWT认证等更复杂的场景,为全栈开发奠定坚实基础。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/19545/viewspace-3100026/ ,如需转载,请注明出处,否则将追究法律责任。