目錄
- JSR303
- 使用步驟
- 關于不為空
- 分組校驗
- 自定義校驗
- 完整代碼
JSR303
使用步驟
1.依賴
<!--資料校驗-->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
2.在entity類的屬性上添加注解
3.開啟校驗功能:在controller類的方法的引數上加上@Valid屬性
4.校驗失敗的處理:
- 第一種:單獨處理
public R save(@Valid @RequestBody BrandEntity brand,BindingResult result){
if(result.hasErrors()){
Map<String,String> map = new HashMap<>();
//1、獲取校驗的錯誤結果
result.getFieldErrors().forEach((item)->{
//FieldError 獲取到錯誤提示
String message = item.getDefaultMessage();
//獲取錯誤的屬性的名字
String field = item.getField();
map.put(field,message);
});
return R.error(400,"提交的資料不合法").put("data",map);
}else {
brandService.save(brand);
}
return R.ok();
}
- 第二種,拋出例外后統一處理
- 定義
@RestControllerAdvice處理請求例外類 - 將
@ExceptionHandler(value= https://www.cnblogs.com/jklixin/p/xxx.class)注解根據例外型別標注在方法上,撰寫處理邏輯
@Slf4j
@RestControllerAdvice
public class ExceptionControllerAdvice {
@ExceptionHandler(value= https://www.cnblogs.com/jklixin/p/MethodArgumentNotValidException.class)
public R handleValidException(MethodArgumentNotValidException e){
log.error("資料校驗出現問題{},例外型別:{}",e.getMessage(),e.getClass());
BindingResult bindingResult = e.getBindingResult();
Map<String,String> errorMap = new HashMap<>();
bindingResult.getFieldErrors().forEach((error)->{
//存盤校驗欄位名,以及校驗欄位失敗提示
errorMap.put(error.getField(),error.getDefaultMessage());
});
return R.error(BizCodeEnume.VAILD_EXCEPTION.getCode(),BizCodeEnume.VAILD_EXCEPTION.getMsg()).put("data",errorMap);
}
@ExceptionHandler(value = https://www.cnblogs.com/jklixin/p/Throwable.class)
public R handleException(Throwable throwable){
log.error("錯誤:",throwable);
return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(),BizCodeEnume.UNKNOW_EXCEPTION.getMsg());
}
}
- 定義例外列舉類
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 int getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
關于不為空
-
@NotNull
只要不為空,校驗任意型別
The annotated element must not be {@code null}.
Accepts any type.
-
@NotBlank
至少有一個非空字符,校驗字符
The annotated element must not be {@code null} and must contain at least one
non-whitespace character. Accepts {@code CharSequence}.
-
@NotEmpty
非空,也不能內容為空,校驗字符,集合,陣列
The annotated element must not be {@code null} nor empty. Supported types are:
{@code CharSequence} (length of character sequence is evaluated)
{@code Collection} (collection size is evaluated)
{@code Map} (map size is evaluated)
Array (array length is evaluated)
分組校驗
步驟:
-
在校驗注解上加上
groups = {xxx.class, ...}屬性,值可以是任意interface介面,例如@URL(message = "logo必須是一個合法的url地址",groups={AddGroup.class,UpdateGroup.class}); -
在開啟校驗處,將
@Valid注解改為@Validated({xxx.class}),例如@Validated({AddGroup.class})就表示只校驗該組的屬性;注意:未添加任何分組的校驗將會無效,開啟嬌艷的時候i如果添加了分組資訊,那么只會校驗同樣頁添加了該分組的屬性,
自定義校驗
1)、撰寫一個自定義的校驗注解
@Documented
@Constraint(validatedBy = { })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {
String message() default "{com.lx.common.valid.ListValue.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
int[] vals() default { };
}
2)、撰寫組態檔ValidationMessages.properties,給自定義的校驗配置校驗失敗的資訊
com.lx.common.valid.ListValue.message=顯示狀態只能為1或0
3)、撰寫一個自定義的校驗器 ConstraintValidator
? 實作ConstraintValidator介面,第一個引數為系結的校驗注解名,第二個引數為校驗的屬性型別,完成初始化與判斷方法,
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
private Set<Integer> set = new HashSet<>();
/**
* @Description: 根據注解中的屬性初始化
* @Param0: constraintAnnotation
**/
@Override
public void initialize(ListValue constraintAnnotation) {
int[] vals = constraintAnnotation.vals();
for (int val:vals) {
set.add(val);
}
}
/**
* @Description: 判斷校驗是否成功
* @Param0: value 被校驗值
* @Param1: context
**/
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
return set.contains(value);
}
}
4)、關聯自定義的校驗器和自定義的校驗注解
@Constraint(validatedBy = { ListValueConstraintValidator.class })
5)、使用
@NotNull(groups = {AddGroup.class, UpdateGroup.class})
@ListValue(vals = {0,1},groups = {AddGroup.class,UpdateGroup.class})
private Integer showStatus;
完整代碼
controller
/**
* 保存
*/
@RequestMapping("/save")
public R save(@Validated({AddGroup.class}) @RequestBody BrandEntity brand){
brandService.save(brand);
return R.ok();
}
/**
* 修改
*/
@RequestMapping("/update")
public R update(@Validated(UpdateGroup.class) @RequestBody BrandEntity brand){
brandService.updateById(brand);
return R.ok();
}
entity
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 品牌id
*/
@NotNull(message = "修改必須指定品牌id",groups = {UpdateGroup.class})
@Null(message = "新增不能指定id",groups = {AddGroup.class})
@TableId
private Long brandId;
/**
* 品牌名
*/
@NotBlank(message = "品牌名必須提交",groups = {AddGroup.class,UpdateGroup.class})
private String name;
/**
* 品牌logo地址
*/
@URL(message = "logo必須是一個合法的url地址",groups={AddGroup.class,UpdateGroup.class})
private String logo;
/**
* 介紹
*/
private String descript;
/**
* 顯示狀態[0-不顯示;1-顯示]
*/
@NotNull(groups = {AddGroup.class, UpdateGroup.class})
@ListValue(vals = {0,1},groups = {AddGroup.class,UpdateGroup.class})
private Integer showStatus;
/**
* 檢索首字母
*/
@NotEmpty(groups={AddGroup.class})
@Pattern(regexp="^[a-zA-Z]$",message = "檢索首字母必須是一個字母",groups={AddGroup.class,UpdateGroup.class})
private String firstLetter;
/**
* 排序
*/
@NotNull(groups={AddGroup.class})
@Min(value = https://www.cnblogs.com/jklixin/p/0,message ="排序必須大于等于0",groups={AddGroup.class,UpdateGroup.class})
private Integer sort;
}
測驗1:

測驗2:

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/187330.html
標籤:Java
下一篇:第六章第三十一題(金融應用:信用卡號的合法性驗證)(Financial: credit card number validation) - 編程練習題答案
