1.定义一个自个儿的校验注解
package com.lance.common.core.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 字段校验注解
*
* @author lance
*/
@Target({FIELD})
@Retention(RUNTIME)
public @interface Validation
{
// 允许的值
String[] allowValue() default {};
// 限制的值
String[] limitValue() default {};
// 必须为空
boolean mustEmpty() default false;
// 若值为限制值的返回信息
String limitMsg() default "校验未通过";
}
2.一个执行校验的util
package com.lance.common.core.annotation.impl;
import com.lance.common.core.annotation.Validation;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Arrays;
/**
* 用于参数校验的方法
*
* @author lance
*/
@SuppressWarnings({"rawtypes", "unused", "unchecked"})
public final class ValidationUtils
{
/**
* 参数校验.
*
* @param obj pojo对象
* @return 校验结果
* @throws Exception e
*/
public static String validate(Object obj)
{
Assert.notNull(obj, "参数为null");
// 校验结果
String validateResult = null;
// 获取类字段
Field[] fields = obj.getClass().getDeclaredFields();
// 遍历pojo的字段进行校验
for (Field field : fields)
{
try
{
validateResult = fieldValidate(obj, field);
}
catch (IllegalAccessException e)
{
e.printStackTrace();
validateResult = "校验过程出现异常";
}
if (!StringUtils.isEmpty(validateResult))
{
return validateResult;
}
}
return validateResult;
}
/**
* 遍历字段上的注解对指定注解进行校验.
*
* @param obj 参数
* @param field 属性
* @return 单个字段的检验结果
* @throws Exception e
*/
private static String fieldValidate(Object obj, Field field) throws IllegalAccessException
{
String backVal = null;
// 获取字段名称
String fieldName = field.getName();
// 设置可以获取private属性的字段
field.setAccessible(true);
// 获取字段的值
Object value = field.get(obj);
// 获取字段上的注解
Annotation[] annotations = field.getAnnotations();
// 校验结果
for (Annotation an : annotations)
{
// 若扫描到Verification注解
if (an.annotationType().getName().equals(Validation.class.getName()))
{
// 获取指定类型注解
Validation column = field.getAnnotation(Validation.class);
// 进行业务处理,校验
backVal = businessValidate(column, value);
if (!StringUtils.isEmpty(backVal))
{
return backVal;
}
}
}
field.setAccessible(false);
return backVal;
}
/**
* 业务校验
*
* @param column 注解
* @param value 字段值
* @return 业务校验结果
*/
private static String businessValidate(Validation column, Object value)
{
String emptyVal;
String limitVal;
if (!StringUtils.isEmpty(emptyVal = mustEmptyValidate(column, value)))
{
return emptyVal;
}
else if (!StringUtils.isEmpty(limitVal = limitValueValidate(column, value)))
{
return limitVal;
}
else
{
return allowValueValidate(column, value);
}
}
/**
* 必须为空校验
*
* @param column 注解
* @param value 字段值
* @return 业务校验结果
*/
private static String mustEmptyValidate(Validation column, Object value)
{
if (column.mustEmpty() && null != value)
{
return column.limitMsg();
}
else
{
return null;
}
}
/**
* 限制值校验
*
* @param column 注解
* @param value 字段值
* @return 业务校验结果
*/
private static String limitValueValidate(Validation column, Object value)
{
String[] limitArray = column.limitValue();
if (limitArray.length > 0)
{
value = String.valueOf(value);
boolean result = Arrays.asList(limitArray).contains(value);
if (result)
{
return column.limitMsg();
}
else
{
return null;
}
}
else
{
return null;
}
}
/**
* 允许值校验
*
* @param column 注解
* @param value 字段值
* @return 业务校验结果
*/
private static String allowValueValidate(Validation column, Object value)
{
String[] allowArray = column.allowValue();
if (allowArray.length > 0)
{
value = String.valueOf(value);
boolean result = Arrays.asList(allowArray).contains(value);
if (!result)
{
return column.limitMsg();
}
else
{
return null;
}
}
else
{
return null;
}
}
}
3.在需要校验的bean字段上加入注解信息,并添加一个校验方法
package com.lance.business.pojo.model;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.lance.common.core.annotation.Validation;
import com.lance.common.core.annotation.impl.ValidationUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 基础信息类
*
* @author lance
**/
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public class SampleModel
{
/**
* 标识
*/
public String key;
/**
* 是否允许查询
*/
@Validation(limitValue = {"否"}, limitMsg = "不允许此渠道查询")
public String allowSearch;
/**
* 类型
*/
@Validation(allowValue = {"A类", "C类"}, limitMsg = "此类型不受理")
public String kind;
/**
* 信息校验
*
* @return 检验结果
*/
public String validateResult()
{
return ValidationUtils.validate(this);
}
}
4.使用测试
import com.lance.business.pojo.model.SampleModel;
import org.junit.Test;
import org.springframework.util.StringUtils;
public class BaseTest
{
@Test
public void validateTest()
{
SampleModel sampleModel = new SampleModel();
sampleModel.setKey("");
sampleModel.setAllowSearch("");
sampleModel.setKind("");
String validateMsg = sampleModel.validateResult();
if (StringUtils.isEmpty(validateMsg))
{
System.out.println("校验结果:成功");
}
else
{
System.out.println("校验结果:失败");
System.out.println(validateMsg);
}
}
}
最后:
使用此种方式进行校验可以减少一些令人不爽的if...else,代码看起来整洁清爽且开发、改动更加方便,但是性能却不如一堆if...else,但几乎无影响。比较适用于我这种患者。
比如从数据库查出来一个对象,要判断里面的属性是否合规,正常就需要写一堆if...else,啊,看起来好烦...
而使用这种注解的方式几行代码就解决了,清爽~
代码示例见:
https://blog.csdn.net/sinat_30637097/article/details/87920779
github地址的BaseTest