Mike Green
Mike Green

Reputation: 13

Parsing a JSON String which was originally encoded using Jackson with the Jackson parser throws an IOExeption

I made a fairly basic Java object which holds three variables; a String, a String[] and a String[][]. This encoded into a JSON object perfectly fine using Jackson and I was able to print it. However trying to parse this String using Jackson will not give me the object back, it simply throws an IOException.

The code below can be used to duplicate my issue.

Object:

public class CityJSON {

    String[] currentCityList;
    String brokenCity;
    String[][] cityCosts;

    CityJSON(String[] ccl, String bc, String[][] cc){
        currentCityList = ccl;
        brokenCity = bc;
        cityCosts = cc;
    }

    public String[] getCurrentCityList() {
        return currentCityList;
    }

    public void setCurrentCityList(String[] currentCityList) {
        this.currentCityList = currentCityList;
    }

    public String getBrokenCity() {
        return brokenCity;
    }

    public void setBrokenCity(String brokenCity) {
        this.brokenCity = brokenCity;
    }

    public String[][] getCityCosts() {
        return cityCosts;
    }

    public void setCityCosts(String[][] cityCosts) {
        this.cityCosts = cityCosts;
    }

}

Encoder and Parser:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Tester {
    public static void main(String args[]){


        String[] cities = {"A city", "Another city"};
        String[] one = {"cost1", "cost2"};
        String[] two = {"cost3", "cost4"};
        String[][] twod = new String[2][2];
        twod[0] = one;
        twod[1] = two;
        CityJSON json = new CityJSON(cities, "myCity", twod);


        String gen = "";
        ObjectMapper mapper = new ObjectMapper();
        try {
            gen = mapper.writeValueAsString(json);
        } catch (JsonProcessingException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }

        System.out.println(gen);


        try {
            CityJSON ob = new ObjectMapper().readValue(gen, CityJSON.class);
        } catch (IOException ex) {
            System.out.println("FAILED");
        }

    }
}

The catch statement will be triggered causing "FAILED" to be printed.

Upvotes: 0

Views: 856

Answers (1)

beresfordt
beresfordt

Reputation: 5222

The IOException states:

com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class CityJSON]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?) at [Source: {"currentCityList":["A city","Another city"],"brokenCity":"myCity","cityCosts":[["cost1","cost2"],["cost3","cost4"]]}; line: 1, column: 2] at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)

So create a no-arg constructor, or annotate the existing constructor with @JsonCreator and annotate the args to that constructor with @JsonProperty("propertyName") - eg

@JsonCreator
CityJSON(
    @JsonProperty("currentCityList") String[] ccl,
    @JsonProperty("brokenCity") String bc,
    @JsonProperty("cityCosts")String[][] cc
){
    currentCityList = ccl;
    brokenCity = bc;
    cityCosts = cc;
}

Upvotes: 1

Related Questions