美文网首页
FastJSON解析-----@JSONField注解详解

FastJSON解析-----@JSONField注解详解

作者: 周蛋蛋 | 来源:发表于2019-08-20 14:53 被阅读0次

    为什么今天要提到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即可

    image.png

    输出结果,前后对比,names不见了

    image.png
    如果我在反序列化的时候想过滤掉呢?如下:

    @JSONField(deserialize = false)

    如果我在序列化的时候想输出日期格式怎么办?如下:

    @JSONField(format = "yyyy-MM-dd")

    如果我想在生成json或者解析json时获得的对象名字前面都加上"大爷怎么办"呢?这就需要具体的定制了.下面是解析和生成结合到了一起


    deserializeUsing //自定反序列化类,必须是静态类。实现ObjectDeserializer接口,不是静态类的话我测试了会错误

    image.png

    相关文章

      网友评论

          本文标题:FastJSON解析-----@JSONField注解详解

          本文链接:https://www.haomeiwen.com/subject/ywdusctx.html