使用gson从对象列表中获取JSON字符串

时间:2015-11-04 13:22:22

标签: java json rest gson

以前我的代码就是这样:

objJson = gson.toJson(objList);
return objJson;

我得到了带有该返回值的字符串JSON。

但是当JSON变得太大时,我开始出现着名的 Out Of Memory错误

然后我按照以下帖子将对象列表转换为JSON字符串,以便有效地解决OOM错误:

https://sites.google.com/site/gson/streaming

所以,我在这里采用了上述方法:

public String writeJsonStream(List<MyObj> objList) throws IOException {
    ByteArrayOutputStream baos=new ByteArrayOutputStream();
    OutputStreamWriter outputStreamWriter=new OutputStreamWriter(baos,"UTF-8");
    JsonWriter writer = new JsonWriter(outputStreamWriter);
    writer.setIndent("  ");
    writer.beginArray();
    Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create();
    for (MyObj myobj : objList) {
        gson.toJson(myobj, MyObj.class, writer);
    }

    String objJson = writer.toString();
    writer.endArray();
    writer.close();
    return objJson;
}

但是这个返回的对象com.google.gson.stream.JsonWriter@6a9454cd

方法gson.toJson(myobj, MyObj.class, writer);的类型为void,并且不会返回JSON字符串。那么在这种情况下如何获取JSON字符串呢?

3 个答案:

答案 0 :(得分:3)

那是因为你从String objJson = writer.toString();获得了JSON字符串。这不是你应该如何检索它:这段代码只会调用toString()实例上的writer方法。自此toString() is not overriden起,此结果为默认com.google.gson.stream.JsonWriter@6a9454cd

您要做的是获取JsonWriter写入输出流的字节。在您的情况下,您使用的是ByteArrayOutputStream,因此您可以调用toString(charsetName)将内容作为字符串获取:

public String writeJsonStream(List<MyObj> objList) throws IOException {
    ByteArrayOutputStream baos=new ByteArrayOutputStream();
    OutputStreamWriter outputStreamWriter=new OutputStreamWriter(baos,"UTF-8");
    JsonWriter writer = new JsonWriter(outputStreamWriter);
    writer.setIndent("  ");
    writer.beginArray();
    Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create();
    for (MyObj myobj : objList) {
        gson.toJson(myobj, MyObj.class, writer);
    }
    writer.endArray();
    writer.close();
    return baos.toString("UTF-8");
}

作为旁注,您可以改为使用StringWriter并使用toString()获取内容:

StringWriter stringWriter = new StringWriter();
JsonWriter writer = new JsonWriter(stringWriter);
// rest of code
writer.close();
String json = stringWriter.toString();

答案 1 :(得分:0)

好吧,遗憾的是,将流转换为静态对象并不能避免OOM问题。无论哪种方式,您都试图分配/请求内存来构造/写入该字符串。您必须将生成的流传输到另一个流,或者在某个循环中使用 public void actionPerformed(ActionEvent e) { JButton action = (JButton)e.getSource(); int buttin = action.getAccessibleContext().getAccessibleIndexInParent(); int row = buttin/COLS; int col = buttin%COLS; toggle(row, col ); toggle(row-1, col ); // up toggle(row+1, col ); // down toggle(row, col-1); // backward toggle(row, col+1); // forward } void toggle(int row, int col) { if (0 <= row && row < ROWS && 0 <= col && col < COLS) if (lights[row][col].getText() == "0") lights[row][col].setText("1"); else lights[row][col].setText("0"); } 来简单地使用该流中的所有数据。

答案 2 :(得分:0)

试试这个。将ByteArrayOutputStream更改为OutputStream并从System.out

获取对象
   public String writeJsonStream(List<MyObj> objList) throws IOException {
        OutputStream baos = System.out;
        OutputStreamWriter outputStreamWriter=new OutputStreamWriter(baos,"UTF-8");
        JsonWriter writer = new JsonWriter(outputStreamWriter);
        writer.setIndent("  ");
        writer.beginArray();
        Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create();
        for (MyObj myobj : objList) {
            gson.toJson(myobj, MyObj.class, writer);
        }

        String objJson = writer.toString();
        writer.endArray();
        writer.close();
        return objJson;