1. Prerequisite
< dependency>
< groupId> javax.validation</ groupId>
< artifactId> validation-api</ artifactId>
< version> 2.0.1.Final</ version>
</ dependency>
2. Check directly and return the error message given to you by the system
The encapsulated object passed from the front end, the attributes of the object bean
(BrandEntity as an example) you have added validation annotations ( @NotNull
, @NotEmpty
etc.).
@Valid
controller
The request body marked inside tells Spring that the attributes of the entity class need to be verified, and then once the verification fails, an error message will be returned to the front end
@RequestMapping ( "/save" )
public R save ( @Valid @RequestBody BrandEntity brand ) {
3, use BindingResult
@RequestMapping( "/save" )
public R save( @Valid @RequestBody BrandEntity brand , BindingResult result) {
BindingResult
The verification result of the corresponding entity class encapsulated inside
BindingResult
public interface BindingResult extends Errors {
String MODEL_KEY_PREFIX = BindingResult. class . getName ( ) + "." ;
@Nullable
Object getTarget ( ) ;
Map< String, Object> getModel ( ) ;
@Nullable
Object getRawFieldValue ( String var1) ;
@Nullable
PropertyEditor findEditor ( @Nullable String var1, @Nullable Class< ? > var2) ;
@Nullable
PropertyEditorRegistry getPropertyEditorRegistry ( ) ;
String[ ] resolveMessageCodes ( String var1) ;
String[ ] resolveMessageCodes ( String var1, String var2) ;
void addError ( ObjectError var1) ;
default void recordFieldValue ( String field, Class< ? > type, @Nullable Object value) {
}
default void recordSuppressedField ( String field) {
}
default String[ ] getSuppressedFields ( ) {
return new String [ 0 ] ;
}
}
public interface Errors {
String NESTED_PATH_SEPARATOR = "." ;
String getObjectName ( ) ;
void setNestedPath ( String var1) ;
String getNestedPath ( ) ;
void pushNestedPath ( String var1) ;
void popNestedPath ( ) throws IllegalStateException;
void reject ( String var1) ;
void reject ( String var1, String var2) ;
void reject ( String var1, @Nullable Object[ ] var2, @Nullable String var3) ;
void rejectValue ( @Nullable String var1, String var2) ;
void rejectValue ( @Nullable String var1, String var2, String var3) ;
void rejectValue ( @Nullable String var1, String var2, @Nullable Object[ ] var3, @Nullable String var4) ;
void addAllErrors ( Errors var1) ;
boolean hasErrors ( ) ;
int getErrorCount ( ) ;
List< ObjectError> getAllErrors ( ) ;
boolean hasGlobalErrors ( ) ;
int getGlobalErrorCount ( ) ;
List< ObjectError> getGlobalErrors ( ) ;
@Nullable
ObjectError getGlobalError ( ) ;
boolean hasFieldErrors ( ) ;
int getFieldErrorCount ( ) ;
List< FieldError> getFieldErrors ( ) ;
@Nullable
FieldError getFieldError ( ) ;
boolean hasFieldErrors ( String var1) ;
int getFieldErrorCount ( String var1) ;
List< FieldError> getFieldErrors ( String var1) ;
@Nullable
FieldError getFieldError ( String var1) ;
@Nullable
Object getFieldValue ( String var1) ;
@Nullable
Class< ? > getFieldType ( String var1) ;
}
Package again into the data you want to return
R
It is another example of my article used to encapsulate the front-end data. R example
if ( result. hasErrors ( ) ) {
Map< String, String> map = new HashMap < > ( ) ;
result. getFieldErrors ( ) . forEach ( ( item) - > {
String message = item. getDefaultMessage ( ) ;
String field = item. getField ( ) ;
map. put ( field, message) ;
} ) ;
return R. error ( 400 , "提交数据不合法" ) . put ( "data" , map) ;
}
4. Centralized processing
Unified exception handling, using SpringMVC provided ControllerAdvice
Extract classes that handle exceptions ExcExceptionControllerAdvice
@RestControllerAdvice 的basePackages
Specify the controller you need to handle
@ExceptionHandler(value = MethodArgumentNotValidException.class)
value: what kind of exception you need to handle
@Slf4j
@RestControllerAdvice ( basePackages = "" )
public class ExcExceptionControllerAdvice {
@ExceptionHandler ( value = MethodArgumentNotValidException. class )
public R handleValidException ( MethodArgumentNotValidException e) {
log. error ( "数据校验出现问题{},异常类型,{}" , e. getMessage ( ) , e. getClass ( ) ) ;
BindingResult bindingResult = e. getBindingResult ( ) ;
Map< String, String> map = new HashMap < > ( ) ;
bindingResult. getFieldErrors ( ) . forEach ( ( fieldError) - > {
map. put ( fieldError. getField ( ) , fieldError. getDefaultMessage ( ) ) ;
} ) ;
return R. error ( BizCodeEnume. VAILD_EXCEPTION. getCode ( ) , BizCodeEnume. VAILD_EXCEPTION. getMsg ( ) ) . put ( "data" , map) ;
}
@ExceptionHandler ( value = Throwable. class )
public R handleException ( Throwable throwable) {
log. error ( "错误:" + throwable) ;
return R. error ( BizCodeEnume. UNKNOW_EXCEPTION. getCode ( ) , BizCodeEnume. UNKNOW_EXCEPTION. getMsg ( ) ) ;
}
}
When using this centralized processing, the controller must throw an exception, so if you remove it from the request parameter, the BindingResult
exception will be sensed in the processing class.
@RequestMapping ( "/save" )
public R save ( @Valid @RequestBody BrandEntity brand) {
Canonical system error code
public enum BizCodeEnume {
UNKNOW_EXCEPTION ( 10000 , "系统未知异常" ) ,
VAILD_EXCEPTION ( 10001 , "参数格式检验失败" ) ;
private int code;
private String msg;
BizCodeEnume ( int code, String msg) {
this . code = code;
this . msg = msg;
}
public String getMsg ( ) {
return msg;
}
public int getCode ( ) {
return code;
}
}
5. Enhanced (JSR303 packet check)
public @interface NotBlank {
String message ( ) default "{javax.validation.constraints.NotBlank.message}" ;
Class< ? > [ ] groups ( ) default {
} ;
So we define an interface as a logo, without doing anything
E.g
public interface AddGroup {
}
@NotBlank ( groups = AddGroup. class )
private String brandName;
And write it in the corresponding method, then the name will only be save
verified at the time of the method
@Validated
It is different from the above useless grouping @Valid
, here you need to pay attention
@RequestMapping ( "/save" )
public R save ( @Validated ( {
AddGroup. class } ) @RequestBody BrandEntity brand ) {
/