JAVA引數統一驗證擴充套件
Java中都可以以物件做為傳輸的形式,所有的本地介面,dubbo介面呼叫,都是要和物件打交道的
作為很平常的一個介面之間的呼叫,對於介面中傳遞物件的引數校驗是必不可少的,如果說物件內容較少,一個兩個if就可以驗證完畢,但是當介面引數超過10個,還要對內部引數進行:非空,是否大於xxx小於xxx,長度不能超過多少的時候,就很頭疼了。第一是浪費時間,第二是修改的時候可讀性也不好,很有可能改錯,或者覺得不方便。
最近在專案中遇到了一個很不錯的解決方法,自己試了下,也記錄下,以後會用上。使用該方法的好處如圖所示。
假設一個介面需要,學生(Student),和老師(Teacher)物件,這兩個物件的內部引數,有部分不能為空,有部分不能取別的值,按照以往的做法就很麻煩,每個內部引數可能至少有一個或多個if驗證(先驗證是否為空,在驗證是否是某些值)。
但是使用了這種拓展方法,就可以通過註解的方式,制定一個統一的引數驗證方法,改的時候也非常簡單。
實現過程如下:
1.首先,pom中新增
<dependency>
<groupId>net.sf.oval</groupId>
<artifactId>oval</artifactId>
<version>1.81</version>
</dependency>
oval 就是這次起核心作用的擴充套件包,他的任務就是,提供在物件或者引數上註解,然後通過內部提供的validate方法,對相關物件和介面統一驗證。
2.待驗證的物件,以下列程式碼為例,將所需註解,和如果驗證不通過的返回message及errorCode包裝好
package zxy.test.dto; import net.sf.oval.constraint.Length; import net.sf.oval.constraint.Max; import net.sf.oval.constraint.Min; import net.sf.oval.constraint.NotNull; public class Student { @NotNull(errorCode="9001",message="學生姓名不能為空") private String name; @Length(min=1,max=3,errorCode="9010",message="請檢查年齡是否合規") private int age; @Max(value=1,errorCode="9011",message="請檢查性別是否合規,0是男生,1是女生") @Min(value=0,errorCode="9012",message="請檢查性別是否合規,0是男生,1是女生") private int sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getSex() { return sex; } public void setSex(int sex) { this.sex = sex; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", sex=" + sex + "]"; } }
3.驗證工具類 ,其中 BaseResp,和RespEnum是我建的驗證返回物件,和列舉,按具體情況修改。
package zxy.test.util;
import java.util.List;
import net.sf.oval.ConstraintViolation;
import net.sf.oval.Validator;
import zxy.test.dto.BaseResp;
import zxy.test.dto.RespEnum;
public class validKit {
public static BaseResp valid(Object obj) {
Validator validator = new Validator();
List<ConstraintViolation> list = validator.validate(obj);
BaseResp resp = new BaseResp();
//只要list不為空,就可以判斷是驗證沒有通過,一般只用獲取其中一條錯誤返回即可
if (!list.isEmpty()) {
resp.setMessage(list.get(0).getMessage());
resp.setCode(list.get(0).getErrorCode());
//下面迴圈,只是為了展示驗證結果,實際中按業務需求
for (ConstraintViolation constraintViolation : list) {
System.out.println("物件驗證結果,返回碼:"+constraintViolation.getErrorCode()+",返回資訊"+constraintViolation.getMessage());
}
} else {
resp.setCode(RespEnum.SUCCESS.code);
resp.setMessage(RespEnum.SUCCESS.message);
}
return resp;
}
}
package zxy.test.dto;
public class BaseResp {
private String code;
private String message;
@Override
public String toString() {
return "BaseResp [code=" + code + ", message=" + message + "]";
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
package zxy.test.dto;
public enum RespEnum {
SUCCESS("SUCCESS", "0000");
public String code;
public String message;
RespEnum(String code, String message) {
this.code = code;
this.message = message;
}
}
4.工具類的呼叫
只要成功就會返回code :0000,其餘的失敗都會自動在驗證工具類中,把事先用註解配置好的code,和message返回到返回物件中,這樣,只要判斷返回物件code是否為0000就可以了
public class app {
public static void main(String[] args) {
//構造引數
Student student=new Student();
student.setAge(9999);
student.setSex(888);
Teacher teacher=new Teacher();
//驗證學生
BaseResp respStudent= validKit.valid(student);
//驗證老師
BaseResp respTeacher=validKit.valid(teacher);
//返回值判斷
if(!RespEnum.SUCCESS.code.equals(respStudent.getCode())
||!RespEnum.SUCCESS.code.equals(respTeacher.getCode()) ){
System.err.println(respStudent.toString());
System.err.println(respTeacher.toString());
return;
}
//假設訪問方法
StudyActivity activity=new StudyActivity();
activity.mathClass(student,teacher);
}
}
附demo連結:
該demo包括了excel 通用解析,和java引數統一驗證的完整方法,可直接執行