I have json String and trying to convert to Java Object using GSon where the type of one element is dynamic.
Format1:
{"success":false,"errorMessage":"Missing all necessary request parameters.","status":400}
Format2:
{"success":false,"errorMessage":{"errors":[{"code":007,"message":"Daily quota reached maximum limit"}]},"status":400}";
Tried implementing a class with 'code' and 'message' properties. But using the POJO, can handle only one scenario at a time.
Is there any other way that i can handle if element object type is dynamic (string or object in this case)
You have to make your own JsonDeserializer
:
public class ErrorMessageConverter implements JsonDeserializer<List<ErrorMessage>> {
public List<ErrorMessage> deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext ctx) {
List<ErrorMessage> vals = new ArrayList<ErrorMessage>();
if (json.isJsonPrimitive()) {
// handle your first case, for example:
ErrorMessage err = new ErrorMessage(json.getAsString());
vals.add(err);
// in this case you will have a List which contains only one element - your String-only error
} else if (json.isJsonObject()) {
// handle your second case
JsonArray errors = json.getAsJsonObject().get("errors").getAsJsonArray();
// work with errors - parse it to a List<ErrorMessage>
// you have to manually iterate over array's elements and parse it one by one to avoid an inifinit loop (if you try parsing it as a List, Gson will call your converter again)
for (JsonElement e : json.getAsJsonArray()) {
vals.add(ctx.deserialize(e, ErrorMessage.class));
}
}
return vals;
}
}
class ErrorMessage {
int code;
String message;
ErrorMessage(String message) {
this.message = message;
}
}
Your POJO class for the response should contain a List<ErrorMessage> errorMessage
.
Don't forget to register your new converter:
gsonBuilder.registerTypeAdapter(new TypeToken<List<ErrorMessage>>() {}.getType(), new ErrorMessageConverter())
Keep this field Object in your POJO . After that when you want to use your POJO , just make a if condition as below:
MyPojo myPojo= new MyPojo();
if( myPojo.getMyField() instanceof String ){
// do something
}
else if(myPojo.getMyField() instanceof Map<String, Object> )
{
// do something
}
Or as a second way just convert your json into Map<String,Object>
after that you can get your fields by using map and of course you have to check the value field for corresponding type.
Rg.
You can use @JsonAnyGetter
annotation if you can use Jackson
API's
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties()
{
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value)
{
this.additionalProperties.put(name, value);
}
This holds the values for unmapped contents.
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.