springboot接口參數(shù)校驗JSR303的實現(xiàn)
在 javax.validation.constraints包中定義了非常多的校驗注解,引入依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
在實體類上添加對應注解即可,
實體類:
package com.zhmsky.mallproduct.entity; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import java.io.Serializable; import java.util.Date; import lombok.Data; import javax.validation.constraints.NotBlank; /** * 品牌 * * @author zhmsky * @email zhmsky@gmail.com * @date 2022-07-30 16:40:28 */ @Data @TableName("pms_brand") public class BrandEntity implements Serializable { private static final long serialVersionUID = 1L; /** * 品牌名 */ @NotBlank(message = "品牌名不能為空") private String name; }
一、在controller接口處理校驗異常
message可指定校驗說明,
接下來在對應的controller接口方法中使用@Valid 注解來指定接口參數(shù)校驗,后面緊跟BindingResult來接收校驗結果,當發(fā)生校驗失敗則封裝并返回校驗失敗信息,如果通過校驗則執(zhí)行相關邏輯
@RequestMapping(value = "/save",method = RequestMethod.POST) public R save(@Valid @RequestBody BrandEntity brand, BindingResult result){ if(result.hasErrors()){ Map<String, String> map = new HashMap<>(); //獲取校驗結果 for (FieldError fieldError : result.getFieldErrors()) { //獲取錯誤提示 String message = fieldError.getDefaultMessage(); //校驗錯誤的字段 String field = fieldError.getField(); //封裝錯誤 map.put(field,message); } return R.error(20001,"參數(shù)校驗失敗").put("errorMap",map); } brandService.save(brand); return R.ok(); }
二、統(tǒng)一異常處理
如果在每一個接口都進行參數(shù)校驗異常處理,工作量比較大,并且代碼比較繁瑣,于是引入全局異常處理,
也就是@RestControllerAdvice+@ExceptionHandler注解的使用。
package com.zhmsky.mallproduct.exception; import com.zhmsky.common.utils.R; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import java.util.HashMap; import java.util.Map; /** * 同意異常處理類 * @author zhmsky * @date 2022/8/1 21:36 */ @Slf4j @RestControllerAdvice(basePackages = {"com.zhmsky.mallproduct.controller"}) public class MallProductControllerAdvice { //具體的某個異常類型處理 @ExceptionHandler(MethodArgumentNotValidException.class) public R handleValidException(MethodArgumentNotValidException e){ log.error("數(shù)據(jù)異常:{},異常類型:{}",e.getMessage(),e.getClass()); BindingResult result = e.getBindingResult(); Map<String, String> map = new HashMap<>(); for (FieldError fieldError : result.getFieldErrors()) { map.put(fieldError.getDefaultMessage(),fieldError.getField()); } return R.error().put("errorMap",map); } //拋出的所有異常類型處理 @ExceptionHandler(Throwable.class) public R handleException(Throwable e){ //TODO 處理邏輯 return R.error(); } }
三、錯誤碼枚舉類
package com.zhmsky.common.exception; /** * @author zhmsky * @date 2022/8/1 21:56 */ public enum ErrorCodeEnum { UNKNOWN_EXCEPTION(10000, "系統(tǒng)未知錯誤"), VALID_EXCEPTION(10001, "參數(shù)格式校驗失敗"); /** * 錯誤碼 */ private Integer code; /** * 錯誤提示 */ private String msg; ErrorCodeEnum(Integer code, String msg) { this.code = code; this.msg = msg; } public Integer getCode(){ return this.code; } public String getMsg(){ return this.msg; } }
四、自定義參數(shù)校驗注解
1、編寫自定義校驗注解
參照javax.validation.constraints的@NotBlank注解,
@Documented @Constraint(validatedBy = { }) @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) @Repeatable(List.class) public @interface NotBlank { //校驗規(guī)則提示信息 String message() default "{javax.validation.constraints.NotBlank.message}"; //分組校驗 Class<?>[] groups() default { }; //負載 Class<? extends Payload>[] payload() default { }; /** * Defines several {@code @NotBlank} constraints on the same element. * * @see NotBlank */ @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) @Documented public @interface List { NotBlank[] value(); } }
模仿上面可快速編寫一個自定義注解:
@Documented @Constraint(validatedBy = {StatusValueConstraintValidator.class}) @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE}) @Retention(RUNTIME) public @interface statusValue { //校驗規(guī)則提示信息(在配置文件中配置) String message() default "{com.zhmsky.common.validator.statusValue.message}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; //注解參數(shù) int[] values() default {}; }
創(chuàng)建 ValidationMessages.properties 文件,在配置文件中配置自定義的校驗規(guī)則提示信息:
com.zhmsky.common.validator.statusValue.message=error.......xxxx
2、編寫自定義校驗器
//statusValue就是自定義的注解,Integer就是自定義注解標注的字段類型 public class StatusValueConstraintValidator implements ConstraintValidator<statusValue, Integer> { private Set<Integer> set = new HashSet<>(); //初始化方法 @Override public void initialize(statusValue constraintAnnotation) { //字段標注的注解里面設定的值(校驗規(guī)則) int[] values = constraintAnnotation.values(); for (int value : values) { set.add(value); } } //判斷是否校驗成功 @Override public boolean isValid(Integer value, ConstraintValidatorContext context) { //value就是字段字段實際接收到的值 return set.contains(value); } }
3、關聯(lián)自定義注解和自定義校驗器
也就是在自定義注解的@Constraint注解中指明自定義的校驗器,
4、測試自定義注解@statusValue
@Data @TableName("pms_brand") public class BrandEntity implements Serializable { private static final long serialVersionUID = 1L; /** * 品牌名 */ @NotBlank(message = "品牌名不能為空") private String name; /** * 顯示狀態(tài)[0-不顯示;1-顯示],指定字段值只能為 0 或 1 */ @statusValue(values={0,1}) private Integer showStatus; }
在對應的controller接口中使用@Validated注解來進行校驗,showStatus字段傳入值3,
測試結果如圖:
到此這篇關于springboot接口參數(shù)校驗JSR303的實現(xiàn)的文章就介紹到這了,更多相關springboot接口參數(shù)校驗JSR303 內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot通過整合Dubbo解決@Reference注解問題
這篇文章主要介紹了SpringBoot通過整合Dubbo解決@Reference注解問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-03-03SpringMVC中Model和ModelAndView的EL表達式取值方法
下面小編就為大家分享一篇SpringMVC中Model和ModelAndView的EL表達式取值方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03