1. 自定義校驗(yàn)器實(shí)現(xiàn)
package javax.validation.constraints;下有許多預(yù)設(shè)的校驗(yàn)器注解比如:
- [x]
AssertFalse - [x]
AssertTrue - [x]
DecimalMax - [x]
DecimalMin - [x]
Max - [x]
Min - [x]
NotNull - [x]
Null
但是有時(shí)候會(huì)有校驗(yàn)手機(jī)號(hào)或郵箱的麻煩事,或者校驗(yàn)全角半角字符長(zhǎng)度的校驗(yàn),這時(shí)自定義校驗(yàn)器就派上用場(chǎng)了
2.校驗(yàn)器示例(一個(gè)蛋疼的全角半角字符校驗(yàn))- 來(lái)自ios客戶(hù)端某評(píng)論內(nèi)容需求
2.1 定義注解名,注解類(lèi)型,校驗(yàn)實(shí)現(xiàn)類(lèi)等,內(nèi)容如下:
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 描述:校驗(yàn)unicode長(zhǎng)度
*
* @author biguodong
* Create time 2018-07-31 上午10:33
**/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UnicodeMaxImpl.class)
public @interface UnicodeMax {
int minLength();
int maxLength();
String message() default "數(shù)據(jù)長(zhǎng)度不合法!";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
如上聲明的是一個(gè)全角半角字符長(zhǎng)度判斷校驗(yàn)器注解,相關(guān)字段參數(shù)在使用的時(shí)候酌情添加修改即可:
2.2 自定義校驗(yàn)器需要實(shí)現(xiàn)的接口類(lèi)ConstraintValidator<A extends Annotation, T>
需要重寫(xiě)兩個(gè)方法:
- [x]
void initialize(A constraintAnnotation); - [x]
boolean isValid(T value, ConstraintValidatorContext context);
接口定義如下:
package javax.validation;
import javax.validation.constraintvalidation.SupportedValidationTarget;
import java.lang.annotation.Annotation;
/**
* 定義校驗(yàn)注解 {@code A}以及需要校驗(yàn)的數(shù)據(jù)類(lèi)型 {@code T}
*/
public interface ConstraintValidator<A extends Annotation, T> {
/**
* 實(shí)例化校驗(yàn)器
* 使用校驗(yàn)器之前,此方法一定會(huì)被調(diào)用
*/
void initialize(A constraintAnnotation);
/**
* 實(shí)現(xiàn)校驗(yàn)邏輯
* {@code value}不能被改變
* 如果校驗(yàn)不通過(guò),返回false
*/
boolean isValid(T value, ConstraintValidatorContext context);
}
2.3 校驗(yàn)器實(shí)現(xiàn)類(lèi)邏輯
import org.springframework.util.StringUtils;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* 描述:校驗(yàn)unicode長(zhǎng)度實(shí)現(xiàn)
* 計(jì)算半角和全角長(zhǎng)度
* @author biguodong
* Create time 2018-07-31 上午10:35
**/
//注解的實(shí)現(xiàn)類(lèi)需要實(shí)現(xiàn)ConstraintValidator接口并指定注解類(lèi)和被校驗(yàn)的數(shù)據(jù)類(lèi)型(String)
public class UnicodeMaxImpl implements ConstraintValidator<UnicodeMax, String> {
//定義長(zhǎng)度下限
private int minLength;
//定義長(zhǎng)度上限
private int maxLength;
/**
*重寫(xiě)實(shí)例化方法
*/
@Override
public void initialize(UnicodeMax constraintAnnotation) {
this.maxLength = constraintAnnotation.maxLength();
this.minLength = constraintAnnotation.minLength();
}
/**
*重寫(xiě)校驗(yàn)方法
*/
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
//判空邏輯因人而異
if (StringUtils.isEmpty(value)) {
return true;
}
int length = getCharLength(value);
if (length < minLength || length > maxLength) {
return false;
}
return true;
//return Pattern.matches("^(([\\u4e00-\\u9fa5]|[\\w\\s]|[\\pP|\\pS])*)?$", value);
}
/*
*獲取字符串的長(zhǎng)度(含半角字符和全角字符)
*/
public static int getCharLength(String value){
int halfCharCount = 0;
int allCharCount = 0;
char[] chars = value.toCharArray();
for (int i = 0; i < chars.length; i++) {
String temp = String.valueOf(chars[i]);
/**
* 判斷是全角字符
*/
if (temp.matches("[^\\x00-\\xff]")) {
allCharCount ++;
}
/**
* 判斷是半角字符
*/
else {
halfCharCount ++;
}
}
return halfCharCount + 2 * allCharCount;
}
}
2.5 小試牛刀之好鞍上馬
我在一個(gè)內(nèi)部類(lèi)上添加了此注解來(lái)約束content的數(shù)據(jù)長(zhǎng)度
/**
* 移動(dòng)端傳遞數(shù)據(jù)接收對(duì)象
* @author biguodong
*/
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class CommentReceiver{
/**
* 視頻id
*/
private Long videoId;
/**
* 父級(jí)id-回復(fù)
*/
private Long parentId;
/**
* 用戶(hù)id
*/
private Long userId;
/**
* 評(píng)論內(nèi)容
*/
@UnicodeMax(maxLength = 100, minLength = 0, message = "內(nèi)容過(guò)長(zhǎng)!")
private String content;
}
2.6 小試牛刀之策馬奔騰
配上好兄弟
@Validated讓我們策馬奔騰看下效果吧~
import org.springframework.validation.annotation.Validated;
/**
* 添加評(píng)論
* @param commentReceiver
* @return
* @throws BizException
*/
@PostMapping
public Object commentAdd(@RequestParam long loginUserId, @RequestBody @Validated CommentVo.CommentReceiver commentReceiver) throws BizException{
commentReceiver.setUserId(loginUserId);
return commentService.save(commentReceiver);
}
提示信息不能亂來(lái)奧~