我正在替换Spring Boot REST控制器中对POST请求输入的手动验证。JSR-303 Spring Bean验证用于验证请求主体中的实例变量,这是预期的工作。什么是建议的方法来验证请求主体中的对象不是null?
我试过:
>
用@NotNull注释整个类
我正在替换:
@PostMapping...
public ResponseEntity<Map<String, Object>> editFoo(
@RequestBody Foo foo, ...) {
if(foo == null) {
return (new ResponseEntity<>(headers, HttpStatus.BAD_REQUEST));
}
}
与Bean验证等效:
@PostMapping...
public ResponseEntity<Map<String, Object>> editFoo(
@Valid @RequestBody Foo foo, ...) {
...
}
我尝试通过以下方式对控制器方法进行单元测试:
// Arrange
Foo foo = null;
String requestBody = objectMapper.writeValueAsString(foo);
// Act + assert
mockMvc
.perform(
post("/end_point")
.contentType("application/json")
.content(requestBody))
.andExpect(status().isBadRequest());
我希望MethodArgumentNotValidException由@ControllerAdvice处理此异常,但在执行单元测试时,我得到了HttpMessageEndableException。我的问题是:
查看代码时,您已经检查了主体是否为空。实际上,@RequestBody
有一个默认参数required
,默认为true。所以不需要进行Bean验证!
你的主要问题似乎在你的测试中。首先,编写一个测试来验证null上的endpoint行为是很好的。
然而,在你的测试中,你不能通过null。您尝试使用objectMapper
从null
值创建Json对象。您正在编写的对象似乎不是有效的json。因此,当您发送此正文时,Spring表示它无法读取消息,也就是您请求的正文,正如您所说,它是一个应用程序/json
内容,但其中没有json。
要测试空正文,只需在测试中发送请求,只需删除。内容(requestBody)
行,它应该可以工作!
---编辑1我以为它是因为身体而拒绝了信息,但事实上它似乎马上就对我起作用了。这是我的控制器和测试,您可以将其与完整代码进行比较:
@RestController()
@RequestMapping("end_point")
public class TestController {
@PostMapping
public ResponseEntity<Map<String, Object>> editFoo(@RequestBody Foo foo) {
// if(foo == null) {
// return (new ResponseEntity<>(new HashMap<>(), HttpStatus.BAD_REQUEST));
// }
return (new ResponseEntity<>(new HashMap<>(), HttpStatus.OK));
}
}
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class TestControllerTest {
@Autowired
private MockMvc mvc;
@Autowired
private ObjectMapper objectMapper;
@Test
public void test_body_is_null() throws Exception {
Foo foo = null;
String requestBody = objectMapper.writeValueAsString(foo);
// Act + assert
mvc
.perform(
post("/end_point")
.contentType("application/json")
.content(requestBody))
.andExpect(status().isBadRequest());
}
}
这是使用Spring Boot 2.1.6制作的。发布
---为记录编辑2如果您想在此处使用null验证,请参阅控制器的一个片段:
@RestController()
@RequestMapping("end_point")
@Validated
public class TestController {
@PostMapping
public ResponseEntity<Map<String, Object>> editFoo(@NotNull @RequestBody(required = false) Foo foo) {
return (new ResponseEntity<>(new HashMap<>(), HttpStatus.OK));
}
}
首先,必须将主体的required设置为false,因为默认值为true。然后,您必须在请求主体上添加@NotNull
注释,并在控制器上添加@Validated
。在这里,如果启动测试,您将看到请求失败,原因是:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.validation.ConstraintViolationException: editFoo.foo: must not be null
正如你所说的,你有一个@ControlllerAdtions
,然后你可以按照你的意愿映射异常!
我正在使用Java和Spring构建一个RESTAPI,我需要在我的控制器中处理一个POST请求,但我需要从该请求中提取主体,它是一个JSON,也是该请求的“来源”, 我有几个问题:首先是如何获取该请求的来源(我猜是在标题中移动的url?),是否有与@RequestBody类似的注释?。 我的第二个问题是,在这种post方法中,通常应该返回什么对象作为响应。
在我的控制器中,我有一个用以下映射映射的方法:@PostMapping(“/”)。 此方法需要一个我试图捕获的请求主体,如下所述: 使用这两种方法对我来说都很好,我只是进退两难,如果直接在实体类中接受请求体是一个好主意和最佳实践的话。 我不想在controller类中公开我的实体类,因为我不确定这是否是一个好主意。 java 这两种方法都给出了相同的结果,更多的是关注要遵循的最佳实践。
对传递的 URL 发出一个 POST 请求。 使用 XMLHttpRequest web api 对给定的url 发出一个 post 请求。 用 setRequestHeader 方法设置 HTTP 请求头的值。 通过调用给定的 callback 和 responseText 来处理 onload 事件。 通过运行提供的 err 函数,处理onerror事件。 省略第三个参数 data ,不发送数
问题内容: 我正在开发一个使用大量ajax的grails应用程序。如果请求是ajax调用,那么它应该给出响应(这部分正在工作),但是如果我在浏览器中输入URL,它应该带我到主页/索引页面而不是请求的页面。下面是Ajax调用的示例gsp代码。 如果我们在浏览器URL栏中键入http:// localhost:8080 / Dash / todo / list ,则控制器应重定向到http:// lo
我需要实现一个接受对象(json)的postendpoint。但对象中的某些参数是可选的。所以,当我尝试进行api调用时,它并没有映射到相应的方法。 显示页面未找到Err: 404 我发送的请求正文只包含两个字段,其余的都是可选的。 对象的Pojo Spring控制器: 卷曲命令: 有效载荷 } Rest控制器:
我试图在提供者端运行一个PACT测试,但我不知道如何操作从PACT文件中获得的请求体。我需要这样做,因为我必须使用来自State Step的id。 此外,更复杂的是,我的主体是一个XML。下面是我的协议请求的样子: 正如我所说的,在Provider状态下,我将有一个请求,并且这个请求的响应将是让我们说'Mary'。所以我的问题是,在执行验证测试时,如何将协议请求体中的“Jane”替换为“Mary”