Q:

How to do Custom Serialization using GSON?

I have a case where I would like to use GSON custom serialization feature.
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;
   }

}

Now when I do
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);

I get output like this:
[{"name":"sam","rollNumer":1},{"name":"tom","rollNumer":2}]

But I want it to be :
["student":{"name":"sam","rollNumer":1},"student":{"name":"tom","rollNumer":2}]

How do I achieve this using GSON custom serialization?
I have tried this and this. But did not help much.

A:

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

is not valid JSON (you can verify it yourself using an online tool like jsonlint). See details from the JSON specification:
Definition of an object:

An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).

Definition of an array:

An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).

Definition of a value:

A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.

Your output defines a JSON array, but the objects in that array aren't properly surrounded with braces. A correct representation would look like this:
[{"student":{"name":"sam","rollNumer":1}}, {"student":{"name":"tom","rollNumer":2}}]

Which can be generated with this simple 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 method:
@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);
}

And 'relevant' output:
{"students":[{"student":{"name":"sam","rollNumber":1}},{"student":{"name":"tom","rollNumber":2}}]}

