Gson:JSON到java对象的转换问题(如果元素类型是动态的)
我有json字符串,并试图使用GSon转换为Java对象,其中一个元素的类型是动态的 格式1:Gson:JSON到java对象的转换问题(如果元素类型是动态的),java,json,gson,Java,Json,Gson,我有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"}]},"s
{"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}";
尝试实现具有“代码”和“消息”属性的类。但是使用POJO,一次只能处理一个场景
如果元素对象类型是动态的(本例中为字符串或对象),是否有其他方法可以处理该问题?将此字段对象保持在POJO中。 之后,当您想使用POJO时,只需按如下所示设置一个if条件:
MyPojo myPojo= new MyPojo();
if( myPojo.getMyField() instanceof String ){
// do something
}
else if(myPojo.getMyField() instanceof Map<String, Object> )
{
// do something
}
MyPojo MyPojo=new MyPojo();
if(myPojo.getMyField()字符串实例){
//做点什么
}
else if(myPojo.getMyField()映射实例)
{
//做点什么
}
或者作为第二种方法,只需将json转换为Map
,然后就可以使用Map获取字段,当然还需要检查值字段的对应类型
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;
}
}
公共类ErrorMessageConverter实现JsonDeserializer{
公共列表反序列化(JsonElement json,类型typeOfT,
JsonDeserializationContext(ctx){
List vals=new ArrayList();
if(json.isJsonPrimitive()){
//处理您的第一个案例,例如:
ErrorMessage err=新的ErrorMessage(json.getAsString());
VAL.add(错误);
//在本例中,您将有一个仅包含一个元素的列表-仅字符串错误
}else if(json.isJsonObject()){
//处理你的第二个案子
JsonArray errors=json.getAsJsonObject().get(“errors”).getAsJsonArray();
//处理错误-将其解析为列表
//您必须手动迭代数组的元素并逐个解析,以避免inifinit循环(如果您尝试将其解析为列表,Gson将再次调用转换器)
for(JsonElement e:json.getAsJsonArray()){
add(ctx.deserialize(e,ErrorMessage.class));
}
}
返回VAL;
}
}
类错误消息{
int代码;
字符串消息;
ErrorMessage(字符串消息){
this.message=消息;
}
}
响应的POJO类应该包含一个列表错误消息
不要忘记注册新转换器:
gsonBuilder.registerTypeAdapter(new TypeToken<List<ErrorMessage>>() {}.getType(), new ErrorMessageConverter())
gsonBuilder.registerTypeAdapter(新的TypeToken(){}.getType(),新的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);
}
@JsonAnyGetter
公共映射getAdditionalProperties()
{
返回此。附加属性;
}
@JSONANYSETER
public void setAdditionalProperty(字符串名称、对象值)
{
this.additionalProperties.put(名称、值);
}
这将保存未映射内容的值 这是一个众所周知的问题。你有两个选择来解决问题1-总是发送更大的响应!2-使用conrol json结构动态创建对象。看看本教程,将json转换为java对象-。感谢您的详细解释。它回答了我的问题。