java json反序列化问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5219073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 10:02:11  来源:igfitidea点击:

json deserialization problem

javajsongsonHymanson

提问by user496949

Have an array, when the size is 1, the json data I received does NOT contains []; like

有一个数组,当大小为1时,我收到的json数据不包含[];喜欢

{"firstname":"tom"}

when the size is larger than 1, the data I received contains [], like

当大小大于 1 时,我收到的数据包含[],比如

[{"firstname":"tom"},{"firstname":"robert"}]

Currently my class contains an array property

目前我的班级包含一个数组属性

String[] firstname;
//getter setter omit here

Code to handle this likes

处理这种喜欢的代码

ObjectMapper mapper = new ObjectMapper();    
MyClass object = mapper.readValue(json, MyClass.class);

When the size is larger than 1, the deserialization works. However when size is 1, the deserialization failed.

当大小大于 1 时,反序列化工作。但是当大小为 1 时,反序列化失败。

I am currently using Hymanson, any solution for this problem?

我目前正在使用 Hymanson,这个问题有什么解决方案吗?

I am wondering if Hymanson/gson or any other library can handle this?

我想知道 Hymanson/gson 或任何其他图书馆是否可以处理这个问题?

回答by StaxMan

For Hymanson specifically, your best bet would to first bind to a JsonNode or Object, like:

特别是对于 Hymanson,最好的办法是首先绑定到 JsonNode 或 Object,例如:

Object raw = objectMapper.readValue(json, Object.class); // becomes Map, List, String etc

and then check what you got, bind again:

然后检查你得到了什么,再次绑定:

MyClass[] result;
if (raw instanceof List<?>) { // array
  result = objectMapper.convertValue(raw, MyClass[].class);
} else { // single object
  result = objectMapper.convertValue(raw, MyClass.class);
}

But I think JSON you are getting is bad -- why would you return an object, or array, intead of just array of size 1? -- so if at all possible, I'd rather fix JSON first. But if that is not possible, this would work.

但我认为你得到的 JSON 很糟糕——你为什么要返回一个对象或数组,而不是大小为 1 的数组?-- 所以如果可能的话,我宁愿先修复 JSON。但如果这是不可能的,这将起作用。

回答by Sean Patrick Floyd

Here's how to do it with GSON. Let's assume this object structure:

以下是如何使用 GSON 做到这一点。让我们假设这个对象结构:

public class Group{

    public Group(final List<Person> members){
        this.members = members;
    }

    private final List<Person> members;
}

public class Person{

    public Person(final String firstName, final String lastName){
        this.firstName = firstName;
        this.lastName = lastName;
    }

    private final String firstName;
    private final String lastName;
}

Here's a deserializer that understands single Person entries as well as arrays of them:

这是一个反序列化器,它可以理解单个 Person 条目以及它们的数组:

public class GroupDeserializer implements JsonDeserializer<Group>{

    @Override
    public Group deserialize(final JsonElement json,
        final Type typeOfT,
        final JsonDeserializationContext context) throws JsonParseException{
        List<Person> members;
        if(json.isJsonArray()){
            final JsonArray array = json.getAsJsonArray();
            members = new ArrayList<Person>(array.size());
            for(final JsonElement personElement : array){
                members.add(getSinglePerson(personElement, context));
            }
        } else{
            members =
                Collections.singletonList(getSinglePerson(json, context));
        }
        return new Group(members);
    }

    private Person getSinglePerson(final JsonElement element,
        final JsonDeserializationContext context){
        final JsonObject personObject = element.getAsJsonObject();
        final String firstName =
            personObject.getAsJsonPrimitive("firstname").getAsString();
        final String lastName =
            personObject.getAsJsonPrimitive("lastname").getAsString();
        return new Person(firstName, lastName);
    }

}

And here you can find the necessary Configuration to use this

在这里你可以找到必要的配置来使用它

回答by user634618

edit:I guess you would then just extract a JsonElementand check it's isJsonArray()and/or isJsonObject(). Then, just call getAsJsonArray()or getAsJsonObject().

编辑:我猜你会提取 aJsonElement并检查它的isJsonArray()和/或isJsonObject(). 然后,只需调用getAsJsonArray()getAsJsonObject()

Old answer:Why not just try to extract the array and catch the JsonParseExceptionif it fails. In the catch block, try to extract an object instead.

旧答案:为什么不尝试提取数组并在JsonParseException失败时捕获它。在 catch 块中,尝试提取一个对象。

I know it's not pretty but it should work.

我知道它不漂亮,但它应该可以工作。

回答by sambathp

I have faced the same issue when I am trying to deserialize the JSON object which was constructed from XML. (XML-JSON). After quite a bit of research, found that we have a simple fix.

当我尝试反序列化从 XML 构造的 JSON 对象时,我遇到了同样的问题。(XML-JSON)。经过相当多的研究,发现我们有一个简单的修复。

Just set the feature : ACCEPT_SINGLE_VALUE_AS_ARRAY.

只需设置功能:ACCEPT_SINGLE_VALUE_AS_ARRAY。

ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

For more info : http://fasterxml.github.com/Hymanson-databind/javadoc/2.0.0/com/fasterxml/Hymanson/databind/DeserializationFeature.html#ACCEPT_SINGLE_VALUE_AS_ARRAY

更多信息:http: //fasterxml.github.com/Hymanson-databind/javadoc/2.0.0/com/fasterxml/Hymanson/databind/DeserializationFeature.html#ACCEPT_SINGLE_VALUE_AS_ARRAY

回答by Iain Collins

In the first instance it looks like an object, in the second instance it looks like an array of objects (which it sounds like you are expecting).

在第一个实例中,它看起来像一个对象,在第二个实例中,它看起来像一个对象数组(听起来像是您所期望的)。

JSON encoding libraries typically have a "force array" option for cases like this. Failing that, on your client you could check the JSON response and if it's not an array, push the returned objected into an new array.

对于此类情况,JSON 编码库通常具有“强制数组”选项。如果失败,您可以在您的客户端上检查 JSON 响应,如果它不是数组,则将返回的对象推送到新数组中。