2013-05-09 34 views
1

我有一个情况,我想使用GSON自定义序列化功能。如何使用GSON进行自定义序列化?

class Student{ 
    public String name; 
    public int rollNumber; 

    public Student(String name, int rollNumber){ 
     this.name = name; 
     this.rollNumber = rollNumber; 
    } 

    public int getRollNumber(){ 
     return this.rollNumber; 
    } 

    public String getName(){ 
     return this.name; 
    } 


} 
class School{ 

    public Student[] students; 

    public School(Student[] students){ 
      this.students = students; 
    } 


    public Students[] getStudents(){ 
     return this.students; 
    } 

} 

现在,当我做

private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create(); 

Student[] students = new Student[2];

students[0] = new Student("sam", 1); 

students[1] = new Student("tom", 2); 

School school = new School(students); 

GSON.toJson(school); 

我得到的输出是这样的:

[{"name":"sam","rollNumer":1},{"name":"tom","rollNumer":2}] 

但我希望它是:

["student":{"name":"sam","rollNumer":1},"student":{"name":"tom","rollNumer":2}] 

如何使用GSON自定义序列化实现此目的?

我试过thisthis。但没有多大帮助。

+2

你想要的输出是无效的JSON。如果你坚持生成它,那么你可以使用['JSONWriter'](http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonWriter .html),尽管说实话我不知道你为什么要生成语法错误的数据。 – Perception 2013-05-09 13:32:05

+0

@Perception是否因重复键“学生”而无效?或者其他原因? – Sam 2013-05-09 13:42:36

+2

这是无效的,因为你的JSON数组中的对象没有用大括号正确包围。您可以随时使用在线工具检查数据的有效性,如[jsonlint](http://jsonlint.com) – Perception 2013-05-09 13:46:11

回答

4

["student":{"name":"sam","rollNumer":1},"student":{"name":"tom","rollNumer":2}] 

不是有效的JSON(你可以用自己的验证在线工具如jsonlint)。见详情从JSON specification:对象的

定义:

一个目的是无序集合的名称/值对。一个对象以{(左大括号)开始并以}(右大括号)结束。每个名称后跟:(冒号),名称/值对由(逗号)分隔。阵列的

定义:

数组是值的有序集合。数组以[(左括号)开始,以[]结尾(右括号)。值由(逗号)分隔。一个值的

定义:

值可以是在双引号的字符串或数字,或真或假或为空,或物体或阵列。这些结构可以嵌套。

您的输出定义了一个JSON数组,但该数组中的对象没有用大括号正确包围。正确的表达应该是这样的:

[{"student":{"name":"sam","rollNumer":1}}, {"student":{"name":"tom","rollNumer":2}}] 

可与这种简单的GSON TypeAdapter产生:

class StudentAdapter extends TypeAdapter<Student> { 

    @Override 
    public void write(final JsonWriter writer, final Student student) 
      throws IOException { 
     if (student == null) { 
      writer.nullValue(); 
      return; 
     } 

     writer.beginObject(); 
     writer.name("student"); 
     writer.beginObject(); 
     writer.name("name"); 
     writer.value(student.getName()); 
     writer.name("rollNumber"); 
     writer.value(student.getRollNumber()); 
     writer.endObject(); 
     writer.endObject(); 
    } 

    @Override 
    public Student read(final JsonReader reader) throws IOException { 
     if (reader.peek() == JsonToken.NULL) { 
      reader.nextNull(); 
      return null; 
     } 

     final Student student = new Student(); 
     reader.beginObject(); 
     reader.nextName(); // discard the 'student' wrapper property 
     reader.beginObject(); 
     while (reader.hasNext()) { 
      final String attrName = reader.nextName(); 
      if ("name".equals(attrName)) { 
       student.setName(reader.nextString()); 
      } else if ("rollNumber".equals(attrName)) { 
       student.setRollNumber(reader.nextInt()); 
      } 
     } 
     reader.endObject(); 
     reader.endObject(); 

     return student; 
    } 
} 

测试方法:

@Test 
public void testWriteSchoolsAsJSONWithGsonAndCustomOutput() 
     throws Exception { 
    final Gson gson = new GsonBuilder().registerTypeAdapter(Student.class, 
      new StudentAdapter()).create(); 

    Student[] students = new Student[2]; 
    students[0] = new Student("sam", 1); 
    students[1] = new Student("tom", 2); 

    School school = new School(students); 

    final String outputJson = gson.toJson(school); 
    System.out.println(outputJson); 

    school = gson.fromJson(outputJson, School.class); 
    System.out.println(school); 
} 

和 '相关' 输出:

{"students":[{"student":{"name":"sam","rollNumber":1}},{"student":{"name":"tom","rollNumber":2}}]} 
1

首先你不能输出为[“student”:{“name”:“sam”,“rollNumer”:1},“student”:{“name”:“tom”,“rollNumer “:2}],因为你试图将对象转换成json而不是数组对象。

我想你的代码,我得到以下输出

{ “学生”:[{ “Name”: “山姆”, “rollNumber”:1},{ “名”: “汤姆”,” rollNumber“:2}]}

这里是代码:

Student[] students = new Student[2]; 

    students[0] = new Student("sam", 1); 

    students[1] = new Student("tom", 2); 

    School school = new School(students); 

    Gson gson = new GsonBuilder().disableHtmlEscaping().create(); 

    System.out.println(gson.toJson(school)); 
+0

学校有一组Student对象。 – Sam 2013-05-09 13:21:49

1

根据你的课程你会得到正确的结果。

你有对象Student看起来像这样的:

{"name":"sam", "rollNumer":1} 

很简单,在JSON对象被包围{},并包含对属性/值的...

然后,阵列,JSON被包围着[]并且包含许多用逗号分隔的对象/值。正如你有一个Student的数组,你只是有一些对象,如上面用逗号分隔的所有对象,并且全部被[]包围。

而这正是你所拥有的......一切都合情合理!

好的,你希望JSON在每个Student对象之前包含"student",但是这个字符串是什么"student"?它从何而来?事实上,在你的类的任何地方都没有这样的字符串,所以你如何让Gson(或任何库)将它包含在JSON中?

如果你真的需要这个字符串,你需要以某种方式包括在您的课,我想出的最简单的方法是有一个Map而不是数组,像这样:

public Map<String, Student> students; 

而且然后将学生添加到地图上是这样的:

Student student = new Student("sam", 1); 
students.put("student", student); 
//add other students... 

需要注意的是,现在你有串"student",与学生在地图上的键关联...

现在你将有或多或少的结果你想要的,但不完全!因为整个事情将{},而不是[]包围,因为Map是一个对象,而不是一个数组...

{"student":{"name":"sam","rollNumer":1}},{"student":{"name":"tom","rollNumer":2}} 

恐怕响应完全按照你希望它是不可能得到(据我所知)...

相关问题