java 用GSON反序列化带有字段类型容器的json

snvhrwxg  于 2023-02-28  发布在  Java
关注(0)|答案(3)|浏览(129)

我有一个带有字段类型容器的json,如

var inputJson = """
                {
                    "stringField1": {
                        "string": "stringField1Value"
                    }
                }
                """;

我还有课

package model;

import lombok.Data;

@Data
public class SimpleClass {
    private Long longField;
    private String stringField1;
    private String stringField2;
}

我怎样用GSON把这个json反序列化为SimpleClass?Gson或者GsonBuilder有默认设置吗?
我尝试配置GsonBuilder,但失败

t1rydlwq

t1rydlwq1#

默认情况下,Gson会使用反射将JSON对象的字段Map到Java对象的字段。但是,在您的示例中,JSON对象有一个字段是容器,无法直接Map到Java对象中的String字段。要处理此问题,您需要为stringField1字段创建一个自定义反序列化器。以下是示例代码:

class SimpleClassDeserializer implements JsonDeserializer<SimpleClass> {
    @Override
    public SimpleClass deserialize(JsonElement json, 
        Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
    JsonObject jsonObject = json.getAsJsonObject();
    SimpleClass simpleClass = new SimpleClass();
    JsonObject stringField1Object = jsonObject.getAsJsonObject("stringField1");
    simpleClass.setStringField1(stringField1Object.get("string").getAsString());                                                        
    return simpleClass;
   }
}

此代码为SimpleClass创建一个自定义反序列化器,该反序列化器通过提取字符串字段值并将其设置为SimpleClass示例的stringField1字段来处理stringField1容器字段。
如何使用反序列化器:

String inputJson = "{\n" +
    "  \"stringField1\": {\n" +
    "    \"string\": \"stringField1Value\"\n" +
    "  }\n" +
    "}";
Gson gson = new GsonBuilder()
    .registerTypeAdapter(SimpleClass.class, new SimpleClassDeserializer())
    .create();
SimpleClass simpleClass = gson.fromJson(inputJson, SimpleClass.class);
System.out.println(simpleClass);

结果将是:SimpleClass(longField=null, stringField1=stringField1Value, stringField2=null)
注意,在定制的反序列化器中,您需要自己处理SimpleClass的所有字段,因为不会使用Gson的基于反射的Map。

htzpubme

htzpubme2#

如果您只是需要快速实现,我建议使用org.json.JSONObject,而不要设置GSON数据类。
只要用json字符串调用构造函数JSONObject(String),你就会得到一个可以像这样访问的对象:

JSONObject o = new JSONObject(inputJson);
String string1 = o.getJSONObject("stringField1").getString("string1");
sr4lhrrt

sr4lhrrt3#

作为创建反序列化器来处理SimpleClass的完整反序列化(如the other answer here中所建议的)的替代方法,您可以创建一个自定义反序列化器或类型适配器来解开字符串值,然后将Gson的@JsonAdapter注解放在stringField1字段上,以便仅为该字段自定义反序列化:

class UnwrappingStringAdapter extends TypeAdapter<String> {
    // No-args constructor called by Gson
    public UnwrappingStringAdapter() { }

    @Override
    public void write(JsonWriter out, String value) throws IOException {
        throw new UnsupportedOperationException();
    }

    @Override
    public String read(JsonReader in) throws IOException {
        in.beginObject();
        String name = in.nextName();
        String value;

        if (name.equals("string")) {
            value = in.nextString();
        } else {
            throw new IllegalArgumentException("Unexpected property: " + name);
        }

        in.endObject();
        return value;
    }
}

然后将@JsonAdapter注解放在字段上:

class SimpleClass {
    @JsonAdapter(UnwrappingStringAdapter.class)
    private String stringField1;
}

相关问题