是否可以将@Valid与从JSON负载创建的@HashMap一起使用



我正在尝试将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
    }
}

感谢两位成员的评论,使我得出了这个答案。

最新更新