7

I am trying to display data from a web service and getting this error : Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token at...

Find below my code :

Model object :

public class Commune implements Serializable{

    private static final long serialVersionUID = 1L;

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Commune [name=" + name + "]";
    }
}

Main class:

public class Test {

    public static void main(String[] args) throws IOException {

        URL url = new URL("https://bj-decoupage-territorial.herokuapp.com/api/v1/towns");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setRequestProperty("Accept", "application/json");

        if(connection.getResponseCode() != 200){
            throw new RuntimeException("Failed : Http code : "+connection.getResponseCode());
        }

        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

        String output;

        while((output = reader.readLine()) != null){

            ObjectMapper mapper = new ObjectMapper();
            TypeReference<List<Commune>> mapType = new TypeReference<List<Commune>>() {};
            List<Commune> jsonToCommuneList = mapper.readValue(output, mapType);

            for(Commune c : jsonToCommuneList) {
                System.out.println(c.getName());
            }
        }
        connection.disconnect();        
    }
}

Here is the data getting from the url :

{"towns":
   [
      {"name":"BANIKOARA"},
      {"name":"GOGOUNOU"},
      {"name":"KANDI"},
      {"name":"KARIMAMA"}
   ]
}

Help me please to check what i did wrong.

Thank you

FooBayo
  • 141
  • 2
  • 3
  • 12
  • Possible duplicate of https://stackoverflow.com/questions/24709643/jackson-jsonmappingexception-can-not-deserialize-instance . – Jabongg Jan 15 '19 at 12:32
  • Do you want to read the response first and then use the object mapper ?? Also in response it is inside towns you need to create class which has array of Commune and then use parse – ygbgames Jan 15 '19 at 12:32

2 Answers2

10

You are getting this error because you are trying to deserialize something that is not actually a JSON Array into a Collection

If you are able to change your JSON to send just a JSON Array format, it will look like this one below:

[
  {"name":"BANIKOARA"},
  {"name":"GOGOUNOU"},
  {"name":"KANDI"},
  {"name":"KARIMAMA"}
]

Otherwise, to parse it correctly you also can create a new class which will represent the town of your JSON and parse using it:

public class TownRecords implements Serializable {

    private List<Commune> communes;

    ... getters and setters
}
nortontgueno
  • 2,553
  • 1
  • 24
  • 36
5

You're trying to deserialize a list of Commune, but in HTTP response you're getting an object, containing such a list, but not a list itself. So, you need another wrapper object for deserialisation:

Wrapper

public class Towns implements Serializable {
    private List<Commune> towns;

    public Towns() {}

    public List<Commune> getTowns() {
        return towns;
    }

    public void setTowns(List<Commune> towns) {
        this.towns = towns;
    }

    @Override
    public String toString() {
        return "Towns: " + towns.toString();
    }
}

main app

    TypeReference<Towns> mapType = new TypeReference<Towns>() {};
    Towns towns = mapper.readValue(output, mapType);
    System.out.println(towns);
kami
  • 189
  • 1
  • 9