FastJSON解析-----@JSONField注解详解
为什么今天要提到FastJson注解的这个属性,我说一下一个场合大家就明白了,你将一个功能开发完毕以后,数据适配完毕,但是后台人员忽然告诉你,后台的返回报文字段名字要做修改,你如果没有遇到这个属性之前,心中千万句草拟马略过,因为要重新去屑bean对象,重新系列,重新获取;但是遇到这个以后,心中不愿意,但是微微一下,点点头告诉他;可以
序列化和反序列化
众所周知,类的对象会随着程序的终止而被垃圾收集器销毁。如果要在不重新创建对象的情况下调用该类,该怎么做?这就可以通过序列化将数据转换为字节流。
- 序列化
对象序列化的最主要的用处就是在传递和保存对象的时候,保证对象的完整性和可传递性。序列化是把对象转换成有序字节流,以便在网络上传输或者保存在本地文件中。序列化后的字节流保存了Java对象的状态以及相关的描述信息。序列化机制的核心作用就是对象状态的保存与重建。 - 反序列化
客户端从文件中或网络上获得序列化后的对象字节流后,根据字节流中所保存的对象状态及描述信息,通过反序列化重建对象。
本质上讲,序列化就是把实体对象状态按照一定的格式写入到有序字节流,反序列化就是从有序字节流重建对象,恢复对象状态。
package com.java;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* 序列化对象
* @author -zhengzx-
*
*/
public class Player implements Serializable{
/**
*
*/
private static final long serialVersionUID = -5248069984631225347L;
public Player(long playerId, int age, String name) {
this.playerId = playerId;
this.age = age;
this.name = name;
}
private long playerId;
private int age;
private String name;
private List<Integer> skills = new ArrayList<>();
public long getPlayerId() {
return playerId;
}
public void setPlayerId(long playerId) {
this.playerId = playerId;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Integer> getSkills() {
return skills;
}
public void setSkills(List<Integer> skills) {
this.skills = skills;
}
}
【1】:对象序列化代码如下,具体细节注释说明:Java中通过对象流 ObjectOutputStream 进行序列化。
【2】:反序列化为对象,具体细节注释说明:Java中通过对象流 ObjectInputStream 进行序列化。
package com.java;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
/**
* Description:序列化与反序列化
* @author zhengzx
*/
public class JavaSerialize {
public static void main(String[] args) throws Exception {
Player player = new Player(10001, 21, "teacher");
player.getSkills().add(10001);
//序列化
byte[] bytes = toBytes(player);
//反序列化
toPlay(bytes);
}
/**
* Title: toBytes
* Description:序列化对象
* @author zhengzx
* @throws Exception
*/
public static byte[] toBytes(Object out) throws Exception {
//用于序列化后存储对象
ByteArrayOutputStream byteArrayOutputStream = null;
//java序列化API
ObjectOutputStream objectOutputStream = null;
try {
byteArrayOutputStream = new ByteArrayOutputStream();
objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
//将out对象进行序列化
objectOutputStream.writeObject(out);
//测试验证输入(获取字节数组)
byte[] bs = byteArrayOutputStream.toByteArray();
//将数组转化为字符串输入
System.out.println(Arrays.toString(bs));
return bs;
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭最外层的流(内部流会自动关闭)
objectOutputStream.close();
}
return null;
}
/*
* Title: toPlay
* Description:反序列化对象
* @author zhengzx
* @throws Exception
*/
public static void toPlay(byte[] bs) throws Exception {
//创建存放二进制数据的API
ByteArrayInputStream byteArrayInputStream = null;
//创建反序列化对象
ObjectInputStream objectInputStream = null;
try {
byteArrayInputStream = new ByteArrayInputStream(bs);
objectInputStream = new ObjectInputStream(byteArrayInputStream);
//校验测试
Player player = (Player) objectInputStream.readObject();
System.out.println(player.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
objectInputStream.close();
}
}
}
输出结果
image.png
fastjson编程式如何使用以及痛点
一般最常见的是这两个方法:
JSON.toJSONString(object):序列化对象,生产字符串
JSON.parse(text):反序列化对象,字符串转json
几个属性
- name
- format,
- serialize
- deserialize
- serializeUsing,
- deserializeUsing
public class TestBean {
/**
* result : 000000
* message : 请求成功!
* data : [{"id_number":"61042319","if_select":"0","names":"王引"},{"id_number":"1307309337","if_select":"0","names":"张灵狐"},{"id_number":"610404201109216027","if_select":"0","names":"华怡涵"},{"id_number":"370213194506033833","if_select":"0","names":"哈士奇"},{"id_number":"610404201504165039","if_select":"0","names":"杜锦尚"},{"id_number":"610121197005181908","if_select":"0","names":"齐军平"},{"id_number":"610402198511287002","if_select":"户籍地址不在服务包发布范围,不能进行签约!","names":"赵纳"},{"id_number":"610404197010155544","if_select":"户籍地址不在服务包发布范围,不能进行签约!","names":"姚爱玲"},{"id_number":"61040419941123551X","if_select":"户籍地址不在服务包发布范围,不能进行签约!","names":"郭路裕"},{"id_number":"61040419490705551X","if_select":"户籍地址不在服务包发布范围,不能进行签约!","names":"王建业"},{"id_number":"610402197504306100","if_select":"户籍地址不在服务包发布范围,不能进行签约!","names":"曹锋利"},{"id_number":"610404195506205526","if_select":"户籍地址不在服务包发布范围,不能进行签约!","names":"边淑会"},{"id_number":"610404200402015019","if_select":"户籍地址不在服务包发布范围,不能进行签约!","names":"杜尚"},{"id_number":"610121194201041570","if_select":"户籍地址不在服务包发布范围,不能进行签约!","names":"曹志政"},{"id_number":"610404200710135522","if_select":"户籍地址不在服务包发布范围,不能进行签约!","names":"郭栩彤"},{"id_number":"61040419720408553X","if_select":"户籍地址不在服务包发布范围,不能进行签约!","names":"郭群利"},{"id_number":"610404194611085525","if_select":"户籍地址不在服务包发布范围,不能进行签约!","names":"司淑云"},{"id_number":"610404197604195017","if_select":"已加入购物车,不能重复操作!","names":"杜龙"}]
*/
private String result;
private String message;
private List<DataBean> data;
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<DataBean> getData() {
return data;
}
public void setData(List<DataBean> data) {
this.data = data;
}
public static class DataBean {
/**
* id_number : 61042319871110302X
* if_select : 0
* names : 王引
*/
private String id_number;
private String if_select;
private String names;
public String getId_number() {
return id_number;
}
public void setId_number(String id_number) {
this.id_number = id_number;
}
public String getIf_select() {
return if_select;
}
public void setIf_select(String if_select) {
this.if_select = if_select;
}
public String getNames() {
return names;
}
public void setNames(String names) {
this.names = names;
}
}
}}
测试:
这样去写只是证明了序列化成功了:
public class Main2Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
String json = "{\n" +
" \"data\": [\n" +
" {\n" +
" \"id_number\": \"61042319\",\n" +
" \"if_select\": \"0\",\n" +
" \"names\": \"王引\"\n" +
" },\n" +
" {\n" +
" \"id_number\": \"1307309337\",\n" +
" \"if_select\": \"0\",\n" +
" \"names\": \"张灵狐\"\n" +
" }\n" +
" ],\n" +
" \"message\": \"请求成功!\",\n" +
" \"result\": \"000000\"\n" +
"}";
TestBean testBean = JSON.parseObject(json, TestBean.class);
Log.e("string",JSON.toJSONString(testBean));
}
}
输出,证明了我们序列化成功了
image.png假设现在我们后台的报文将"id_number"返回值变为"number";我们来看输出结果
image.png
输出报Json的异常,那么我们这种情况下应该使用name这个属性了
image.png打印结果,报文正常输出,显示后台最新的报文
image.png
如果我还想将name放到前面形成{"names":"张灵狐","number":"1307309337"}这样呢?如下即可,ordinal是用来排序的.
image.png我们配置了names为0,number为1,来一起看输出顺序,前后两次的顺序就很明显
image.png如果我在序列化的时候想过滤掉name这个字段怎么做呢?使用serialize即可
输出结果,前后对比,names不见了
image.png如果我在反序列化的时候想过滤掉呢?如下:
@JSONField(deserialize = false)
如果我在序列化的时候想输出日期格式怎么办?如下:
@JSONField(format = "yyyy-MM-dd")
如果我想在生成json或者解析json时获得的对象名字前面都加上"大爷怎么办"呢?这就需要具体的定制了.下面是解析和生成结合到了一起
坑
deserializeUsing //自定反序列化类,必须是静态类。实现ObjectDeserializer接口,不是静态类的话我测试了会错误