我正在尝试将spring-mvc @Valid
与@RequestBody
一起使用,以验证我的json负载是否有给定的参数。
我已经找到了使用绑定的解决方案,但这样做几乎就像在@RequestMapping
方法中调用验证一样。我还找到了一种方法,当您有预期的Payload时,可以使用@Valid
。
我的有效负载是完全动态的,我只想验证字段的存在,例如id
。我目前的处理程序是:
@RequestMapping(method = RequestMethod.POST, value="/path", consumes = "application/json")
@ResponseBody
@Valid
public Object get(final HttpServletRequest request, @Valid @RequestBody HashMap payload ) {
由于我的负载是完全动态的,我创建了一个HashMap
来保存它。我想知道如果我将HashMap
扩展到一个自定义类,只需验证该属性是否存在,我是否可以使用@NotEmpty
或类似的注释。
我走对了吗?这对于动态有效载荷来说是不可能的吗?
提前谢谢。
问题是肯定和否定。
是,您可以使用@Valid
请求验证。
否,您不能对属性使用简单的@NotEmpty
,因为您需要一个定义的DTO。
考虑到有效负载是动态的,我能做的最好的事情是基于@EddieB教程链接,它是这样的。
与我在问题中的功能标题相同
@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
}
}
感谢两位成员的评论,使我得出了这个答案。