Fastjson妙⽤之@JSONField注解
在开发的过程中使⽤json格式的地⽅⾮常多,现在前后端分离的项⽬中,前后端数据交换的格式⼀般为json,这种格式的优/缺点这⾥不再赘述,感兴趣的可以百度。把java中的实体类序列化为json的⽅式也有很多⽅式,今天来看看常⽤到的fastjson。
都知道fastjson是阿⾥开源的⼀个序列化/反序列化的jar包,在⽇常的开发过程中经常会碰到,也是使⽤频率较⾼的⼀款⼯具。
fastjson怎么用这⾥要了解⼀个概念,那就是序列化/反序列化,序列化是把⼀个java对象转化为其他的形式,如json、XML、对象字节;反序列化则是把json、XML、对象字节转化为java对象。
⼀、初始Fastjson
1、环境搭建
要想使⽤fastjson,⾸先需要引⼊fastjson的包,我这⾥使⽤的是maven⼯具,所以这⾥只要在pom⽂件中添加相应的依赖即可,
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
2、⼀个⼩例⼦
有⼀个实体类,
package st;
import lombok.Data;
@Data
public class Student {
private Integer id;
private String name;
private String address;
private String phoneNumber;
}
下⾯看测试⽅法
package st;
import com.alibaba.fastjson.JSON;
slf4j.Slf4j;
@Slf4j
public class TestFastJson {
public static void main(String[] args) {
Student student=new Student();
student.setId(1);
student.setName("tom");
student.setAddress("beijing");
student.setPhoneNumber("010-*******");
//把对象转化为json串
String JSONString(student);
log.info("student序列化为:{}",jsonString);
}
}
下⾯看测试结果
22:22:41.657 [main] INFO st.TestFastJson - student序列化为:{"address":"beijing","id":1,"name":"tom","phoneNumber":"010-*******"}
Process finished with exit code 0
从上⾯可以看到打印除了序列化为json的字符串,这⾥是⼀个序列化的过程,当然也可以把⼀个字符串反序列化为java对象。
⼆、@JSONField注解
在上⾯的例⼦中,student被序列化为⼀个json字符串,字符串是键值对的形式,键是Student的属性名。
现在有这样的⼀个需求,要返回给前端Student的json字符串,但不想给前端phoneNumber字段,你要怎么做那?⼀个⽐较容易想到的⽅式是从字符串中把这个属性去掉,或者重新⽣成⼀个不包含phoneNumber的实体对象。难道没有更好的⽅式么
在fastjson提供了@JSONField这样⼀个注解。
1、@JSONField(serialize = false)
@JSONField注解中有seaialize这样⼀个属性,看名称应该和序列化有关,尝试下看看效果,
package st;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
@Data
public class Student {
private Integer id;
private String name;
private String address;
@JSONField(serialize = false)
private String phoneNumber;
}
再看上⾯的测试类的执⾏结果,
22:30:26.678 [main] INFO st.TestFastJson - student序列化为:{"address":"beijing","id":1,"name":"tom"}
Process finished with exit code 0
可以看到轻轻松松phoneNumber不见了,也就是说@JSONField(serialize=false)起作⽤了,该属性不会参与序列化,反之,不加该注解或serialize的值设为true,则会参与序列化。
2、@JSONField(name= "XXX")
在和前端的交互过程中,可能存在这样的情况,java类中定义的字段的形式为驼峰,但前端需要的是以_连接的形式,要怎么做那,在
@JSONField中有name属性,
package st;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
@Data
public class Student {
private Integer id;
private String name;
private String address;
@JSONField(name = "phone_number")
private String phoneNumber;
}
在phoneNuber上注解@JSONField且name为phone_number,看测试结果,
21:47:48.766 [main] INFO st.TestFastJson - student序列化为:{"address":"beijing","id":1,"name":"tom","phone_number":"010-*******"}
可以看到在序列化的json字符串中出现了phone_number,说明@JSONField起了作⽤,在序列化的时候指定序列化字段的名称,如果指定了使⽤指定的(@JSONField中name的值),如果不指定使⽤java类中属性的名字。
3、@JSONField注解
在上⾯,我们看了@JSONField的两种⽤法,还有很多⽤法,这⾥不⼀⼀列举,看下@JSONField这个注解的定义,
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.alibaba.fastjson.annotation;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
public @interface JSONField {
int ordinal() default 0;
String name() default "";
String format() default "";
boolean serialize() default true;
boolean deserialize() default true;
SerializerFeature[] serialzeFeatures() default {};
Feature[] parseFeatures() default {};
String label() default "";
boolean jsonDirect() default false;
Class<?> serializeUsing() default Void.class;
Class<?> deserializeUsing() default Void.class;
String[] alternateNames() default {};
boolean unwrapped() default false;
String defaultValue() default "";
}
在这个注解上使⽤了@Target注解标注,@Target中的值为{ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER},也就是说@JSONField可以标注在⽅法上、字段、参数上。在上⾯的例⼦中,我们把@JSONField⽤在了字段上,下⾯看使⽤在⽅法上的例⼦,在⼀个类中有getXXX/setXXX⽅法,看@JSONField⽤在getXXX/setXXX的⽤法。
package st;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
@Data
public class Student {
private Integer id;
private String name;
private String address;
private String phoneNumber;
//getXXX⽅法⽤在序列化过程中
@JSONField(serialize = false)
public String getPhoneNumber() {
return phoneNumber;
}
//setXXX⽅法⽤在反序列化过程中
@JSONField(deserialize = false)
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
看测试结果
21:59:28.334 [main] INFO st.TestFastJson - student序列化为:{"address":"beijing","id":1,"name":"tom"}
再来看反序列化的测试结果,测试类,
package st;
import com.alibaba.fastjson.JSON;
slf4j.Slf4j;
@Slf4j
public class TestFastJson {
public static void main(String[] args) {
Student student=new Student();
student.setId(1);
student.setName("tom");
student.setAddress("beijing");
student.setPhoneNumber("010-*******");
//把对象转化为json串
String JSONString(student);
log.info("student序列化为:{}",jsonString);
//反序列化
String str="{\"address\":\"beijing\",\"id\":1,\"name\":\"tom\",\"phoneNumber\":\"010-*******\"}";
Student stu=JSON.parseObject(str,Student.class);
log.info("反序列化的结果:{}",stu);
}
}
使⽤了含有phoneNumber的字符串,看反序列化的结果,
22:04:04.746 [main] INFO st.TestFastJson - student序列化为:{"address":"beijing","id":1,"name":"tom"}
22:04:04.776 [main] INFO st.TestFastJson - 反序列化的结果:Student(id=1, name=tom, address=beijing, phoneNumber=null)
可以看到phoneNumber的值为null,证明该属性未取得反序列化的值,证明了@JSONField⽤在setXXX⽅法上起到了反序列化的控制作⽤。
三、总结
本⽂分享了fastjson中@JSONField的⽤法,主要是在序列化/反序列化的过程中,主要体现在以下⼏个⽅⾯,
1、@JSONField⽤在字段上影响序列化/反序列化两个过程;
2、@JSONField⽤在setXXX、getXXX⽅法上,分别影响反序列化、序列化过程;
有不正指出,欢迎指正!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论