Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Gson:JSON到java对象的转换问题(如果元素类型是动态的)_Java_Json_Gson - Fatal编程技术网

Gson:JSON到java对象的转换问题(如果元素类型是动态的)

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

我有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}";
尝试实现具有“代码”和“消息”属性的类。但是使用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对象-。感谢您的详细解释。它回答了我的问题。