Java Spring Bean 验证 @Valid 处理

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24811643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 14:58:31  来源:igfitidea点击:

Spring Bean Validation @Valid handling

javaspring-mvcbean-validation

提问by Dormouse

I have created a Spring MVC REST service using Bean Validation 1.2 with the following method:

我使用 Bean Validation 1.2 和以下方法创建了一个 Spring MVC REST 服务:

@RequestMapping(value = "/valid")
public String validatedMethod(@Valid ValidObject object) {

}

If object isn't valid, Tomcat informs me that The request sent by the client was syntactically incorrect.and my validatedMethodis never called.

如果对象无效,Tomcat 会通知我,The request sent by the client was syntactically incorrect.并且validatedMethod永远不会调用my 。

How can I get the message that was defined in the ValidObjectbean? Should I used some filter or interceptor?

如何获取在ValidObjectbean中定义的消息?我应该使用一些过滤器还是拦截器?

I know that I can rewrite like below, to get the set of ConstraintViolations from the injected Validator, but the above seems more neat...

我知道我可以像下面这样重写,ConstraintViolation从注入的s 中获取s的集合Validator,但上面的看起来更整洁......

@RequestMapping(value = "/valid")
public String validatedMethod(ValidObject object) {
    Set<ConstraintViolation<ValidObject>> constraintViolations = validator
            .validate(object);
    if (constraintViolations.isEmpty()) {
        return "valid";
    } else {
        final StringBuilder message = new StringBuilder();
        constraintViolations.forEach((action) -> {
            message.append(action.getPropertyPath());
            message.append(": ");
            message.append(action.getMessage());
        });
        return message.toString();
    }
}

采纳答案by dharam

I believe a better way of doing this is using ExceptionHandler.

我相信这样做的更好方法是使用ExceptionHandler.

In your Controlleryou can write ExceptionHandlerto handle different exceptions. Below is the code for the same:

在您Controller可以编写ExceptionHandler处理不同的异常。下面是相同的代码:

@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ValidationFailureResponse validationError(MethodArgumentNotValidException ex) {
    BindingResult result = ex.getBindingResult();
    final List<FieldError> fieldErrors = result.getFieldErrors();

    return new ValidationFailureResponse((FieldError[])(fieldErrors.toArray(new FieldError[fieldErrors.size()])));
}

When you send a bad request to the Controller, the validator throws an exception of type MethodArgumentNotValidException. So the ideal way would be to write an exception handler to specifically handle this exception.

当您向 Controller 发送错误请求时,验证器会抛出类型为 的异常MethodArgumentNotValidException。所以理想的方法是编写一个异常处理程序来专门处理这个异常。

There you can create a beautiful response to tell the user of things which went wrong. I advocate this, because you have to write this just once and many Controllermethods can use it. :)

在那里你可以创建一个漂亮的响应来告诉用户出了什么问题。我提倡这样做,因为你只需要写一次,很多Controller方法都可以使用它。:)

UPDATE

更新

When you use the @Valid annotation for a method argument in the Controller, the validator is invoked automatically and it tries to validate the object, if the object is invalid, it throws MethodArgumentNotValidException.

当您对 中的方法参数使用 @Valid 注释时Controller,验证器会自动调用并尝试验证对象,如果对象无效,则抛出MethodArgumentNotValidException

If Spring finds an ExceptionHandlermethod for this exception it will execute the code inside this method.

如果 Spring 找到ExceptionHandler此异常的方法,它将执行此方法中的代码。

You just need to make sure that the method above is present in your Controller.

您只需要确保上述方法存在于您的控制器中。

Now there is another case when you have multiple Controllers where you want to validate the method arguments. In this case I suggest you to create a ExceptionResolverclass and put this method there. Make your Controllers extend this class and your job is done.

现在还有另一种情况,当您有多个Controller要验证方法参数的 s时。在这种情况下,我建议您创建一个ExceptionResolver类并将此方法放在那里。让你的Controllers 扩展这个类,你的工作就完成了。

回答by usha

Try this

尝试这个

@RequestMapping(value = "/valid")
public String validatedMethod(@Valid ValidObject object, BindingResult result) {
    StringBuilder builder = new StringBuilder();
    List<FieldError> errors = bindingResult.getFieldErrors();
    for (FieldError error : errors ) {
       builder.append(error.getField() + " : " + error.getDefaultMessage());
    } 
    return builder.toString();
}