要正确处理验证错误,您可以使用JSR-303附带Spring网络。例如,假设您有一个控制器,它有两个参数postalCode
和email
。你可以创建一个名为ApiParameters
对象:
public class ApiParameters {
@NotNull(message = "is empty")
@Email(message = "is not an email")
private String email;
@NotNull(message = "is required")
private String postalCode;
public ApiParameters() {
}
// Getters + Setters
}
的@NotNull
和@Email
注解验证注解(@Email
是从休眠虽然)。现在
,在你的控制器,你现在可以把:
@GetMapping
public String doStuff(@Valid ApiParameters parameters) {
// ...
}
由于@Valid
注释,如果任何参数是错误的,那么BindException
被抛出,你可以在一个catch控制器咨询类,像这样:
@ControllerAdvice
public class ErrorHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(BindException.class)
@ResponseBody
public ErrorResponse errorResponse(BindException ex) {
return new ErrorResponse("Validation failed", ex.getFieldErrors()
.stream()
.map(err -> new SpecificError(err.getField(), err.getDefaultMessage()))
.collect(Collectors.toList()));
}
}
这里发生的是,我所说的BindException
的getFieldErrors()
方法,它包含了所有错误的列表。然后映射那些类似于你想要的响应(ErrorResponse
和SpecificErorr
)响应类:
public class ErrorResponse {
@JsonProperty("general_errors")
private String generalErrors;
private List<SpecificError> errors;
public ErrorResponse(String generalErrors, List<SpecificError> errors) {
this.generalErrors = generalErrors;
this.errors = errors;
}
public String getGeneralErrors() {
return generalErrors;
}
public List<SpecificError> getErrors() {
return errors;
}
}
public class SpecificError {
private String key;
private String value;
public SpecificError(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
}
如果你打电话给你的API与参数不够,你现在将得到下面的JSON响应:
{
"errors": [
{
"key": "postalCode",
"value": "is required"
},
{
"key": "email",
"value": "is empty"
}
],
"general_errors": "Validation failed"
}
这个类似,您可以赶上RuntimeException
S以及:
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(RuntimeException.class)
@ResponseBody
public ErrorResponse errorResponse(RuntimeException ex) {
return new ErrorResponse(ex.getMessage(), null);
}
但是,如果你想两者结合起来,你会甲肝e手动调用验证器,因为这种方式的作用是一旦抛出异常,它将停止处理该方法。
这意味着如果您的方法会抛出RuntimeException
,如果验证错误已被抛出,则不会发生。
难道你不能只使用标准的JSR303验证。示例https://www.mkyong.com/spring-mvc/spring-3-mvc-and-jsr303-valid-example/ BindingResult包含所有发现的错误。 – StanislavL