2013-05-09 4 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?

Я пробовал this и this. Но это не помогло.

+2

Ваш желаемый результат недействителен JSON. Если вы настаиваете на его создании, вы можете сделать это с помощью ['JSONWriter'] (http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonWriter .html), хотя, честно говоря, я не знаю, почему вы хотите генерировать синтаксически неверные данные. – Perception

+0

@Перцепция Is недействительна из-за дублирования ключей «ученик»? Или любая другая причина? – Sam

+2

Недопустимо, потому что объекты в вашем массиве JSON неправильно окружены фигурными скобками. Вы всегда можете проверить правильность своих данных с помощью онлайн-инструментов, таких как [jsonlint] (http://jsonlint.com). – Perception

ответ

4

Это

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

не является допустимым JSON (вы можете проверить это самостоятельно используя онли ne инструмент как 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, а не в массив объекта.

Я попробовал ваш код, и я получаю следующий вывод

{ "студентов": [{ "Имя": "Сэм", "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

1

Вы получаете правильный результат в соответствии с вашими классами.

У вас есть объекты, которые Student выглядеть следующим образом:

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

Это просто, объект в JSON окружен {} и содержит пары свойств/значения ...

Затем, массивы в JSON окружены [] и содержат ряд объектов/значений, разделенных запятыми. Поскольку у вас есть массив из Student, у вас есть только несколько объектов, таких как выше, разделенных запятыми, и все они окружены [].

И это именно то, что у вас есть ... все имеет смысл!

OK, вы хотите, чтобы 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}} 

Я боюсь, что ответ именно так, как вы хотите, это не представляется возможным получить (насколько я понимаю) ...

Смежные вопросы