简体   繁体   English

json反序列化问题

[英]json deserialization problem

Have an array, when the size is 1, the json data I received does NOT contains [] ; 有一个数组,当大小为1时,我收到的json数据不包含[] ; like 喜欢

{"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. 当大小大于1时,反序列化工作。 However when size is 1, the deserialization failed. 但是,当size为1时,反序列化失败。

I am currently using jackson, any solution for this problem? 我目前正在使用杰克逊,这个问题的任何解决方案?

I am wondering if jackson/gson or any other library can handle this? 我想知道杰克逊/ gson或任何其他图书馆是否可以处理这个问题?

For Jackson specifically, your best bet would to first bind to a JsonNode or Object, like: 特别是杰克逊,你最好的选择是首先绑定到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? 但我认为你得到的JSON很糟糕 - 为什么你会返回一个只有1号数组的对象或数组? -- so if at all possible, I'd rather fix JSON first. - 所以如果可能的话,我宁愿先修好JSON。 But if that is not possible, this would work. 但如果不可能,这将有效。

Here's how to do it with GSON. 以下是使用GSON的方法。 Let's assume this object structure: 让我们假设这个对象结构:

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 在这里,您可以找到使用它的必要配置

I have faced the same issue when I am trying to deserialize the JSON object which was constructed from XML. 当我尝试反序列化从XML构造的JSON对象时,我遇到了同样的问题。 (XML-JSON). (XML-JSON)。 After quite a bit of research, found that we have a simple fix. 经过相当多的研究,发现我们有一个简单的解决方案。

Just set the feature : ACCEPT_SINGLE_VALUE_AS_ARRAY. 只需设置功能:ACCEPT_SINGLE_VALUE_AS_ARRAY。

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

For more info : http://fasterxml.github.com/jackson-databind/javadoc/2.0.0/com/fasterxml/jackson/databind/DeserializationFeature.html#ACCEPT_SINGLE_VALUE_AS_ARRAY 欲了解更多信息: http//fasterxml.github.com/jackson-databind/javadoc/2.0.0/com/fasterxml/jackson/databind/DeserializationFeature.html#ACCEPT_SINGLE_VALUE_AS_ARRAY

edit: I guess you would then just extract a JsonElement and check it's isJsonArray() and/or isJsonObject() . 编辑:我想你只需要提取一个JsonElement并检查它是isJsonArray()和/或isJsonObject() Then, just call getAsJsonArray() or getAsJsonObject() . 然后,只需调用getAsJsonArray()getAsJsonObject()

Old answer: Why not just try to extract the array and catch the JsonParseException if it fails. 旧答案:为什么不尝试提取数组并在失败时捕获JsonParseException In the catch block, try to extract an object instead. 在catch块中,尝试提取对象。

I know it's not pretty but it should work. 我知道它不漂亮但应该有效。

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. 对于这样的情况,JSON编码库通常具有“强制数组”选项。 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响应,如果它不是数组,则将返回的对象推送到新数组中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM