GSON Expected BEGIN_ARRAY but was BEGIN_OBJECT

前端 未结 3 1686
你的背包
你的背包 2020-11-30 08:12

I\'m getting this error when I receive only one single item in a list. I\'m using Jersey in the server side REST Web service, I only get the error when the List returned one

相关标签:
3条回答
  • 2020-11-30 08:35

    Basically, your web service is broken in terms of how it's replying. If there's only one object for project it's returning only an object instead of an array.

    MikO's answer solves the problem but another approach is encapsulating that logic in a custom deserializer:

    class MyDeserializer implements JsonDeserializer<ProjectContainer> {
    
        @Override
        public ProjectContainer deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException {
    
            JsonObject jo = je.getAsJsonObject().getAsJsonObject("project");
            if (jo.isJsonArray()) {
                 return new Gson().fromJson(je, ProjectContainer.class);
            } else {
                 Project p = jdc.deserialize(jo, Project.class);
                 List<Project> pList = new ArrayList<Project>(1);
                 pList.add(p);
                 ProjectContainer pc = new ProjectContainer();
                 pc.setProjects(pList);
                 return pc;
            }
        }
    }
    

    Then you can use:

    Gson gson = new GsonBuilder()
                    .registerTypeAdapter(ProjectContainer.class, new MyDeserializer())
                    .build();
    ProjectContainer pContainer = gson.fromJson(myJson, ProjectContainer.class);
    
    0 讨论(0)
  • 2020-11-30 08:38

    I ended up using Jackson library instead of gson to parse the json response. It automatically converts object into ArrayList. It is pretty much similar to gson in terms of ease of use. Hope it helps!

    0 讨论(0)
  • 2020-11-30 08:40

    Your issue results really weird for me... it seems that there must be some problem with Jersey's JSON serialization of single element arrays... if you Google "Jersey JSON single element arrays" you'll find the same issue, like here or here. I don't know too much about Jersey, so I can't help you with that...


    That said, I can suggest a workaround using manually parsing in Gson, to adapt your parsing to the 2 different responses (object or array). You could do something like this:

    //manually parsing until get the "project" element...
    JsonParser parser = new JsonParser();
    JsonObject rootObejct = parser.parse(yourJsonString).getAsJsonObject();
    JsonElement projectElement = rootObejct.get("project");
    
    Gson gson = new Gson();
    List<Project> projectList = new ArrayList<>();
    
    //Check if "project" element is an array or an object and parse accordingly...
    if (projectElement.isJsonObject()) {
        //The returned list has only 1 element
        Project project = gson.fromJson(projectElement, Project.class);
        projectList.add(project);
    }
    else if (projectElement.isJsonArray()) {
        //The returned list has >1 elements
        Type projectListType = new TypeToken<List<Project>>() {}.getType();
        projectList = gson.fromJson(projectElement, projectListType);
    }
    
    //Now you have a List<Project> projectList with one or many Project elements, 
    //depending on the response...
    

    Note that you don't need your class ProjectContainer.

    Something like this should work for you, although obviously the best thing would be fix the serialization issue!

    0 讨论(0)
提交回复
热议问题