具有 Collection 字段的对象的 GSON 自定义序列化程序
GSON custom serializer for an object with a Collection field
我有以下架构:
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没有明确说明如何为集合编写序列化程序。
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
对象发生变化时,将变化写入序列映射。
您可以创建一个 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}}
我有以下架构:
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没有明确说明如何为集合编写序列化程序。
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
对象发生变化时,将变化写入序列映射。
您可以创建一个 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}}