如何处理RequestMapping中的@Valid违规?

时间:2018-08-17 13:41:02

标签: java spring rest validation

我在Java / Spring中具有以下Rest Controller。检查约束的有效性。但是,这些在到达“ bar”方法的主体之前就已完成。如何处理违规案件?我可以自定义400个响应正文吗?

@RestController
@RequestMapping("foo")
public class FooController {

    @RequestMapping(value = "bar", method = RequestMethod.POST)
    public ResponseEntity<Void> bar(@RequestBody @Valid Foo foo) {
        //body part
        return ResponseEntity.status(HttpStatus.OK).build();
    }

}

3 个答案:

答案 0 :(得分:1)

您应该使用controllerAdvice,这是一个示例(在Kotlin中):

@ControllerAdvice
open class ExceptionAdvice {

    @ExceptionHandler(MethodArgumentNotValidException::class)
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    open fun methodArgumentNotValidExceptionHandler(request: HttpServletRequest, e: MethodArgumentNotValidException): ErrorDto {

        val errors = HashMap<String, String>()

        for (violation in e.bindingResult.allErrors) {
            if (violation is FieldError) {
                errors.put(violation.field, violation.defaultMessage)
            }
        }

        return ErrorDto(errors)
    }

    @ExceptionHandler(BindException::class)
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    open fun bindExceptionHandler(request: HttpServletRequest, e: BindException): ErrorDto {

        val errors = HashMap<String, String>()

        for (violation in e.bindingResult.allErrors) {
            if (violation is FieldError) {
                errors.put(violation.field, violation.defaultMessage)
            }
        }

        return ErrorDto(errors)
    }
}

它允许处理控制器抛出的异常,包括验证异常。

答案 1 :(得分:1)

您可以在最后将BindingResult作为参数添加到方法签名中。

@RequestMapping(value = "bar", method = RequestMethod.POST)
public ResponseEntity<Void> bar(@RequestBody @Valid Foo foo, BindingResult bindingResult) 
{
    if (bindingResult.hasErrors()) {
        //do something if errors occured
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
    } 

    //body part
    return ResponseEntity.status(HttpStatus.OK).build();
}

答案 2 :(得分:-2)

使用休眠注释正确注释Foo对象,它将自动工作。例如,可能很少有验证

@NotEmpty(message = "first name must not be empty")
private String firstName;

@NotEmpty(message = "last name must not be empty")
private String lastName;

@NotEmpty(message = "email must not be empty")
@Email(message = "email should be a valid email")
private String email;

要处理其他错误,请写@ControllerAdvice

@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler
{
    @ExceptionHandler(RecordNotFoundException.class)
    public final ResponseEntity<Object> handleUserNotFoundException(RecordNotFoundException ex, WebRequest request) {
        List<String> details = new ArrayList<>();
        details.add(ex.getLocalizedMessage());
        ErrorResponse error = new ErrorResponse("Record Not Found", details);
        return new ResponseEntity(error, HttpStatus.NOT_FOUND);
    }
}

并在接受请求正文的同时添加@Valid注释。

@PostMapping(value = "/employees")
public ResponseEntity<EmployeeVO> addEmployee (@Valid @RequestBody EmployeeVO employee)
{
    EmployeeDB.addEmployee(employee);
    return new ResponseEntity<EmployeeVO>(employee, HttpStatus.OK);
}

详细了解有关rest validation的此博客。