我尝试在@Valid
旁边使用spring-mvc @RequestBody
来验证我的json有效负载是否具有给定参数。
我找到了使用绑定的解决方案,但这样做几乎就像在@RequestMapping
方法中调用验证一样。当您有预期的有效负载时,我也找到了使用@Valid
的方法。
我的有效负载是完全动态的,我只想验证字段的存在,例如id
。我当前的处理程序是:
@RequestMapping(method = RequestMethod.POST, value="/path", consumes = "application/json")
@ResponseBody
@Valid
public Object get(final HttpServletRequest request, @Valid @RequestBody HashMap payload ) {
由于我的有效负载是完全动态的,因此我创建了一个HashMap
来保存它。如果我将@NotEmpty
扩展到只是验证该属性是否存在的自定义类,我想知道是否可以使用HashMap
或类似的注释。
我是否在正确的轨道上?这对动态有效载荷不可能吗?
提前致谢。
答案 0 :(得分:3)
问题是肯定的,不是。
是,您可以使用@Valid
请求验证。
否,您不能对属性使用简单的@NotEmpty
,因为您需要为此目的定义DTO。
鉴于有效载荷是动态的,我能做的最好的事情是基于@EddieB tutorial link,它就是这样的。
与我在问题中的函数标题相同
@RequestMapping(method = RequestMethod.POST, value="/path", consumes = "application/json")
@ResponseBody
public Object get(final HttpServletRequest request, @Valid @RequestBody HashMap payload ) {
但由于有效负载是动态的,在本例中是HashMap,因此需要进行某种自定义验证。我找到的最简洁的方法是使用@InitBinder
注释将Validator
附加到@Valid
请求。
// instantiated in the constructor
private final MyValidator myValidator
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(this.myValidator);
}
然后是我们的自定义验证器:
public class MyValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return HashMap.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
// do your custom validation.
// if you don't call error.reject* it is considered a valid argument
}
如果您确实抛出了错误,则可以通过创建@ControllerAdvice
来捕获它。在我的情况下,我明确地将@ResponseStatus
设置为BAD_REQUEST
,就像它到达这里一样,它肯定是由一个糟糕的有效载荷引起的:
@ControllerAdvice
public class MyHandler{
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public String processValidationError(MethodArgumentNotValidException exception) {
// custom error handling
}
}
感谢两位成员的评论让我得到了这个答案。