Java丨优雅地使用Java一行代码实现对象的空值校验

一、效果

二、实现思路 

具体的实现思路是,使用反射技术获得并执行传入对象的getter方法,通过判断执行结果校验其参数是否为空,再通过自定义注解的形式取得字段的中文名拼接结果并将其返回。

三、实现步骤

3.1 自定义注解@FieldName

   使用自定义注解标注类对象的字段,使方法能通过反射的形式获取到对象的字段的中文释义

/**
 * 注解 @FieldName  用于标注类对象的字段
 * 使用该注解,甚至可以代替传统的javadoc
 * @author TanzJ
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FieldName {
    //默认值
    String value();
    //对象备注,可要可不要
    String comment() default "";
}

    特别注意的是,此处 @Retention 注解十分重要,他用于定义该注解的生命周期,一般有三个参数选择:

        1、仅编译期:RetentionPolicy.SOURCE

        2、仅Class文件:RetentionPolicy.CLASS

        3、运行期:RetentionPolicy.RUNTIME

    此处我们定义了RetentionPolicy.RUNTIME,原因是在运行期我们需要通过反射来获取对象的value值。

而 @Target 注解也被称为元注解,他用于定义目标注解所能使用的位置,一般有以下几个参数可供选择:

       1、类或接口:ElementType.TYPE

       2、字段:ElementType.FIELD

       3、方法:ElementType.METHOD

       4、构造方法:ElementType.CONSTRUCTOR

       5、方法参数:ElementType.PARAMETER

    此处我们因为需要对对象的字段进行控制校验,因此定义了ElementType.FIELD。

至此,我们完成了自定义注解的编写,通过该注解,我们甚至可以替换掉传统的javadoc注释。关于自定义注解的更多内容,这里不再过多赘述。

3.2 使用@FieldName注解对象的字段

public class Teacher {
    @FieldName(value = "教工号")
    private String teacherNo;
    @FieldName(value = "教师姓名")
    private String teacherName;
    @FieldName(value = "身份证号",comment = "18位")
    private String identityNo;
    //省略getter与setter
}

3.3 编写结果组件间传输对象 


public class BaseModel {
	@FieldName(value = "操作结果",comment = "操作结果-success/fail")
	private String result;
	@FieldName(value = "返回信息")
	private Object message;
	@FieldName(value = "业务状态码")
	private Integer code;
	//省略getter/setter
}

3.4 编写空值校验器


public class CommonUtil {
		/**
	 * 对象空值校验器
	 * @param targetObject 传入的目标对象
	 * @param params 需要校验的参数数组
	 * @return BaseModel success/fail
	 */
	public static BaseModel validateParamsBlankAndNull(Object targetObject,String... params) throws NoSuchFieldException {
		//取得目标对象的类
		Class clazz = targetObject.getClass();
		//定义错误数量字段
		Integer errorNumber = 0;
		StringBuilder stringBuilder = new StringBuilder();
		for (String param:params){
			param = param.trim();
			Method method = null;
			try {
				//将param首字母大写,通过拼接“getter”取得对象的getter方法
				method = clazz.getMethod("get"+param.substring(0,1).toUpperCase()+param.substring(1));
			} catch (NoSuchMethodException e) {
				return new BaseModel(Constant.FAIL,"参数"+param+"不存在");
			}
			String result = null;
			try {
				//执行targetObject的getter方法
				result = (String) method.invoke(targetObject);
			} catch (IllegalAccessException e) {
				logger.error(e.getMessage());
				return new BaseModel(Constant.FAIL,"方法不可执行");
			} catch (InvocationTargetException e) {
				logger.error(e.getMessage());
				return new BaseModel(Constant.FAIL,"传入对象异常");
			}
			if (result==null || "".equals(result)){
				//注意,这里需要使用getDeclaredField,因为面向对象封装的特性,字段名一定是private的
				FieldName fieldName = clazz.getDeclaredField(param).getAnnotation(FieldName.class);
				if (fieldName!=null){
					stringBuilder.append(fieldName.value()+"为空;");
				}else {
					stringBuilder.append(param+"为空;");
				}
				errorNumber++;
			}
		}
		return errorNumber==0 ? new BaseModel(Constant.SUCCESS,"校验通过"):new BaseModel(Constant.FAIL,stringBuilder);
	}
 
}

3.5 编写单元测试


    @Test
    public void validateParamsBlankAndNull_test() throws NoSuchFieldException {
        Teacher teacher = new Teacher();
        teacher.setTeacherName("TanzJ");
        CommonUtil.validateParamsBlankAndNull(teacher,"teacherNo","teacherName","identityNo");
    }

至此,你可以使用一句

 CommonUtil.validateParamsBlankAndNull(targetObject,params[])

取得返回的result来对目标对象进行空值校验判断操作。

 

源码地址:

https://github.com/tanzzj/CommonWebNeedUtils

该项目将会封装常用的mybatis通用BaseDAO、分页插件、空值校验工具等,便于服务端开发的工具。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值