java - 当结构不同时如何将JSON字符串转换为JAVA对象

标签 java json type-conversion gson

我正在尝试从 json 字符串创建对象的实例。 这是我的目标:

public class Person {
    String name;
    String address;
}

这是我的转换器:

Gson gson = new Gson();
Person p = gson.fromJson(str, Person.class);

问题是我的输入字符串格式可能比我的 Person 对象更复杂,例如:

{
  "name":"itay",
  "address":{
       "street":"my street",
       "number":"10"
     }
}

或者address的值可以是一个简单的字符串(在这种情况下我没有问题)。 我希望 p.address 将 json 对象包含为字符串。 这只是我的问题的一个例子,事实上,“地址”要复杂得多,结构未知。

我的解决方案是将 Person 类更改为:

public class BetterPerson {
    String name;
    Object address;
}

现在,address 是一个对象,我可以使用 .toString() 来获取值。

有更好的方法吗?

最佳答案

您可以尝试使用 JsonDeserializer根据运行时确定的 JSON 结构对其进行反序列化。

有关更多信息,请查看 GSON Deserialiser Example

示例代码:

class Person {
    private String name;
    private Object address;
    // getter & setter
}

class Address {
    private String street;
    private String number;
    // getter & setter
}

...

class PersonDeserializer implements JsonDeserializer<Person> {

    @Override
    public Person deserialize(final JsonElement json, final Type typeOfT,
            final JsonDeserializationContext context) throws JsonParseException {

        JsonObject jsonObject = json.getAsJsonObject();

        Person person = new Person();
        person.setName(jsonObject.get("name").getAsString());

        JsonElement jsonElement = jsonObject.get("address");
        if (!jsonElement.isJsonObject()) {
            String address = jsonElement.getAsString();
            person.setAddress(address);
        } else {
            JsonObject addressJsonObject = (JsonObject) jsonElement;

            Address address = new Address();
            address.setNumber(addressJsonObject.get("number").getAsString());
            address.setStreet(addressJsonObject.get("street").getAsString());
            person.setAddress(address);
        }

        return person;
    }
}

Person data = new GsonBuilder()
        .registerTypeAdapter(Person.class, new PersonDeserializer()).create()
        .fromJson(jsonString, Person.class);

if (data.getAddress() instanceof Address) {
    Address address = (Address) data.getAddress();
} else {
    String address = (String) data.getAddress();
}
<小时/>

您可以尝试HashMap<String,String> address无需使用额外的Address POJO 类,如果它的结构也不知道的话。

您也可以这样做,如果地址是字符串,则构造地址对象并在街道变量中设置地址字符串,如下所示:

class Person {
    private String name;
    private Address address;
    // getter & setter
}


...
JsonElement jsonElement = jsonObject.get("address");
if (!jsonElement.isJsonObject()) {
    String address = jsonElement.getAsString();
    Address obj = new Address();
    obj.setStreet(address);
    person.setAddress(obj);
}else{...}

关于java - 当结构不同时如何将JSON字符串转换为JAVA对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24125695/

相关文章:

java - StreamCorruptedException : invalid stream header:

javascript - 将 JSON 解析为常规 JavaScript 数组

将 malloc() 转换为 calloc()

int 和 longs 之间的 java 乘法给出 0

java - 如果您的 Serializable 类包含一个不可序列化的成员,会发生什么情况?你如何解决它?

java - 具有注解驱动的 spring 任务的多个 spring 任务执行器

java - Jackson:如何将平面 json 转换为嵌套 json

javascript - 如何解码类似 JSON 的 JavaScript 对象文字字符串

php - 我可以在 PHP 中遍历多维数组并将类型从字符串转换为整数(如果它们仅包含数字)吗?

java - JLabel 明文