When response is a JSON Object you can use default bean deserialiser. In case it is a JSON Array you can read it as array and create response object manually. Below you can find example custom deserialiser and BeanDeserializerModifier which is used to register custom deserialiser. BeanDeserializerModifier allows to use default deserialiser when JSON payload fits POJO model:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.BeanDeserializer;
import com.fasterxml.jackson.databind.deser.BeanDeserializerBase;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.type.CollectionType;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new BeanDeserializerModifier() {
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
if (beanDesc.getBeanClass() == Response.class) {
return new ResponseJsonDeserializer((BeanDeserializerBase) deserializer);
}
return super.modifyDeserializer(config, beanDesc, deserializer);
}
});
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
System.out.println(mapper.readValue(jsonFile, Response.class));
}
}
class ResponseJsonDeserializer extends BeanDeserializer {
private final BeanDeserializerBase baseDeserializer;
protected ResponseJsonDeserializer(BeanDeserializerBase src) {
super(src);
this.baseDeserializer = src;
}
@Override
public Response deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
if (p.currentToken() == JsonToken.START_OBJECT) {
return (Response) baseDeserializer.deserialize(p, ctxt);
}
if (p.currentToken() == JsonToken.START_ARRAY) {
CollectionType collectionType = ctxt.getTypeFactory().constructCollectionType(List.class, Item.class);
JsonDeserializer<Object> deserializer = ctxt.findRootValueDeserializer(collectionType);
List<Item> results = (List<Item>) deserializer.deserialize(p, ctxt);
Response response = new Response();
response.setCount(results.size());
response.setResults(results);
return response;
}
throw MismatchedInputException.from(p, Response.class, "Only object or array!");
}
}
class Response {
private int count;
private List<Item> results;
// getters, setters, toString
}
class Item {
private String example;
@JsonProperty("is_valid")
private boolean isValid;
// getters, setters, toString
}
Above code for JSON Object payload prints:
Response{count=5, results=[Item{example='test', isValid=true}, Item{example='test2', isValid=true}]}
And for JSON Array payload prints:
Response{count=2, results=[Item{example='test', isValid=true}, Item{example='test2', isValid=true}]}
jp?