「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」
前言
今天在实现json返回数据时,要屏蔽掉其中的几个属性,于是我在网上查找了一下资料,只需要在相应的属性上加上@JsonIgnore
注解就可以了,或者还有一种是在实体类上加上@JsonIgnoreProperties(value={"status","updateTime"})
其中value里为要屏蔽的属性列表,我一看,这好使啊,前提是需要引入fastjson
。
Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,也可以将 JSON 字符串转换为 Java 对象。
所以我很好奇为什么一个注解就可以实现属性的屏蔽,对于java自定义注解,以前根本没用过,所以都不知道它的含义。
我打开@JsonIgnore
源代码一看,这啥呀,就这样就能实现了吗?这什么也没有啊,于是我就去学习自定义注解了。
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface JsonIgnore {
boolean value() default true;
}
写了一个小demo
使用自定义注解实现属性屏蔽
首先定义一个学生类Student
public class Student {
private String name;
private int age;
private BigDecimal account;
public Student(){
}
public Student(String name, int age, BigDecimal account) {
this.name = name;
this.age = age;
this.account = account;
}
//省略getter setter
}
注解类IgnoreFiled
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreFiled {
}
测试类:
public class Test {
public static void main(String[] args) throws IllegalAccessException {
Student student = new Student("张三",18, BigDecimal.valueOf(10000));
printIgnoreField(student);
}
public static void printIgnoreField(Object obj) throws IllegalAccessException {
StringBuilder builder = new StringBuilder();
Class<?> c = obj.getClass();
Field[] fields = c.getDeclaredFields();
String[] className = c.getName().split("\.");
builder.append(className[className.length-1]).append("{");
for(Field field:fields){ //遍历属性
field.setAccessible(true);
if(!field.isAnnotationPresent(IgnoreFiled.class)){ //如果属性上没有IgnoreFiled这个注解类,拼接字符串
builder.append(field.getName()).append("='").append(field.get(obj)).append("'").append(",");
}
}
//删掉最后一个逗号
builder.delete(builder.length()-1,builder.length());
builder.append("}");
System.out.println(builder);
}
}
我们没有在对象属性上加**@IgnoreFiled**注解前
我们在account属性上加上注解
输出
是不是很简单也很容易懂
demo说明
首先我们看自定义的注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreFiled {
}
-
@Target说明了Annotation所修饰的对象范围:在Annotation类型的声明中使用了target可更加明晰其修饰的目标,取值如下:
1.CONSTRUCTOR:用于描述构造器 2.FIELD:用于描述域 3.LOCAL_VARIABLE:用于描述局部变量 4.METHOD:用于描述方法 5.PACKAGE:用于描述包 6.PARAMETER:用于描述参数 7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
-
@Retention定义了该Annotation的生命周期,就是在什么时候有效,取值如下:
1.SOURCE:在源文件中有效(即源文件保留) 2.CLASS:在class文件中有效(即class保留) 3.RUNTIME:在运行时有效(即运行时保留)
-
@Documented – 注解是否将包含在JavaDoc中
-
@Inherited – 是否允许子类继承该注解,如果一个使用了@Inherited 修饰的annotation 类型被用于一个class,则这个annotation 将被用于该class 的子类。
然后通过反射获取Student类的属性,判断哪些属性上有我们自定义的注解,有的就不拼接,没有就拼接输出。
自定义注解的场景有很多,比如登录、权限拦截、日志、以及各种框架,常与切面编程结合,奈何我比较菜,今天的分享先到这里,每天进步一点点,相信会有质变的一天。