[英]How do I get the details of multiple missing request parameters from a Validated Spring RestController?
I'm attempting to use Spring's validation of two @RequestParam
s, with an @ControllerAdvice
catching the exceptions thrown by the framework when a parameter is missing, and returning a 400 error with the missing parameter.我正在尝试使用 Spring 对两个
@RequestParam
的验证,使用@ControllerAdvice
捕获缺少参数时框架抛出的异常,并返回缺少参数的 400 错误。
So, my code looks like:所以,我的代码看起来像:
@RestController
@Validated
public class FooController {
@RequestMapping(value = "/foo", method = RequestMethod.GET)
@ResponseBody
public Foo getFoo(@RequestParam LocalDate dateFrom, @RequestParam LocalDate dateTo) {
// Do stuff
}
}
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(value = {MissingServletRequestParameterException.class})
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
@ResponseBody
public ErrorResponse handleMissingParameterException(MissingServletRequestParameterException ex) {
return new ErrorResponse(ex.getMessage());
}
}
This works perfectly if I miss a single parameter - I get a nice JSON response that looks like:如果我错过了一个参数,这将非常有效——我得到一个很好的 JSON 响应,如下所示:
{
"reason": "Required LocalDate parameter 'dateFrom' is not present"
}
with a 400 status.状态为 400。
However if I miss both parameters, I get the same error response as above - ie it's only reporting the first missing parameter, where I'd prefer it if I can list all of them.然而,如果我错过了这两个参数,我会得到与上面相同的错误响应——即它只报告第一个缺少的参数,如果我能列出所有参数,我会更喜欢它。
Looking at the method of the exception, it seems like it only intends to handle a single parameter - it has methods getParameterName()
and getParameterType()
in the singular.查看异常的方法,它似乎只打算处理单个参数 - 它具有单数形式的方法
getParameterName()
和getParameterType()
。
Is there any way I can get Spring to report all validation errors in a single exception to improve the experience for the client?有什么方法可以让 Spring 在单个异常中报告所有验证错误以改善客户端的体验?
Instead introduce a one POJO filter with validate annotations取而代之的是引入一个带有验证注解的 POJO 过滤器
public class Filter {
@NotNull
private LocalDate dateFrom;
@NotNull
private LocalDate dateTo;
}
and then just use it in the controller然后在控制器中使用它
public Foo getFoo(@Valid Filter filter) {
// Do stuff
}
BindingResult will provide all validation errors BindingResult 将提供所有验证错误
You can set @RequestParam(required = false)
and then use @NotNull
.您可以设置
@RequestParam(required = false)
然后使用@NotNull
。
If a parameter is null
then a ConstraintViolationException
will be thrown.如果参数为
null
,则将抛出ConstraintViolationException
。 To handle it just declare an @ExceptionHandler
method.要处理它,只需声明一个
@ExceptionHandler
方法。 Check the code snippet below检查下面的代码片段
@RestController
@Validated
public class FooController {
@RequestMapping(value = "/foo", method = RequestMethod.GET)
@ResponseBody
public Foo getFoo(
@RequestParam (required = false)
@NotNull(message = "Required LocalDate parameter dateFrom is not present")
LocalDate dateFrom,
@RequestParam (required = false)
@NotNull(message = "Required LocalDate parameter dateTo is not present")
LocalDate dateTo)
) {
// Do stuff
}
}
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler({ConstraintViolationException.class})
public ResponseEntity<List<ErrorResponseDTO>> exceptionHandler(ConstraintViolationException e) {
List<ErrorResponseDTO> errors = new ArrayList<>(e.getConstraintViolations().size());
e.getConstraintViolations().forEach(violation -> errors.add(new ErrorResponseDTO(violation.getMessage())));
return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
}
}
Outcome will be like this:结果会是这样的:
[
{
"reason": "Required LocalDate parameter dateFrom is not present"
},
{
"reason": "Required LocalDate parameter dateTo is not present"
}
]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.