如何让gson在json响应中避免转义json?

nvbavucw  于 2023-05-30  发布在  其他
关注(0)|答案(6)|浏览(516)

我有一个这样的响应对象:

public class TestResponse {

    private final String response;
    private final ErrorCodeEnum error;
    private final StatusCodeEnum status;

    // .. constructors and getters here
}

我使用Gson库序列化上面的类,如下所示:

Gson gson = new GsonBuilder().setPrettyPrinting().serializeNulls().create();
System.out.println(gson.toJson(testResponseOutput));

我得到的回复如下所示:

{
  "response": "{\"hello\":0,\"world\":\"0\"}",
  "error": "OK",
  "status": "SUCCESS"
}

正如你所看到的,我在"response"字段中的json字符串被转义了。有没有什么方法可以让gson不要这样做,而是返回一个完整的响应,像这样:

{
  "response": {"hello":0,"world":"0"},
  "error": "OK",
  "status": "SUCCESS"
}

还有-如果我按上面的方式做有什么问题吗?

**注意:**我的"response"字符串将始终是JSON字符串,或者它将为null,因此只有这两个值将存在于我的"response"字符串中。在"response"字段中,我可以有任何json字符串,因为这个库调用了一个可以返回任何json字符串的rest服务,所以我将其存储在字符串"response"字段中。

s5a0g9ez

s5a0g9ez1#

如果你的response字段可以是任意的JSON,那么你需要:
1.将其定义为任意JSON字段(通过将其定义为JSON层次结构的根,利用已经内置到GSON中的JSON类型系统-JsonElement

public class TestResponse {
    private final JsonElement response;
}

1.将String字段转换为适当的JSON对象表示形式。为此,您可以使用GSON的JsonParser类:

final JsonParser parser = new JsonParser();

String responseJson = "{\"hello\":0,\"world\":\"0\"}";
JsonElement json = parser.parse(responseJson); // Omits error checking, what if responseJson is invalid JSON?
System.out.println(gson.toJson(new TestResponse(json)));

这应该打印:

{
  "response": {
    "hello": 0,
    "world": "0"
  }
}

它也应该适用于任何有效的JSON:

String responseJson = "{\"arbitrary\":\"fields\",\"can-be\":{\"in\":[\"here\",\"!\"]}}";
JsonElement json = parser.parse(responseJson);
System.out.println(gson.toJson(new TestResponse(json)));

输出:

{
  "response": {
    "arbitrary": "fields",
    "can-be": {
      "in": [
        "here",
        "!"
      ]
    }
  }
}
9rbhqvlz

9rbhqvlz2#

我知道这是旧的,但只是添加一个潜在的答案,以防万一是需要的。
听起来你只想返回响应而不想逃避。转义是一件好事,它将有助于防止安全问题,并防止您的JS应用程序因错误而崩溃。
但是,如果您仍然想忽略转义,请尝试:
Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().serializeNulls().create();

carvr3hs

carvr3hs3#

添加简单的TypeAdapter并使用jsonValue(value) gson 2.8.0
版本1:

@Test
public void correctlyShow() {
    TestResponse2 src = new TestResponse2("{\"arbitrary\":\"fields\",\"can-be\":{\"in\":[\"here\",\"!\"]}}");
    Gson create = new GsonBuilder().registerTypeAdapter(String.class, ADAPTER).create();

    Stopwatch createStarted = Stopwatch.createStarted();
    String json2 = create.toJson(src);
    System.out.println(json2 + " correctlyShow4 " + createStarted.stop());
}

public class TestResponse2 {
    private final String response;

    public TestResponse2(String response) {
        this.response = response;
    }

    public String getResponse() {
        return response;
    }
}

private static final TypeAdapter<String> ADAPTER = new TypeAdapter<String>() {
    @Override
    public String read(JsonReader in) throws IOException {
        throw new UnsupportedOperationException("Unsupported Operation !!!");
    }

    @Override
    public void write(JsonWriter out, String value) throws IOException {
        out.jsonValue(value);
    }
};

...
vesrion 2

@Test
public void correctlyShow() {
    TestResponse2 src = new TestResponse2("{\"arbitrary\":\"fields\",\"can-be\":{\"in\":[\"here\",\"!\"]}}");

    String json2 = new Gson().toJson(src);
    System.out.println(json2 + " correctlyShow4 ");
}

public class TestResponse2 {
    @JsonAdapter(value = AdapterStringJson.class)
    private final String response;

    public TestResponse2(String response) {
        this.response = response;
    }

    public String getResponse() {
        return response;
    }
}

private class AdapterStringJson extends TypeAdapter<String> {
    @Override
    public String read(JsonReader in) throws IOException {
        throw new UnsupportedOperationException("Unsupported Operation !!!");
    }

    @Override
    public void write(JsonWriter out, String value) throws IOException {
        out.jsonValue(value);
    }
}
brvekthn

brvekthn4#

您应该有一个嵌套对象。

public class Response {
    private final Integer hello;
    private final String world;
}

public class TestResponse {
    private final Response response;
    private final ErrorCodeEnum error;
    private final StatusCodeEnum status;

    // .. constructors and getters here
}
c9x0cxw0

c9x0cxw05#

下面的代码是避免转义字符。使用getAsString方法。

jsonElementEntry.getValue().getAsString()

    JsonObject jsonObjectResponse = new JsonObject();
    String jsonResponseProcessed = null;
    try {
        Gson gson = new Gson();
        JsonObject jsonObject = gson.fromJson(jsonString, JsonObject.class);
        for (Map.Entry<String, JsonElement> jsonElementEntry : jsonObject.entrySet()) {
            String jsonElementEntryKey = jsonElementEntry.getKey();
            if (jsonElementEntryKey == null)    continue;
            boolean isIgnoreProperty = false;
            for (String ignorePropertyStr : IGNORE_JOB_PARAMETERS_LIST) {
                if (jsonElementEntryKey.startsWith(ignorePropertyStr)) {
                    isIgnoreProperty = true;
                    break;
                }
            }
            if (!isIgnoreProperty){
                jsonObjectResponse.addProperty(jsonElementEntryKey, jsonElementEntry.getValue().getAsString());
            }
        }
a8jjtwal

a8jjtwal6#

除了String,根据您的需要,您可以使用Map(或类似的)或嵌套的Object。这样表示应该没有问题,但在您的示例中,如果它是一个String,如果您没有转义字符(如双引号),则会出现问题。

相关问题