Gson:如果元素类型是动态的,JSON 到 java 对象转换问题
Gson: JSON to java object conversion issue if element type is dynamic
我有 json 字符串并尝试使用 GSon 转换为 Java 对象,其中一个元素的类型是动态的。
格式 1:
{"success":false,"errorMessage":"Missing all necessary request parameters.","status":400}
格式 2:
{"success":false,"errorMessage":{"errors":[{"code":007,"message":"Daily quota reached maximum limit"}]},"status":400}";
尝试使用 'code' 和 'message' 属性实现 class。但是使用 POJO,一次只能处理一个场景。
如果元素对象类型是动态的(在这种情况下是字符串或对象),我还有其他方法可以处理吗
在您的 POJO 中保留此字段 Object。
之后,当你想使用你的 POJO 时,只需按如下所示创建一个 if 条件:
MyPojo myPojo= new MyPojo();
if( myPojo.getMyField() instanceof String ){
// do something
}
else if(myPojo.getMyField() instanceof Map<String, Object> )
{
// do something
}
或者作为第二种方法,只需将您的 json 转换为 Map<String,Object>
之后您就可以使用地图获取您的字段,当然您必须检查相应类型的值字段。
Rg.
你必须自己制作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;
}
}
您的响应的 POJO class 应包含 List<ErrorMessage> errorMessage
。
别忘了注册您的新转换器:
gsonBuilder.registerTypeAdapter(new TypeToken<List<ErrorMessage>>() {}.getType(), new ErrorMessageConverter())
能用Jackson
API的
就可以用@JsonAnyGetter
注解
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties()
{
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value)
{
this.additionalProperties.put(name, value);
}
这包含未映射内容的值。
我有 json 字符串并尝试使用 GSon 转换为 Java 对象,其中一个元素的类型是动态的。
格式 1:
{"success":false,"errorMessage":"Missing all necessary request parameters.","status":400}
格式 2:
{"success":false,"errorMessage":{"errors":[{"code":007,"message":"Daily quota reached maximum limit"}]},"status":400}";
尝试使用 'code' 和 'message' 属性实现 class。但是使用 POJO,一次只能处理一个场景。
如果元素对象类型是动态的(在这种情况下是字符串或对象),我还有其他方法可以处理吗
在您的 POJO 中保留此字段 Object。 之后,当你想使用你的 POJO 时,只需按如下所示创建一个 if 条件:
MyPojo myPojo= new MyPojo();
if( myPojo.getMyField() instanceof String ){
// do something
}
else if(myPojo.getMyField() instanceof Map<String, Object> )
{
// do something
}
或者作为第二种方法,只需将您的 json 转换为 Map<String,Object>
之后您就可以使用地图获取您的字段,当然您必须检查相应类型的值字段。
Rg.
你必须自己制作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;
}
}
您的响应的 POJO class 应包含 List<ErrorMessage> errorMessage
。
别忘了注册您的新转换器:
gsonBuilder.registerTypeAdapter(new TypeToken<List<ErrorMessage>>() {}.getType(), new ErrorMessageConverter())
能用Jackson
API的
@JsonAnyGetter
注解
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties()
{
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value)
{
this.additionalProperties.put(name, value);
}
这包含未映射内容的值。