mvc分别对应什么 MVC异同解析 springbootmvc项目
本文详细阐述了在Spring Boot应用中使用MockMvc进行REST API测试时,如何有效地向POST或PUT请求传递JSON格式的请求体对象。针对接口需要接收@RequestBody参数的场景,教程介绍了利用Jackson ObjectMapper将Java对象序列化为JSON字符串,并通过MockMvcRequestBuilders的contentType和content方法将其作为请求体发送的完整步骤,确保测试能够准确模拟客户端行为并验证控制器逻辑。
在Spring Boot项目中,MockMvc是测试RESTful API的强大工具,它允许我们模拟HTTP请求,从而启动完整的Servlet容器。但是,当我们需要测试那些接收JSON请求体(通过@RequestBody注解)的接口时,如何将Java对象作为请求参数传递给MockMvc通常会成为一个疑问。本教程将详细介绍解决这个问题的标准方法。理解@RequestBody与MockMvc请求体
Spring MVC 的 @RequestBody 注解用于将 HTTP 请求体的内容绑定到方法的参数上。通常,当客户端发送 JSON 数据时,Spring 会使用内置的 HTTP 消息转换器(例如 Jackson)
在MockMvc测试中,我们无法直接将Java对象实例提交给请求构建器(如post()或put()方法)。MockMvc模拟的是真实的HTTP请求,这意味着请求体必须是原始的字节流或字符串形式。,我们因此需要手动将Java对象序列化为JSON核心步骤:对象序列化与请求构建
实现这一目标的关键在于使用Jackson库的ObjectMapper将Java对象转换为JSON字符串,并将其设置到MockMvcRequestBuilders的content()方法中,同时指定正确的Content-Type头部。 准备发送的 Java 对象
首先,定义你希望发送的请求体作为 Java 对象。
以问题中提到的CartDto为例:public class CartDto { private String itemId; private int amount; // Getters and Setters public CartDto() {} // Jackson经常需要默认构造函数 public CartDto(String itemId, int amount) { this.itemId = itemId; this.quantity =Quantity; } public String getItemId() { return itemId; } public void setItemId(String itemId) { this.itemId = itemId; } public int getQuantity() { return数量; } public void setQuantity(int数量) { this.quantity = 数量; }}登录后复制2. 将Java对象序列化为JSON字符串
使用Jackson ObjectMapper将CartD转换为JSON字符串。ObjectMapper是Jackson库的核心类,用于JSON的序列化和反序列化。
import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.core.JsonProcessingException;// ... 在你的测试类中 ...ObjectMapper objectMapper = new ObjectMapper();CartDto cartDto = new CartDto(quot;item001quot;, 2);String jsonContent;try { jsonContent = objectMapper.writeValueAsString(cartDto);} catch (JsonProcessingException e) { // 处理序列化异常,例如记录日志或发送运行时异常 throw new RuntimeException(quot;无法将 CartDto 序列化为 JSONquot;, e);}System.out.println(quot;生成的 JSON: quot; jsonContent);// 预期输出示例: 生成的 JSON: {quot;itemIdquot;:quot;item001quot;,quot;quantityquot;:2}登录后复制3. 构建 MockMvc 请求并发送 JSON 内容
现在,有了 JSON 字符串,你可以将其传递给 MockMvcRequestBuilders 的 content() 方法。同时,一定要使用 contentType(MediaType.APPLICATION_JSON) 设置请求的 Content-Type 头部,以告知 Spring 这是一个 JSON 请求。
import org.springframework.test.web.servlet.MockMvc;import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;import org.springframework.http.MediaType;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;// ... 在你的测试类中 ...// 假设mockMvc已经被@Autowired或手动初始化// @Autowired// private MockMvc mockMvc;// ... 接续上面的jsonContent生成代码 ...mockMvc.perform(MockMvcRequestBuilders.post(quot;/user/addItemIntoCartquot;) .contentType(MediaType.APPLICATION_JSON) // 声明请求体内容为JSON格式 .content(jsonContent)) //JSON字符串作为请求体.andExpect(status().isOk()) // 希望HTTP状态码为200 OK .andReturn(); // 获取MvcResult登录后复制完整示例代码
下面是一个完整的MockMvc测试方法示例,展示了如何测试一个接收CartDto作为@RequestBody参数的控制器方法。
导入 com.fasterxml.jackson.databind.ObjectMapper;导入 org.junit.jupiter.api.BeforeEach;导入 org.junit.jupiter.api.Test;导入 org.springframework.beans.factory.annotation.Autowired;导入 org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;导入 org.springframework.boot.test.mock.mockito.MockBean;导入 org.springframework.http.MediaType;导入 org.springframework.http.ResponseEntity;导入 org.springframework.test.web.servlet.MockMvc;导入 org.springframework.web.bind.annotation.PostMapping;导入 org.springframework.web.bind.annotation.RequestBody;导入 org.springframework.web.bind.annotation.RequestMapping;导入org.springframework.web.bind.annotation.RestController;导入静态 org.mockito.ArgumentMatchers.any;导入静态 org.mockito.Mockito.when;导入静态 org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;导入静态 org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;导入静态 org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;// 模拟的 CartDto 类 class CartDto { private String itemId; private int amount; public CartDto() {} public CartDto(String itemId, int amount) { this.itemId = itemId; this.quantity = amount; } public String getItemId() { return itemId; } public void setItemId(String itemId) { this.itemId = itemId; } public int
getQuantity() { return amount; } public void setQuantity(int amount) { this.quantity = amount; }}// 模拟的 CartService 接口 interface CartService { ResponseEntitylt;Stringgt; addItemIntoCart(CartDto cartDto);}// 模拟的 UserController @RestController@RequestMapping(quot;/userquot;)class UserController { private final CartService cartService; public UserController(CartService cartService) { this.cartService = cartService; } @PostMapping(value = quot;/addItemIntoCartquot;, consumer = {quot;application/jsonquot;}) public ResponseEntitylt;Stringgt; addItemToCart(@RequestBody CartDto cartDto) { return cartService.addItemIntoCart(cartDto); }}@WebMvcTest(UserController.class) // 针对 UserController 进行 Web 层测试 public class UserControllerTest { @Autowired private MockMvc mockMvc; @MockBean // 模拟CartService,避免真实的服务层调用 private CartService cartService; private ObjectMapper objectMapper; @BeforeEach void setUp() { objectMapper = new ObjectMapper(); // 初始化 ObjectMapper } @Test void testAddItemIntoCart() throws Exception { // 1. 准备发送的 CartDto 对象 CartDto cartDto = new CartDto(quot;productXYZquot;, 3); // 2. 将 CartDto 对象序列化为 JSON 字符串 String jsonContent = objectMapper.writeValueAsString(cartDto); // 3. 模拟 CartService 的行为(任选,但通常需要) // 当 cartService.addItemIntoCart 被调用时,返回一个成功的 ResponseE
ntity when(cartService.addItemIntoCart(any(CartDto.class))) .thenReturn(ResponseEntity.ok(quot;项目添加成功quot;)); // 4. 构建 MockMvc 请求并发送 JSON 内容 mockMvc.perform(post(quot;/user/addItemIntoCartquot;) .contentType(MediaType.APPLICATION_JSON) // 设置 Content-Type .content(jsonContent)) //设置请求体内容 .andExpect(status().isOk()) // 验证 HTTP 状态码是否为 200 OK .andExpect(content().string(quot;项目添加成功quot;)); // 验证响应体内容 }}登录后复制注意事项Content-Type 头部的重要性:务必使用 contentType(MediaType.APPLICATION_JSON)。如果缺少此头部或设置错误,Spring MVC 将无法正确识别请求体为 JSON,并可能导致 415 Unsupported Media类型错误或@RequestBody无法绑定。ObjectMapper实例:在测试中,您可以直接创建new ObjectMapper()实例。如果你的应用对ObjectMapper有特殊的配置(例如日期格式、忽略未知属性等),并且这些配置会影响JSON的序列化/反序列化,那么你可能需要注入或使用Spring里面提供的ObjectMapper实例,以确保测试环境与生产环境的行为一致。异常处理:objectMapper.writeValueAsString()可能会抛出JsonProcessingException。在测试代码中,通常会添加其向上的转发(throws)其他HTTP方法:对于接收请求体的PUT请求,也采用两种方法:序列化对象为JSON,然后通过put().content().contentType()发送。依赖:确保你的项目中包含了Jackson库的依赖,通常在Spring Boot项目中,这会通过spring-boot-starter-web自动引入。总结
通过本教程,我们在Spring Boot学习了MockMvc测试中,如何有效地转发Java对象JSON请求体提交给控制器方法。核心是利用Jackson ObjectMapper将Java对象序列化为JSON字符串,并通过MockMvcRequestBuilders的contentType()和content()方法构建模拟请求。掌握这个技巧对于编写健壮、准确的REST API集成测试关键,它可以帮助你模拟真实的客户端行为,从而全面验证你的控制器逻辑。
以上就是Spring Boot MockMvc 测试:如何传递JSON请求体对象的详细内容,更多请关注乐哥常识网其他文章相关!