gson.toJson(jObj)stackoverflowerror .TypeAdapters $ 25.write(TypeAdapters.java:704)

时间:2013-06-09 14:02:35

标签: java json gson

我正在尝试使用gson将json对象转换为String。以下是代码

List<Student> studs = //from db
        int count = studs.size();
        Integer tot_pages= count/limit;
        if(page>tot_pages){
            page=tot_pages;
        }
        Integer start=limit*page-limit;
        Gson gson = new Gson();
        JsonObject jObj= new JsonObject();
        jObj.addProperty("page", page);
        jObj.addProperty("total",tot_pages);
        jObj.addProperty("records",count);
        JsonArray cell = new JsonArray();
        JsonArray rows = new JsonArray();
        JsonObject row= new JsonObject();
        for(Student stud: studs){
            row= new JsonObject();
            row.addProperty("id", stud.getId());
            cell=new JsonArray();
            JsonPrimitive name = new JsonPrimitive(stud.getName());
            JsonPrimitive rollno = new JsonPrimitive(stud.getRollno());
            JsonPrimitive yr = new JsonPrimitive(stud.getYr());
            cell.add(name);
            cell.add(rollno);
            cell.add(yr);
            row.add("cell", row);
            rows.add(row);
            System.out.println(stud.getId());
        }
        System.out.println("done");

        jObj.add("rows", rows);
        System.out.println("done1");
        return gson.toJson(jObj);

并获得以下错误

  

引起:java.lang.StackOverflowError at   java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:416)     在java.lang.StringBuffer.append(StringBuffer.java:237)at   java.io.StringWriter.write(StringWriter.java:101)at   com.google.gson.stream.JsonWriter.string(JsonWriter.java:534)at at   com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:402)     在com.google.gson.stream.JsonWriter.value(JsonWriter.java:495)at   com.google.gson.internal.bind.TypeAdapters $ 25.write(TypeAdapters.java:686)     在   com.google.gson.internal.bind.TypeAdapters $ 25.write(TypeAdapters.java:704)     在   com.google.gson.internal.bind.TypeAdapters $ 25.write(TypeAdapters.java:704)     在   com.google.gson.internal.bind.TypeAdapters $ 25.write(TypeAdapters.java:704)     在   com.google.gson.internal.bind.TypeAdapters $ 25.write(TypeAdapters.java:704)     在   com.google.gson.internal.bind.TypeAdapters $ 25.write(TypeAdapters.java:704)     在   com.google.gson.internal.bind.TypeAdapters $ 25.write(TypeAdapters.java:704)&lt; -----此行重复多次。

请某人帮助我。

1 个答案:

答案 0 :(得分:3)

变化:

row.add("cell", row);

要:

row.add("cell", cell);

另一方面,Gson对象非常强大,应该能够在没有您现在使用的所有手动代码的情况下序列化学生列表。最糟糕的是,您应该考虑为您的学生班级创建TypeAdapter,将其注册到Gson,并将其序列化为列表:

假设学生班:

public class Student implements Serializable {
    private static final long serialVersionUID = 1L;

    private String ssn;
    private String schoolId;
    private String firstName;
    private String middleName;
    private String lastName;
    private Calendar enrollDate;

    // Constructors, getters/setters

    @Override
    public String toString() {
        return String.format("Student[%s,%s (%s)]", getLastName(),
                getFirstName(), getSchoolId());
    }
}

对应的适配器:

public class StudentAdapter extends TypeAdapter<Student> {

    public StudentAdapter() {
        super();
    }

    @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();
        while (reader.hasNext()) {
            final String name = reader.nextName();
            if ("firstName".equals(name)) {
                student.setFirstName(reader.nextString());
            } else if ("lastName".equals(name)) {
                student.setLastName(reader.nextString());
            } else if ("schoolId".equals(name)) {
                student.setSchoolId(reader.nextString());
            }
        }
        reader.endObject();

        return student;
    }

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

        writer.beginObject();
        writer.name("firstName");
        writer.value(student.getFirstName());
        writer.name("lastName");
        writer.value(student.getLastName());
        writer.name("schoolId");
        writer.value(student.getSchoolId());
        writer.endObject();
    }
}

测试代码:

final List<Student> origStudentList = Arrays.asList(new Student(
        "B12J9", "Samantha", "Cole"), new Student("A09K2", "Adebisi",
        "Onihan"), new Student(null, "Miguel", "Rodriguez"));

final Gson gson = new GsonBuilder().registerTypeAdapter(Student.class,
        new StudentAdapter()).create();

final String json = gson.toJson(origStudentList);
System.out.println(json);

final List<Student> unmarshalledStudentList = gson.fromJson(json,
        new TypeToken<List<Student>>() {
        }.getType());
System.out.println(unmarshalledStudentList);

在上面的示例中,我已经说明了如何创建一个适配器,该适配器仅选择性地序列化假设schoolId对象的firstNamelastNameStudent属性。您可以将此作为起点,并且在Javadoc I链接中还有其他类型适配器示例。