java - 保留属性的原始 JSON 字符串

标签 java json gson

我在 Java 7 中使用 Gson 解析器。我想将我的一个属性保留为原始 JSON 字符串,以便稍后将其反序列化为所需的类。

示例输入 JSON:

{
    "foo":"bar",
    "body":["blah"]
}

{
    "foo":"bar",
    "body":{"a":"b"}
}

反序列化为这样的类:

public class Message {
    public String foo;
    public String bar; //I want this to be a raw JSON string, not parsed
}

代码:

String input = "{\"foo\":\"bar\", \"body\":[\"blah\"]}";

Message message = gson.fromJson(input, Message.class);

message.foo; //"bar"
message.body; //"[\"blah\"]"

这可能吗?

更新:

我目前正在这样做,但如果它可以“更干净”并以某种方式使用 native String 类型,那就太好了......

public class Message {
    public String foo;
    public JsonString body;
}

public static class JsonString {
    public String body;
}

public static class JsonStringDeserializer implements JsonDeserializer<JsonString> {
    @Override
    public JsonString deserialize(JsonElement json, Type type, JsonDeserializationContext context) {
        JsonString a = new JsonString();
        a.body = json.toString();
        return a;
    }
}

我不喜欢的一点是我必须像这样使用反序列化的对象:

Message message = gson.fromJson(input, Message.class);

//notice how i have to use the inner string
SomeClass cls = gson.fromJson(message.body.body, SomeClass.class);

最佳答案

如果您不介意将 body 属性声明为 Object 而不是 String 来解决 JSON 解码问题;您可以执行以下操作。

JSONRawString 的注解定义:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface JSONRawString {
}

Message 类:

public class Message {
    public String foo;

    @JSONRawString
    public Object body;
}

反序列化器:

public class JSONRawStringDeserializer<T> implements JsonDeserializer<T> {
    @Override
    public T deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
        //We decode using the normal deserializer; but will run over all the fields and check if our annotation exists. This is a bit hacky; but should work if you don't mind declaring your objects which you'd like to maintain as deserialized as Object.
        T serializedObject = new Gson().fromJson(jsonElement, type);
        Field[] fields = serializedObject.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.getAnnotation(JSONRawString.class) != null) {
                try {
                    String fieldName = field.getName();
                    if(field.getAnnotation(SerializedName.class) != null) {
                        fieldName = field.getAnnotation(SerializedName.class).value();
                    }

                    String element = new Gson().toJson(jsonElement.getAsJsonObject().get(fieldName).toString());
                    field.set(serializedObject, element);
                } catch(IllegalAccessException e) {
                    throw new JsonParseException(e);
                }
            }
        }

        return serializedObject;
    }
}

最后在 Main 中:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Main {

    public static void main(String[] args) {
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(Message.class, new JSONRawStringDeserializer<Message>())
                .create();

        String input = "{\"foo\":\"bar\", \"body\":[\"blah\"]}";

        Message message = gson.fromJson(input, Message.class);
        System.out.printf("message.foo: %s, message.body: %s", message.foo, message.body);
    }
}

导致 message.foo: bar, message.body: "[\"blah\"]"

这有点老套;因为我们覆盖了 Gson 用我们自己的方法吐出的内容;而且我认为这不是递归的。希望它能引导您找到解决方案。

关于java - 保留属性的原始 JSON 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39090341/

相关文章:

包含数组的 JavaScript map 变成包含 map 的 map

java - 使用 Java 将多行 JSON 转换为 XML

java - ToolProvider.getSystemJavaCompiler() 返回 null

java - Java中以yyyymmddhhmmss.mmm格式递增日期

java - HazelCast分布式二级缓存和更新失效

android - 使用 Retrofit 解析动态未知命名数组 Json

javascript - JavaScript 中的美化函数

javascript - JSON 数据未保存在 WebAPI 中

android - 使用GSON解析JSON

json - GSON disableHtmlEscaping - 为什么 GSON 默认情况下会转义 HTML?