基于自定义注解实现后端对象校验功能
基于自定义注解实现后端对象校验功能
拿到一个需求,对表单进行后端校验,为了提高代码质量,简洁干净,提高复用性,所以考虑使用自定义注解来完成,话不多说,直接开搞。注:此功能没有使用到任何框架。
自定义注解
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FieldDesc {
//字段名称
String value() default "";
//字段长度
int feildLength() default -1;
//是否必填
boolean isNotNull() default false;
//校验类型
FieldTypeEnum feildType() default FieldTypeEnum.NORMAL;
}
校验类型枚举类
public enum FieldTypeEnum {
//正常
NORMAL,
//座机
PHONE,
//邮箱
EMAIL,
//手机号
MOBILE_PHONE,
//身份证号
ID_NUMBER,
//邮编
POST_CODE,
//网址
WEBSITE
}
字段类型校验正则工具类
public class FieldTypeCheckUtil {
//电话正则
public static String phoneregex = "^(\\\\d{3,4}-)?\\\\d{6,8}$";
//邮箱正则
public static String emailregex = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
//手机号正则
public static String mobilePhoneregex = "^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$";
//身份证正则
public static String idCardregex = "^\\d{15}|\\d{18}$";
//邮编正则
public static String postcardregex = "[1-9]\\d{5}(?!\\d)";
//网站正则
public static String websiteregex = "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?";
//校验电话
public static boolean checkPhone(String value) {
return value.matches(phoneregex);
}
//校验邮箱
public static boolean checkEmail(String value) {
return value.matches(emailregex);
//return EmailValidator.getInstance().isValid(value);
}
//校验手机号
public static boolean checkMobilePhone(String value) {
return value.matches(mobilePhoneregex);
}
//校验身份证号
public static boolean checkIdCard(String value) {
return value.matches(idCardregex);
}
//校验邮编
public static boolean checkPostCard(String value) {
return value.matches(postcardregex);
}
//校验网站
public static boolean checkWebsite(String value) {
return value.matches(websiteregex);
//return UrlValidator.getInstance().isValid(value);
}
}
校验结果对象
public class CheckResult {
//校验结果编码 200正常,500错误
private int checkStatusCode;
//存放校验结果信息
private List<String> checkMessage;
public int getCheckStatusCode() {
return checkStatusCode;
}
public void setCheckStatusCode(int checkStatusCode) {
this.checkStatusCode = checkStatusCode;
}
public List<String> getCheckMessage() {
return checkMessage;
}
public void setCheckMessage(List<String> checkMessage) {
this.checkMessage = checkMessage;
}
}
校验工具类
public class CheckUtil {
public static CheckResult Check(Object object) {
CheckResult checkResult = new CheckResult();
//默认校验结果编码先给200
checkResult.setCheckStatusCode(200);
//创建存放校验结果集合
List messageList = new ArrayList();
//获取要校验结果的class
Class clazz = object.getClass();
//获取class对应的属性
Field[] fields = clazz.getDeclaredFields();
//循环对象属性
for(int i = 0; i < fields.length; i++) {
//判断当前属性注解是否包含FieldDesc
if(fields[i].isAnnotationPresent(FieldDesc.class)) {
//拿到属性对应FieldDesc对应注解
FieldDesc fileName = fields[i].getAnnotation(FieldDesc.class);
//授权
fields[i].setAccessible(true);
String value = null;
try {
//获取属性对应的值
value = fields[i].get(object).toString();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//是否为空校验
if(fileName.isNotNull()) {
if(StringUtils.isBlank(value)) {
checkResult.setCheckStatusCode(500);
messageList.add(fileName.value()+“不能为空”);
}
}
//长度校验
if(fileName.feildLength() != -1) {
if(fileName.feildLength() < value.length()) {
checkResult.setCheckStatusCode(500);
messageList.add(fileName.value()+"不能超过"+fileName.feildLength());
}
}
//字段类型校验
if(!(fileName.feildType().equals(FieldTypeEnum.NORMAL))) {
switch (fileName.feildType()) {
case EMAIL:
if(!(FieldTypeCheckUtil.checkEmail(value))) {
checkResult.setCheckStatusCode(500);
messageList.add(fileName.value()+"认证不通过");
}
break;
case WEBSITE:
if(!(FieldTypeCheckUtil.checkWebsite(value))) {
checkResult.setCheckStatusCode(500);
messageList.add(fileName.value()+"认证不通过");
}
break;
case ID_NUMBER:
if(!(FieldTypeCheckUtil.checkIdCard(value))) {
checkResult.setCheckStatusCode(500);
messageList.add(fileName.value()+"认证不通过");
}
break;
case MOBILE_PHONE:
if(!(FieldTypeCheckUtil.checkMobilePhone(value))) {
checkResult.setCheckStatusCode(500);
messageList.add(fileName.value()+"认证不通过");
}
break;
case POST_CODE:
if(!(FieldTypeCheckUtil.checkPostCard(value))) {
checkResult.setCheckStatusCode(500);
messageList.add(fileName.value()+"认证不通过");
}
break;
}
}
}
}
checkResult.setCheckMessage(messageList);
return checkResult;
}
}
校验对象
public class User implements Serializable {
private int id;
@FieldDesc(value = "姓名",isNotNull = true,feildLength = 10)
private String name;
@FieldDesc(value = "年龄")
private int age;
@FieldDesc(value = "身份证号",isNotNull = true,feildType = FieldTypeEnum.ID_NUMBER)
private String idCard;
@FieldDesc(value = "邮编",isNotNull = true,feildType = FieldTypeEnum.POST_CODE)
private String postCode;
@FieldDesc(value = "个人博客",isNotNull = true,feildType = FieldTypeEnum.WEBSITE)
private String blog;
@FieldDesc(value = "手机号",isNotNull = true,feildType = FieldTypeEnum.MOBILE_PHONE)
private String mobilePhone;
@FieldDesc(value = "电子邮箱",isNotNull = true,feildType = FieldTypeEnum.EMAIL)
private String email;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
@Override
public int hashCode() {
return id;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof User) {
User user = (User)obj;
return this.id == user.id;
} else {
return false;
}
}
public User(int id, String name, int age, String idCard, String postCode, String blog, String mobilePhone, String email) {
this.id = id;
this.name = name;
this.age = age;
this.idCard = idCard;
this.postCode = postCode;
this.blog = blog;
this.mobilePhone = mobilePhone;
this.email = email;
}
}
编写测试类
public class UserTest {
private static final Logger logger = LoggerFactory.getLogger(UserTest.class);
public static void main(String[] args) {
User user = new User(1, "张三", -1,"自己编写","自己编写"
,"https://www.baidu.com","自己编写","自己编写");
CheckResult result = CheckUtil.Check(user);
if(result.getCheckStatusCode() == 200) {
logger.info("认证成功");
} else {
logger.warn("认证失败");
List<String> checkResult = result.getCheckMessage();
for (String string : checkResult) {
System.out.println(string);
}
}
}
}
如有代码问题或者优化方案,欢迎指正,虚心接受。