Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/213.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
Java Android GSON POJO可选字段解析_Java_Android_Json_Gson - Fatal编程技术网

Java Android GSON POJO可选字段解析

Java Android GSON POJO可选字段解析,java,android,json,gson,Java,Android,Json,Gson,好的,我正在使用一个api,对于一个JSON参数,它可以返回两种不同的类型。因此,我可以从服务器接收JSON对象或字符串。我是Android开发的新手,所以如果有人能用一个代码示例向我解释我如何处理这个问题 示例json响应{video:{ID OF video}或{video:{ID:{ID:ID OF video,…额外数据}}。我看过自定义反序列化程序,但找不到一个易于遵循的示例。一定有一个简单的方法来解决我的问题。当前我收到错误“预期字符串,但找到BEGIN对象” 还有那部分 Gson

好的,我正在使用一个api,对于一个JSON参数,它可以返回两种不同的类型。因此,我可以从服务器接收JSON对象或字符串。我是Android开发的新手,所以如果有人能用一个代码示例向我解释我如何处理这个问题

示例json响应{video:{ID OF video}或{video:{ID:{ID:ID OF video,…额外数据}}。我看过自定义反序列化程序,但找不到一个易于遵循的示例。一定有一个简单的方法来解决我的问题。当前我收到错误“预期字符串,但找到BEGIN对象”

还有那部分

Gson gson = new Gson();
String jsonString = String.valueOf(dataset);
Type listType = new TypeToken<List<MyNotification>>(){}.getType();
notficationsList = (List<MyNotification>) gson.fromJson(jsonString, listType);
Gson-Gson=new-Gson();
String jsonString=String.valueOf(数据集);
类型listType=newTypeToken(){}.getType();
notificationslist=(List)gson.fromJson(jsonString,listType);
很抱歉花了这么长时间:

如果必须将JSON映射到对象,那么最好修复JSON

尝试使用以下代码清理JSON:

public static String cleanJson(String json) {
    int videoPos = json.indexOf("video");
    if(videoPos == -1) {
        return json; //return, no video here
    }
    boolean isObject = false;

    int objectBegin = -1;
    String cleanedJson = json.replaceAll("\\\"", "\\\\");
    for(int i = videoPos; i < cleanedJson.length(); i++) {
        if(cleanedJson.charAt(i) == '"') {
            System.out.println("string");
            return json; // its a string anyway
        }
        if(cleanedJson.charAt(i) == '{') {
            //its an object
            // i now is the position beginning the object
            objectBegin = i;
        }
    } //replace " with space
    if(objectBegin == -1) {// we did not find any { or " it is a string
        return json;
    }
    boolean inString = false;
    int objectEnd = -1;
    for(int i = objectBegin; i < cleanedJson.length(); i++) {
        //looking for the end of the object;
        if(cleanedJson.charAt(i) == '"') inString = !inString;
        if(cleanedJson.charAt(i) == '}') {
            objectEnd = i;
            break;
        }
    }
    if(objectEnd != -1) {
        String start = json.substring(0,objectBegin);
        String videoPart = json.substring(objectBegin, objectEnd+1);
        String end = json.substring(objectEnd+1);
        // now we want to get the id
        String newVideoPart = "";
        int idStart = videoPart.indexOf("id");
        int idStringStart = -1;
        int idStringEnd = -1;

        for(int i = idStart; i < videoPart.length(); i++) {
            if(videoPart.charAt(i) == '"') {
                if(idStringStart == -1) {
                    idStringStart = i;
                } else {
                    idStringEnd = i;
                    break;
                }
            }
        }
        if(idStringStart != -1 && idStringEnd != -1) {
            newVideoPart = videoPart.substring(idStringStart, idStringEnd+1);
        }

        return start+newVideoPart+end;
    }
    return json;
}
试着这样做:

notficationsList = (List<MyNotification>) gson.fromJson(cleanJson(jsonString), listType);
notificationslist=(List)gson.fromJson(cleanJson(jsonString),listType);

好的,所以我使用的解决方案是我自己编写的类型适配器,gson允许您使用

public class Helper_StringAdapter extends TypeAdapter<String>{
@Override
public String read(com.google.gson.stream.JsonReader in) throws IOException {
   if(in.peek() == JsonToken.NULL){
       in.nextNull();
       return null;
   }else if(in.peek() == JsonToken.BEGIN_OBJECT && in.getPath().contains(".video")){
       L.e("VIDEO IS AN OBJECT!");
       String userId = readAndReturnVideoId(in);
       return userId;
   }else{
       return in.nextString();
   }
}

private String readAndReturnVideoId(com.google.gson.stream.JsonReader reader) throws IOException{
    String id = "";
    reader.beginObject();
    while(reader.hasNext()){
        String name = reader.nextName();
        if(name.equals("_id")){
            id = reader.nextString();
        }else{
            reader.skipValue();
        }
    }
    reader.endObject();
    L.e("READ ID RETURNED"+id);
    return id;
}

@Override
public void write(com.google.gson.stream.JsonWriter out, String value) throws IOException {
    L.e("TEST "+out);
}
}
public class Helper\u StringAdapter扩展了TypeAdapter{
@凌驾
公共字符串读取(com.google.gson.stream.JsonReader in)引发IOException{
if(in.peek()==JsonToken.NULL){
in.nextNull();
返回null;
}else如果(in.peek()==JsonToken.BEGIN\u对象和in.getPath()包含(“.video”)){
L.e(“视频是一个对象!”);
字符串userId=readAndReturnVideoId(in);
返回用户标识;
}否则{
在.nextString()中返回;
}
}
私有字符串readAndReturnVideoId(com.google.gson.stream.JsonReader reader)引发IOException{
字符串id=“”;
reader.beginObject();
while(reader.hasNext()){
字符串名称=reader.nextName();
if(name.equals(“_id”)){
id=reader.nextString();
}否则{
reader.skipValue();
}
}
reader.endObject();
L.e(“返回读取ID”+ID);
返回id;
}
@凌驾
public void write(com.google.gson.stream.JsonWriter out,字符串值)引发IOException{
L.e(“测试”+输出);
}
}
然后在我的活动数据管理器(Recyclerview适配器)中

public void updateData(JSONArray数据集){
GsonBuilder gsonb=新的GsonBuilder();
gsonb.registerTypeAdapter(String.class,new Helper_StringAdapter());
Gson-Gson=gsonb.create();
String jsonString=String.valueOf(数据集);
类型listType=newTypeToken(){}.getType();
notificationslist=(List)gson.fromJson(jsonString,listType);
}

似乎做了这项工作

请发布您的代码发布我的代码?不确定这会有什么帮助?你是说我的POJO定义吗?是的,你的POJO定义可能会有所帮助,抛出异常的Java部分注释掉了给我带来麻烦的部分。我理解如果我将其定义为字符串,那么在将JSON转换为pojo时它需要一个字符串,但必须有一种我不知道的处理方法。JSON是在哪里创建的?这是您自己的服务还是外部服务?我希望您需要vido id。当然,您可以将其转过来,并始终使用它制作对象。通过使用库,您可以使事情变得更简单。所以结果是:你总是会得到视频的id作为一个名为videoOk的字符串,我想是的。谢谢
notficationsList = (List<MyNotification>) gson.fromJson(cleanJson(jsonString), listType);
public class Helper_StringAdapter extends TypeAdapter<String>{
@Override
public String read(com.google.gson.stream.JsonReader in) throws IOException {
   if(in.peek() == JsonToken.NULL){
       in.nextNull();
       return null;
   }else if(in.peek() == JsonToken.BEGIN_OBJECT && in.getPath().contains(".video")){
       L.e("VIDEO IS AN OBJECT!");
       String userId = readAndReturnVideoId(in);
       return userId;
   }else{
       return in.nextString();
   }
}

private String readAndReturnVideoId(com.google.gson.stream.JsonReader reader) throws IOException{
    String id = "";
    reader.beginObject();
    while(reader.hasNext()){
        String name = reader.nextName();
        if(name.equals("_id")){
            id = reader.nextString();
        }else{
            reader.skipValue();
        }
    }
    reader.endObject();
    L.e("READ ID RETURNED"+id);
    return id;
}

@Override
public void write(com.google.gson.stream.JsonWriter out, String value) throws IOException {
    L.e("TEST "+out);
}
}
public void updateData (JSONArray dataset) {
    GsonBuilder gsonb = new GsonBuilder();
    gsonb.registerTypeAdapter(String.class,new Helper_StringAdapter());
    Gson gson = gsonb.create();

    String jsonString = String.valueOf(dataset);
    Type listType = new TypeToken<List<FrameNotification>>(){}.getType();
    notficationsList = (List<FrameNotification>) gson.fromJson(jsonString, listType);
}