zoukankan      html  css  js  c++  java
  • JSON 转含有泛型属性的对象

      在将 json 字符串转为对象时,如果对象含有泛型,在进行转换时需要指明泛型类型。

    1. 对象只含有一个泛型属性时

    1.1  代码

    /**
     * @Describe:
     * @Author: chenfan
     * @Date: 2019/5/9 19:15
     */
    
    @Data
    /**
     * 含有泛型属性的对象
     */
    class OneGeneric<E>{
        E e;
        String ss;
    }
    
    @Data
    /**
     * 泛型对象
     */
    class KeyMessage{
        String kk;
    }
    
    public class JsonTest {
    
        public static void main(String[] args) {
    
            // {"e": {"kk":"qwe"},"ss": "ssValue"}
            String data = "{"e": {"kk":"qwe"},"ss": "ssValue"}";
            Gson gson = new Gson();
            //  OneGeneric : 外层对象类型    KeyMessage :嵌套的泛型类型
            OneGeneric one = gson.fromJson(data, new TypeToken<OneGeneric<KeyMessage>>() {}.getType());
            System.out.println(one);
        }
    
    }

    1.2  运行结果

    正确转换如下:

    1.3 泛型属性为集合类型时

      此时和只有一个泛型对象时处理方式一样

    public class JsonTest {
    
        public static void main(String[] args) {
            // {"ss": "ssValue","list":[{"dd":"dd1"},{"dd":"dd2"}]}
            String data = "{"ss": "ssValue","list":[{"dd":"dd1"},{"dd":"dd2"}]}";
            Gson gson = new Gson();
            OneGeneric grandMessage = gson.fromJson(data, new TypeToken<OneGeneric<Generic>>() {}.getType());
            System.out.println(grandMessage);
        }
    }
    
    /**
     * 含有泛型属性的对象
     */
    @Data
    class OneGeneric<E>{
        List<E> list;
        String ss;
    }
    
    @Data
    class Generic{
        String dd;
    }

    2. 对象只含有多个泛型属性时

    2.1 代码

    /**
     * @Describe:
     * @Author: chenfan
     * @Date: 2019/5/9 19:15
     */
    
    @Data
    /**
     * 含有多个泛型属性的对象
     */
    class GrandMessage<K,V>{
    
        K key;
        V value;
    }
    
    /**
     * 泛型对象
     */
    @Data
    class KeyMessage{
        String kk;
    }
    
    /**
     * 泛型对象
     */
    @Data
    class ValueMessage{
        String vv;
    }
    
    /**
     * 测试类
     */
    public class JsonTest {
    
        public static void main(String[] args) {
            // {"key": {"kk":"qwe"},"value": {"vv":"asd"}}
            String data = "{"key": {"kk":"qwe"},"value": {"vv":"asd"}}";
            Gson gson = new Gson();
            GrandMessage grandMessage = gson.fromJson(data, new TypeToken<GrandMessage<KeyMessage,ValueMessage>>() {}.getType());
            System.out.println(grandMessage);
        }
    }

    2.2 运行结果

    2.3 泛型的顺序问题

      在进行对象转换时, TypeToken<GrandMessage<KeyMessage,ValueMessage>> 中的泛型类型顺序必须按照 GrandMessage<K,V> 中声明的顺序,否则会对象属性全部为null

    3. 泛型类型嵌套

    3.1 代码

    @Data
    class GrandMessage<K>{
    
        K k;
        String msg;
    }
    @Data
    class OneGeneric<E>{
        E e;
        String one;
    }
    
    @Data
    class Generic{
        String dd;
    }
    
    /**
     * 测试类
     */
    public class JsonTest {
    
        public static void main(String[] args) {
            // {"msg":"lili","k":{"one":"111","e":{"dd":"dddd"}}}
            String data = "{"msg":"lili","k":{"one":"111","e":{"dd":"dddd"}}}";
            Gson gson = new Gson();
            // 转换时的泛型顺序一定要严格按照对象的嵌套顺序
            GrandMessage grandMessage = gson.fromJson(data, new TypeToken<GrandMessage<OneGeneric<Generic>>>() {}.getType());
            System.out.println(grandMessage);
        }
    }

    3.2 运行结果

    4. 自定义转换逻辑

      JSON转对象时,如果对象某个属性不确定(比如对象定义为Object,实际为 int 类型),需要自定义转换逻辑

      显示指定  OpSessionControlMessage 的 messageId 为 int 类型:

        private static Gson gson2 = new GsonBuilder()
                .registerTypeAdapter(
                        new TypeToken<OpSessionControlMessage>(){}.getType(),
                        new JsonDeserializer<OpSessionControlMessage>() {
                            @Override
                            public OpSessionControlMessage deserialize(
                                    JsonElement json, Type typeOfT,
                                    JsonDeserializationContext context) throws JsonParseException {
    
                                OpSessionControlMessage message = new OpSessionControlMessage();
                                JsonObject jsonObject = json.getAsJsonObject();
                                Set<Map.Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
                                for (Map.Entry<String, JsonElement> entry : entrySet) {
                                    Object ot = entry.getValue();
                                    if(entry.getKey().equals("messageId")){
                                        message.setOpType(((JsonPrimitive) ot).getAsInt());
                                    }
                                }
                                return message;
                            }
                        }).create();

  • 相关阅读:
    python之路-day31-守护进程、锁、队列、生产者消费者模型
    python之路-day30-进程
    python之路-day26 初探网络编程
    python之路-day25-包
    python之路-day21-模块介绍1
    python之路-day19-面向对象之约束
    递归格式模板
    java创建一个窗体
    异常throws关键字 异常throw关键字
    多个catch块
  • 原文地址:https://www.cnblogs.com/virgosnail/p/10840738.html
Copyright © 2011-2022 走看看