spring 模拟 mvc 执行 post 请求正文丢失:错误 400
spring mock mvc perform post request body is missing : error 400
我尝试模拟一个 mvc 请求以在 spring 中测试端到端我的控制器。
post 请求需要请求正文,但我收到错误 400,告诉我缺少所需的请求正文,即使我使用 MockMvcResultsHandler 打印看到它的正文。
项目架构:
- 来源
- 主要
- 测试
- applications.properties
- 控制器
- 服务
这是我的 application.properties
spring.datasource.url=jdbc:h2:mem:tesdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=*****
spring.datasource.password=*****
spring.jpa.show-sql = true
这是我的测试
@SpringBootTest
@AutoConfigureMockMvc
public class IntegrationTest {
protected User mockUser;
protected List<User> allUsers;
@Autowired
private MockMvc mvc;
@Autowired
private WebApplicationContext webApplicationContext;
@BeforeEach
public void setUp() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext).build();
}
@Test
void testGetAllUsers() throws Exception {
this.mvc.perform(post("/api/users")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.characterEncoding("utf-8")
.content("{\"name\":\"name\"}"))
.andDo(print())
.andExpect(status().isCreated());
}
}
我的@RestController
@PostMapping(path = "/users")
public @ResponseBody ResponseEntity<User> addNewUser(
@RequestBody String name
) {
return userService.createUser(name);
}
和我的用户@Service
public ResponseEntity<User> createUser(String name) {
User user = new User();
user.setName(name);
userRepository.save(user);
当我尝试启动我的测试时,我进入了我的调试控制台
DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public org.springframework.http.ResponseEntity<java.lang.String> ....addNewType(java.lang.String,java.lang.Boolean)]
MockHttpServletRequest:
HTTP Method = POST
Request URI = /api/users
Parameters = {}
Headers = [Content-Type:"application/json;charset=utf-8", Accept:"application/json", Content-Length:"32"]
Body = {"name":"concat"}
Session Attrs = {}
响应是:
MockHttpServletResponse:
Status = 400
Error message = null
Headers = []
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
当我使用相同的体系结构时,get 方法似乎可以工作,主体似乎出现在控制台中,但 servelt 似乎没有 see/understand 请求主体。
美好的一天!
需要检查:
- API URL
- 需要 运行 spring 应用程序以便测试方法能够调用 API
URL.
尝试创建一个明确的 json 然后传入正文,同样在您的控制器中,您需要一个字符串名称,请尝试从 json 中获取它。
例如:
@Test
void testGetAllUsers() throws Exception {
JSONObject json = new JSONObject();
json.put("name", "john");
this.mvc.perform(post("/api/users")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.characterEncoding("utf-8")
.content(json.toString())
.andDo(print())
.andExpect(status().isCreated()); }
在你的控制器中你可以尝试这样的事情
@PostMapping(path = "/users")
public @ResponseBody ResponseEntity<User> addNewUser(
@RequestBody String name
) {
JSONObject json = new JSONObject(name);
String userName = json.getString("name");
return userService.createUser(userName);
}
所以这是我的真实 Web 服务的简化示例。
问题来自于我在同一个请求中多次使用@RequestBody
public @ResponseBody ResponseEntity<User> addNewUser(
@RequestBody String name ,
@RequestBody String lastName,
这是问题的根源。
为了解决这个问题,我创建了一个类似
的 DTO
public @ResponseBody ResponseEntity<User> addNewUser(
@RequestBody UserDTO userDto
现在一切正常
我尝试模拟一个 mvc 请求以在 spring 中测试端到端我的控制器。
post 请求需要请求正文,但我收到错误 400,告诉我缺少所需的请求正文,即使我使用 MockMvcResultsHandler 打印看到它的正文。
项目架构:
- 来源
- 主要
- 测试
- applications.properties
- 控制器
- 服务
这是我的 application.properties
spring.datasource.url=jdbc:h2:mem:tesdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=*****
spring.datasource.password=*****
spring.jpa.show-sql = true
这是我的测试
@SpringBootTest
@AutoConfigureMockMvc
public class IntegrationTest {
protected User mockUser;
protected List<User> allUsers;
@Autowired
private MockMvc mvc;
@Autowired
private WebApplicationContext webApplicationContext;
@BeforeEach
public void setUp() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext).build();
}
@Test
void testGetAllUsers() throws Exception {
this.mvc.perform(post("/api/users")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.characterEncoding("utf-8")
.content("{\"name\":\"name\"}"))
.andDo(print())
.andExpect(status().isCreated());
}
}
我的@RestController
@PostMapping(path = "/users")
public @ResponseBody ResponseEntity<User> addNewUser(
@RequestBody String name
) {
return userService.createUser(name);
}
和我的用户@Service
public ResponseEntity<User> createUser(String name) {
User user = new User();
user.setName(name);
userRepository.save(user);
当我尝试启动我的测试时,我进入了我的调试控制台
DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public org.springframework.http.ResponseEntity<java.lang.String> ....addNewType(java.lang.String,java.lang.Boolean)]
MockHttpServletRequest:
HTTP Method = POST
Request URI = /api/users
Parameters = {}
Headers = [Content-Type:"application/json;charset=utf-8", Accept:"application/json", Content-Length:"32"]
Body = {"name":"concat"}
Session Attrs = {}
响应是:
MockHttpServletResponse:
Status = 400
Error message = null
Headers = []
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
当我使用相同的体系结构时,get 方法似乎可以工作,主体似乎出现在控制台中,但 servelt 似乎没有 see/understand 请求主体。
美好的一天!
需要检查:
- API URL
- 需要 运行 spring 应用程序以便测试方法能够调用 API URL.
尝试创建一个明确的 json 然后传入正文,同样在您的控制器中,您需要一个字符串名称,请尝试从 json 中获取它。 例如:
@Test
void testGetAllUsers() throws Exception {
JSONObject json = new JSONObject();
json.put("name", "john");
this.mvc.perform(post("/api/users")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.characterEncoding("utf-8")
.content(json.toString())
.andDo(print())
.andExpect(status().isCreated()); }
在你的控制器中你可以尝试这样的事情
@PostMapping(path = "/users")
public @ResponseBody ResponseEntity<User> addNewUser(
@RequestBody String name
) {
JSONObject json = new JSONObject(name);
String userName = json.getString("name");
return userService.createUser(userName);
}
所以这是我的真实 Web 服务的简化示例。 问题来自于我在同一个请求中多次使用@RequestBody
public @ResponseBody ResponseEntity<User> addNewUser(
@RequestBody String name ,
@RequestBody String lastName,
这是问题的根源。
为了解决这个问题,我创建了一个类似
的 DTOpublic @ResponseBody ResponseEntity<User> addNewUser(
@RequestBody UserDTO userDto
现在一切正常