【问题标题】:GSON custom serializer for an object with a Collection field具有 Collection 字段的对象的 GSON 自定义序列化程序
【发布时间】:2015-05-04 13:05:09
【问题描述】:

我有以下架构:

public class Student {
    String name;
    List<Integer> sequence;
}

我需要 Student 对象的 Json

{
    name : "Bruce"
    sequence : {
         index_0 : 5
         index_1 : 2
         index_2 : 7
         index_3 : 8
    }
}

The documentation 没有明确说明如何为集合编写序列化程序。

【问题讨论】:

    标签: java json serialization collections gson


    【解决方案1】:

    您可以创建一个TypeAdapter,类似于:

    public static class StudentAdapter extends TypeAdapter<Student> {
        public void write(JsonWriter writer, Student student)
                throws IOException {
            if (student == null) {
                writer.nullValue();
                return;
            }
            writer.beginObject();
    
            writer.name("name");
            writer.value(student.name);
    
            writer.name("sequence");
            writeSequence(writer, student.sequence);
    
            writer.endObject();
        }
    
        private void writeSequence(JsonWriter writer, List<Integer> seq)
                throws IOException {
            writer.beginObject();
            for (int i = 0; i < seq.size(); i++) {
                writer.name("index_" + i);
                writer.value(seq.get(i));
            }
            writer.endObject();
        }
    
        @Override
        public Student read(JsonReader in) throws IOException {
            // This is left blank as an exercise for the reader
            return null;
        }
    }
    

    然后注册到

    GsonBuilder b = new GsonBuilder();
    b.registerTypeAdapter(Student.class, new StudentAdapter());
    Gson g = b.create();
    

    如果您使用示例学生运行此程序:

    Student s = new Student();
    s.name = "John Smith";
    s.sequence = ImmutableList.of(1,3,4,7); // This is a guava method
    System.out.println(g.toJson(s));
    

    输出:

    {"name":"John Smith","sequence":{"index_0":1,"index_1":3,"index_2":4,"index_3":7}}
    

    【讨论】:

    • //这留空,作为读者的练习......很好:) @durron597
    • @Kaushik 好吧,他只问如何序列化,而不是反序列化:-)
    【解决方案2】:

    GSON 支持自定义FieldNamingStrategy

    new GsonBuilder().setFieldNamingStrategy(new FieldNamingStrategy() {
        @Override
        public String translateName(java.lang.reflect.Field f) {
            // return a custom field name
        }
    });
    

    但是这显然不包括你的情况,我能想到的一个简单的解决方法是让你的 sequence 列表 transient 并有一个 实际 序列使用 GSON 的更正数据映射:

    public class Student {
        String name;
        transient List<Integer> sequenceInternal;
        Map<String, Integer> sequence;
    }
    

    并且每当您的 sequenceInternal 对象发生更改时,将更改写入序列映射。

    【讨论】:

      猜你喜欢
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 2014-09-16
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-16
      相关资源
      最近更新 更多