防止GSON序列化JSON字符串

qlckcl4x  于 2022-11-06  发布在  其他
关注(0)|答案(3)|浏览(204)

我是gson的新手,有一些纽比问题我还没有找到答案,所以请耐心等待。StackOverflow和google不是我的朋友:(
我有一个java类“User”,它的一个属性“externalProfile”是一个包含已经序列化的JSON的Java字符串。当gson序列化User对象时,它会将externalProfile视为原语,从而通过添加额外的斜杠等来转义JSON。我希望gson不去管这个字符串,只是“按原样”使用它,因为它已经是有效的和可用的JSON。
为了区分JSON字符串,我创建了一个名为JSONString的简单类,并且我尝试使用reader/writers,registerTypeAdapter,但是没有任何效果。您能帮我吗?

public class User {
    private JSONString externalProfile;
    public void setExternalProfile(JSONString externalProfile) { this.externalProfile = externalProfile; }

}

public final class JSONString {
    private String simpleString;
    public JSONString(String simpleString) { this.simpleString = simpleString; }
}

public customJsonBuilder(Object object) {
    GsonBuilder builder = new GsonBuilder();
        builder.registerTypeAdapter(GregorianCalendar.class, new JsonSerializer<GregorianCalendar>() {
            public JsonElement serialize(GregorianCalendar src, Type type, JsonSerializationContext context) {
                if (src == null) {
                    return null;
                }
                return new JsonPrimitive(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(src.getTime()));
            }
        });
        Gson gson = builder.create();
        return gson.toJson(object);
}

作为一个例子,externalProfile将保存(作为字符串值):

{"profile":{"registrationNumber": 11111}}

在我将它作为JSONString存储在User对象中之后,我们将用户对象转换为JSON:

User user = new User();
user.setExternalProfile(new JSONString(externalProfile)),  
String json = customJsonBuilder(user);

json将保存如下内容:

{\"profile\":{\"registrationNumber\": 11111}}

因此,gson将externalProfile JSONString序列化为String原语,并在双引号前添加额外的斜杠。我希望gson保持此JSONString不变,因为它已经是可用的JSON。我正在寻找一个类型适配器/读写器来完成此操作,但我无法让它工作。

pnwntuvh

pnwntuvh1#

正如Alexis C所说:
首先将外部配置文件存储为JsonObject:

new Gson().fromJson(externalProfile, JsonObject.class));

当输出User对象时,让gson再次序列化它。将产生完全相同的JSON!

hjzp0vay

hjzp0vay2#

我解决了这个问题,没有不必要的反序列化-序列化。

public class RawJsonGsonAdapter extends TypeAdapter<String> {

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

    @Override
    public String read(final JsonReader in) throws IOException {
        return null; // Not supported
    }
}

并在需要时通过注解使用它。例如:

public class MyPojo {
    @JsonAdapter(RawJsonGsonAdapter.class)
    public String someJsonInAString;

    public String normalString;
}

就这样,把Gson当成平常一样.

qyuhtwio

qyuhtwio3#

添加read方法。

public class RawJsonGsonAdapter extends TypeAdapter<String> {

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

    @Override
    public String read(final JsonReader in) throws IOException {
        var sb = new StringBuilder();
        int n = 0;
        while (true) {    
            switch (in.peek()) {
            case BEGIN_ARRAY:
                in.beginArray();
                sb.append("[");
                break;
            case BEGIN_OBJECT:
                in.beginObject();
                sb.append("{");
                n++;
                break;
            case BOOLEAN:
                sb.append(in.nextBoolean()).append(",");
                break;
            case END_ARRAY:
                dropLastComma(sb);
                in.endArray();
                sb.append("]");
                break;
            case END_DOCUMENT:
                throw new RuntimeException("END_DOCUMENT invalid here");
            case END_OBJECT:
                dropLastComma(sb);
                in.endObject();
                sb.append("}");
                if (--n == 0)
                    return sb.toString();
                break;
            case NAME:
                sb.append("\"").append(in.nextName()).append("\":");
                break;
            case NULL:
                in.nextNull();
                sb.append("");
                break;
            case NUMBER:
                try {
                    sb.append(in.nextInt()).append(",");
                    break;
                } catch (Exception e1) {
                    try {
                        sb.append(in.nextLong()).append(",");
                        break;
                    } catch (Exception e2) {
                        sb.append(in.nextDouble()).append(",");
                        break;
                    }
                }
            case STRING:
                sb.append("\"").append(in.nextString()).append("\",");
                break;
            }
        }
    }

    private void dropLastComma(StringBuilder sb) {
        if (sb.charAt(sb.length() - 1) == ',') {
            sb.setLength(sb.length() - 1);
        }
    }
}

相关问题