Have an array, when the size is 1, the json data I received does NOT contains []
; like
{"firstname":"tom"}
when the size is larger than 1, the data I received contains []
, like
[{"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.
I am currently using jackson, any solution for this problem?
I am wondering if jackson/gson or any other library can handle this?
For Jackson specifically, your best bet would to first bind to a JsonNode or Object, like:
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.
Here's how to do it with 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:
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). After quite a bit of research, found that we have a simple fix.
Just set the feature : ACCEPT_SINGLE_VALUE_AS_ARRAY.
ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
edit: I guess you would then just extract a JsonElement
and check it's isJsonArray()
and/or isJsonObject()
. Then, just call getAsJsonArray()
or getAsJsonObject()
.
Old answer: Why not just try to extract the array and catch the JsonParseException
if it fails. In the catch block, try to extract an object instead.
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. 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.