如何从 Validated Spring RestController 获取多个缺失请求参数的详细信息?
Posted
技术标签:
【中文标题】如何从 Validated Spring RestController 获取多个缺失请求参数的详细信息?【英文标题】:How do I get the details of multiple missing request parameters from a Validated Spring RestController? 【发布时间】:2017-12-10 02:47:04 【问题描述】:我正在尝试使用 Spring 对两个 @RequestParam
s 的验证,@ControllerAdvice
在缺少参数时捕获框架抛出的异常,并返回缺少参数的 400 错误。
所以,我的代码如下:
@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());
如果我错过了一个参数,这将非常有效 - 我会得到一个不错的 JSON 响应,如下所示:
"reason": "Required LocalDate parameter 'dateFrom' is not present"
状态为 400。
但是,如果我错过了两个参数,我会得到与上面相同的错误响应 - 即它只报告第一个丢失的参数,如果我可以列出所有参数,我会更喜欢它。
查看异常的方法,它似乎只打算处理单个参数 - 它有方法 getParameterName()
和 getParameterType()
以单数形式。
有什么方法可以让 Spring 在单个异常中报告所有验证错误以改善客户端的体验?
【问题讨论】:
我会尝试将它们设为可选并添加javax.validator
注释
顺便说一句,您确定调用了完全相同的方法,或者在同一路径上可能有另一个方法与单个参数?
【参考方案1】:
而是引入一个带有验证注释的 POJO 过滤器
public class Filter
@NotNull
private LocalDate dateFrom;
@NotNull
private LocalDate dateTo;
然后在控制器中使用它
public Foo getFoo(@Valid Filter filter)
// Do stuff
BindingResult 将提供所有验证错误
【讨论】:
【参考方案2】:您可以设置@RequestParam(required = false)
,然后使用@NotNull
。
如果参数是null
,则将抛出ConstraintViolationException
。要处理它,只需声明一个 @ExceptionHandler
方法。检查下面的代码sn-p
@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);
结果会是这样的:
[
"reason": "Required LocalDate parameter dateFrom is not present"
,
"reason": "Required LocalDate parameter dateTo is not present"
]
【讨论】:
以上是关于如何从 Validated Spring RestController 获取多个缺失请求参数的详细信息?的主要内容,如果未能解决你的问题,请参考以下文章
Spring提供的@Validated和MethodValidationPostProcessor完成数据校验