Java自定义注解校验参数信息
2018-08-27 本文已影响0人
嬉皮码龙
项目要求
实际项目中存在诸多场景需要校验入参数据。繁杂的参数校验占据相当部分的代码量,且不友好。
为便于实际开发写出此注解,切合实际的开发需求,多种场景的数据校验,并抛出自定义的异常信息,便于控制层处理,简化代码。
对比优势
1.繁杂的Hibernate校验注解,且不宜定制化开发,不适合多场景数据校验。
2.自定义注解,配合多场景数据校验,可定制化配置,可扩展,高效,易懂的配置。
自定义注解
- 注解类
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 校验参数注解 可根据需要扩展校验数据的选项,比如值区间max,min,值域
* @author vinod
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Validation {
//校验的属性的类型
ValidateType value() default ValidateType.TYPE_STRING;
//配置则根据当前字段校验 默认为空
String accordField() default "";
//根据accordField的值校验值 默认为空
String accordValue() default "";
//正数校验 默认不校验
boolean isPositive() default false;
}
- 数据类型枚举
/**
* 校验枚举
* @author vinod
*/
public enum ValidateType {
TYPE_STRING,
TYPE_INTEGER,
TYPE_CHAR,
TYPE_LONG,
TYPE_FLOAT,
TYPE_DOUBLE,
TYPE_BOOLEAN,
TYPE_DATE,
TYPE_LIST,
TYPE_MAP,
TYPE_SET,
TYPE_OBJECT
}
注解处理类
1.注解使用: bean中声明属性校验
public class UserInfo implements Serializable{
@Validate(ValidateType.TYPE_STRING)
private String username;
// 此处则可配置值域为(1,2),需扩展注解
private Integer sex; // 1:男 2:女
// 配置当前字段根据sex=2时才校验非空,
@Validate(value = ValidateType.TYPE_STRING,accordField = "sex",accordValue = "2")
private String size;
}
2.调用方法处理
// 1.1 校验必填字段
ValidationHandler.validateParams(req);
3.注解处理类源代码
import com.vinod.test.util.exception.UserDefineException;
import com.vinod.test.util.annotation.Validation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 仅处理传入object中的Validate注解
* @author vinod
*/
public class ValidationHandler {
private static Logger logger = LoggerFactory.getLogger(ValidationHandler.class);
// 方法重载
public static void validateParams(Object obj){
validateParams(obj,null,true);
}
public static void validateParams(Object obj,boolean accordFlag){
validateParams(obj,null,accordFlag);
}
/**
* 校验参数不为空
* @param obj 需要校验的对象
* @param excludeParams 需要排除校验的属性名集合
* @param accordFlag 根据属性依赖校验
*/
public static void validateParams(Object obj,Set<String> excludeParams,boolean accordFlag){
logger.info("xxxx日志记录");
Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
try {
Object value = field.get(obj);
// 当前属性在需要排除校验的集合中时,跳过当前字段校验。
if(excludeParams!=null&&excludeParams.contains(field.getName())){
continue;
}
Validation annotation = (Validation)field.getAnnotation(Validation.class);
//System.out.println("=====----"+annotation+"---> "+field.getName());
//注解存在时,则说明当前字段需要校验
if(annotation!=null){
// 是否根据依据筛选为空属性
if(accordFlag){
// 根据某字段判别是否为空
if(StringUtils.isNotEmpty(annotation.accordField())){
Field accordField = obj.getClass().getDeclaredField(annotation.accordField());
accordField.setAccessible(true);
Object accordValue = accordField.get(obj);
// 为空或不等于注解预设值则跳过当前属性的校验
if(accordValue==null||!accordValue.toString().equals(annotation.accordValue())){
continue;
}
}
}
// 属性值不能为空
if(value==null){
throw new UserDefineException(field.getName());
}
checkTypeEnumValue(annotation,field,value,annotation.isPositive());
}
} catch (IllegalAccessException e) {
// e.printStackTrace();
logger.info("xxxx日志记录");
//抛出自定义异常信息
throw new UserDefineException(field.getName());
} catch (NoSuchFieldException e) {
logger.info("xxxx日志记录");
//抛出自定义异常信息
throw new UserDefineException(field.getName());
}
}
}
/**
* 校验注解配置的属性值
* @param annotation
* @param field
* @param value
* @param isPositive
*/
private static void checkTypeEnumValue(Validation annotation, Field field, Object value,boolean isPositive){
// 暂值列举几种数据处理,剩余类型处理类似
switch (annotation.value()){
case TYPE_STRING:
if(StringUtils.isEmpty(value.toString())||"null".equals(value.toString().toLowerCase())){
throw new UserDefineException(field.getName());
}
break;
case TYPE_LONG:
if(0L==(Long)value){
throw new UserDefineException(field.getName());
}
if(isPositive&&(Long)value<0){
throw new UserDefineException(field.getName());
}
break;
}
}
}