Mr.
Mr.

Reputation: 10142

Jackson - JsonMappingException due to constructor

I am having the following exception when trying to deserialize a JSON

No suitable constructor found for type [simple type, class MyObj$obj$Card]: can not instantiate from JSON object (need to add/enable type information?) at [Source: java.io.StringReader@4344ee21; line: 1, column: 201] (through reference chain: MyObj["obj"]->Obj["cards"])

And the JSON is

{
  "obj":{
  "api":"OK",
  "cache":false,
  "cards":[
     {
        "id":1232995897,
        "items":[
           {
              "id":"vmdSJLpnY",
              "cat":50,
              "rating":0.0
           }
        ]
     },
     {
        "id":0005897,
        "items":[
           {
              "id":"vxdSJLpnY",
              "cat":50,
              "rating":0.0
           }
        ]
     }
 ]
 }
}

And within the Obj class I have the following statement

@JsonProperty("cards") private Card[] cards;

Which produces the exception above. Changing the type Card[] to Object[] does not produce an exception, but it lacks of the correct mapping I desire to get.

Any clue how can I resolve it? A snippet will be GREAT! What this error means anyhow?

UPDATE

I have included the Java class.

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.gson.Gson;

@JsonIgnoreProperties(ignoreUnknown=true)
public final class MyObj {
    @JsonIgnoreProperties(ignoreUnknown=true)
    public final class Obj {
        @JsonIgnoreProperties(ignoreUnknown=true)
        public final class Card {
            @JsonIgnoreProperties(ignoreUnknown=true)
            public final class Item {
                @JsonProperty("id") private String id;
                @JsonProperty("cat") private String cat;
                @JsonProperty("rating") private String rating;
                public final String getId() { return id; }
                public final String getCat() { return cat; }
                public final String getRating() { return ranting; }
                public final String toString() { return new Gson().toJson(this); }
            }

            @JsonProperty("items") private Item[] items;
            public final Item[] getItems() { return items; }
            public final String toString() { return new Gson().toJson(this); }
        }

        @JsonProperty("cards") private Card[] cards;
        public Card[] getCards() { return cards; }
        public final String toString() { return new Gson().toJson(this); }      
    }


    @JsonProperty("obj") MyObj obj;
    public final Card[] getCards(){ return apiServiceResultsNoLists.getCards(); }
}

Upvotes: 29

Views: 96999

Answers (6)

Asif
Asif

Reputation: 535

Add default constructor to the class and all the nested user defined class. It should work then.

Upvotes: 1

Ratul Sharker
Ratul Sharker

Reputation: 8021

I have been facing same kind of problem. My Json data set is like following

{
"count": 1917,
  "data": [
    {
      "id": "1",
      "generated_id": "Z1-1156",
      "first_name": "Maruf",
      "last_name": "Ahmed",
      "full_name": "Mr. Maruf Ahmed",
      "email": "maruf1990@gmail.com",
      "phone": "+8801676798306",
      "company_name": "S M Style Ltd.",
      "website": "http:\\/\\/smartex-bd.com\\/",
      "address": "\\\nRoad No:5 House No:18\\\nLevel:3\\\nLane:\\\nBlock:F\\\nSector:2\\\nArea:Mirpur\\\nDhaka 1216\\\nMirpur\\\nBangladesh",
      "industry_type": "Apparel Retailer",
      "job_title": "Designer",
      "department": "Research & Development",
      "date": "7\\/10\\/2015 1:04:43 PM"
    },
    {
      "id": "2",
      "generated_id": "Z2-1157",
      "first_name": "Akramul",
      "last_name": "Hoque",
      "full_name": "Mr. Akramul Hoque",
      "email": "akram@nassagroup.org",
      "phone": "+8801732005564",
      "company_name": "Nassa Group",
      "website": "www,nassagroup.org",
      "address": "Nassa Group\\\nRoad No:238 House No:\\\nLevel:\\\nLane:\\\nBlock:\\\nSector:\\\nArea:Gulshan li\\\nDhaka 1208\\\nTejgaon Industrial Area\\\nBangladesh",
      "industry_type": "Denim Garments Manufacturer",
      "job_title": "Merchandiser (Senior)",
      "department": "Merchandising",
      "date": "7\\/9\\/2015 10:56:22 PM"
    }
    ]
}
        @JsonIgnoreProperties(ignoreUnknown = true)
    public class Visitors {



      @JsonIgnoreProperties(ignoreUnknown = true)
      public static class Visitor{
        @JsonProperty("id")
        public String mId;

        @JsonProperty("generated_id")
        public String mGenId;

        @JsonProperty("first_name")
        public String mFirstName;

        @JsonProperty("last_name")
        public String mLastName;

        @JsonProperty("full_name")
        public String mFullName;

        @JsonProperty("email")
        public String mEmail;

        @JsonProperty("phone")
        public String mPhone;

        @JsonProperty("company_name")
        public String mCompanyName;

        @JsonProperty("website")
        public String mWebsite;

        @JsonProperty("address")
        public String mAdress;

        @JsonProperty("industry_type")
        public String mIndustryType;

        @JsonProperty("job_title")
        public String mJobtitle;

        @JsonProperty("department")
        public String mDepartment;

        @JsonProperty("date")
        public String mDate;


        public Visitor(@JsonProperty("id") String  Id,
                       @JsonProperty("generated_id") String  GenId,
                       @JsonProperty("first_name") String  FirstName,
                       @JsonProperty("last_name") String  LastName,
                       @JsonProperty("full_name") String  FullName,
                       @JsonProperty("email") String  Email,
                       @JsonProperty("phone") String  Phone,
                       @JsonProperty("company_name") String  CompanyName,
                       @JsonProperty("website") String  Website,
                       @JsonProperty("address") String  Adress,
                       @JsonProperty("industry_type") String  IndustryType,
                       @JsonProperty("job_title") String  Jobtitle,
                       @JsonProperty("department") String  Department,
                       @JsonProperty("date") String  date)
        {
          mId = Id;
          mGenId = GenId;
          mFirstName = FirstName;
          mLastName= LastName;
          mFullName= FullName;
          mEmail= Email;
          mPhone= Phone;
          mCompanyName= CompanyName;
          mWebsite= Website;
          mAdress= Adress;
          mIndustryType= IndustryType;
          mJobtitle= Jobtitle;
          mDepartment= Department;
          mDate= date;
        }
      }


      @JsonProperty("count") public String mCount;


      @JsonProperty("data")  public ArrayList<Visitor> mVisitorList;

      @JsonCreator
      public Visitors(  @JsonProperty("count") String Count,
                        @JsonProperty("data") ArrayList<Visitor> visitorList)
      {
        mCount = Count;
        mVisitorList = visitorList;
      }
    }

The issue was the inner class declaration, it should be static. Because jackson need to access it like

new Visitors.Visitor();

so i declared the inner Visitor class as static. It worked for me.

Upvotes: 6

Tim Stewart
Tim Stewart

Reputation: 5500

I had the same symptoms the other day and took the advice about JsonCreator and JsonProperty but I got the same exact error message. It turns out that the project I'm working on is using fasterxml's and codehaus' versions of jackson. I put the codehaus attributes on my class but used fasterxml's ObjectMapper to do the parsing. They joy of transitive dependencies.

Upvotes: 11

ppeterka
ppeterka

Reputation: 20736

I think the problem is most likely with the Card object

  • it might not have a default constructor
  • if it doesn't have a default constructor, it should be annotated using @JsonCreator

EDIT I have two things:
* you don't have setters.
* you don't have a public constructor that would be allowed to set your fileds.

How should the deserializer populate your fields if you don't give it any (legal*) means for it?

Solutions:
-> add public setters to the classes
-> or create parametrized constructors annotated with @JsonCreator

*: of course, the parser could do the reflective "mofidy the visibility" trick, but come on, this is not "the way it's meant to be played"

EDIT2 I think this should work, but I can't test it - I don't have a project at hand with Jackson properly set up now (this is just a part of it, but I think it is easy to interpret what I wanted to show.) Note, I changed the array to a List:

    @JsonIgnoreProperties(ignoreUnknown=true)     
public final class Card {     
    @JsonIgnoreProperties(ignoreUnknown=true)

    public final class Item {     
        @JsonProperty("id") private String id;     
        @JsonProperty("cat") private String cat;     
        @JsonProperty("rating") private String rating;     

        @JsonCreator
        public Item(@JsonProperty("id") String id, @JsonProperty("cat") String cat, @JsonProperty("rating") String rating) {
            this.id = id;
            this.cat = cat;
            this.rating = rating;
        }   


        public final String getId() { return id; }     
        public final String getCat() { return cat; }     
        public final String getRating() { return ranting; }     
        public final String toString() { return new Gson().toJson(this); }     
    }     
    @JsonProperty("items") private List<Item> items;     

    @JsonCreator
    public Card(@JsonProperty("items") List<Item> items) {
        this.items = items;
    }       

    public final List<Item> getItems() { return items; }     

    public final String toString() { return new Gson().toJson(this); }     
}     

Upvotes: 45

Konstantin Pribluda
Konstantin Pribluda

Reputation: 12367

Look into your Card class - most probably there is no accessible default constructor or constructor lacks proper mappings.

Upvotes: 1

urir
urir

Reputation: 2025

I think your are missing default constructor in one of the classes.
Alternatively: add @JsonCreator annotation to the constructors

Upvotes: 3

Related Questions