Java自定义注解实现验证实体类属性的合法性

    xiaoxiao2024-01-07  158

    一、注解的基础

    1.注解的定义:Java文件叫做Annotation,用@interface表示。

    2.元注解:@interface上面按需要注解上一些东西,包括@Retention、@Target、@Document、@Inherited四种。

    3.注解的保留策略:

    @Retention(RetentionPolicy.SOURCE) // 注解仅存在于源码中,在class字节码文件中不包含

    @Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得

    @Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到

    4.注解的作用目标:

    @Target(ElementType.TYPE) // 接口、类、枚举、注解

    @Target(ElementType.FIELD) // 字段、枚举的常量

    @Target(ElementType.METHOD) // 方法

    @Target(ElementType.PARAMETER) // 方法参数

    @Target(ElementType.CONSTRUCTOR) // 构造函数

    @Target(ElementType.LOCAL_VARIABLE) // 局部变量

    @Target(ElementType.ANNOTATION_TYPE) // 注解

    @Target(ElementType.PACKAGE) // 包

    5.注解包含在javadoc中:

    @Documented

    6.注解可以被继承:

    @Inherited

    1、自定义注解类:

    import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 请求参数校验 * @author Xuan * */ //注解包含于Javadoc中 @Documented //注解的作用目标 @Target(ElementType.FIELD) //注解可以被继承 @Inherited //注解的保留策略 @Retention(RetentionPolicy.RUNTIME) public @interface NotNull { /** * 必须参数 * @return */ boolean flag() default true; }

    2、实体类(规则需生成getandset方法):

    import AnnotationResolve; public class Pojo extends AnnotationResolve{ @NotNull private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }

    3、自定义注解解析器:

    import java.lang.reflect.Field; import java.lang.reflect.Method; /** * 自定义注解解析器 * @author Xuan * */ public class AnnotationResolve { public boolean validate() throws NoSuchMethodException, SecurityException,Exception { // 获取类的属性 Field[] fields = this.getClass().getDeclaredFields(); for (Field field : fields) { System.out.println("1"); if (field.isAnnotationPresent(NotNull.class)) { NotNull notnull = field .getAnnotation(NotNull.class); if (notnull.flag()) { // 如果类型是String // 如果type是类类型,则前面包含"class ",后面跟类名 if (field.getGenericType().toString().equals("class java.lang.String")) { // 拿到该属性的getet方法 Method m = this.getClass().getMethod("get" + getMethodName(field.getName())); System.out.println(field.getName()); // 调用getter方法获取属性值 String val = (String) m.invoke(this); if (val == null || val.equals("")) { throw new Exception(field.getName() + " 不能为空!"); } System.out.println("String t2ype:" + val); } else if (field.getGenericType().toString().equals("class java.lang.Integer")) { Method m = this.getClass().getMethod("get" + getMethodName(field.getName())); // 调用getter方法获取属性值 Integer val = (Integer) m.invoke(this); if (val == null) { throw new Exception(field.getName() + " 不能为空!"); } System.out.println("String ty1pe:" + val); } } } } return true; } /** * 把一个字符串的第一个字母大写、效率是最高的 */ private String getMethodName(String fildeName) throws Exception { byte[] items = fildeName.getBytes(); items[0] = (byte) ((char) items[0] - 'a' + 'A'); return new String(items); } }

    4、测试类:

    public class test { /** * @param args */ public static void main(String[] args) { Pojo pojo = new Pojo(); pojo.setName("轩"); try { boolean flag = pojo.validate(); if(flag){ System.out.println("验证通过"); }else { System.out.println("验证失败"); } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }

    5、如下图:

    6、遇到困难可以评论(有信必回)小轩微信号private_xiao_xuan

    最新回复(0)