Alex Alex - 1 month ago 12
JSON Question

deserialize json from Moodle web service with Jackson (java)

I need to parse a JSON object obtained from a call to the Moodle REST api. The JSON response I get is:

{"users":[{"id":2,"username":"admin","firstname":"Amministratore","lastname":"Utente","fullname":"Amministratore Utente","email":"email@address.com","department":"","firstaccess":1475831148,"lastaccess":1477493148,"description":"","descriptionformat":1,"profileimageurlsmall":"http:\/\/vmoodle.local\/theme\/image.php\/clean\/core\/1475846316\/u\/f2","profileimageurl":"http:\/\/vmoodle.local\/theme\/image.php\/clean\/core\/1475846316\/u\/f1","preferences":[{"name":"auth_manual_passwordupdatetime","value":"1475831184"},{"name":"email_bounce_count","value":"1"},{"name":"email_send_count","value":"1"},{"name":"_lastloaded","value":1477561370}]}],"warnings":[]}


I'd like to map this json to a POJO, so I wrote two classes:

public class MoodleUser {

public MoodleUser() {
}

private int id;
private String username;

/**
* @return the id
*/
public int getId() {
return id;
}

/**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
}

/**
* @return the username
*/
public String getUsername() {
return username;
}

/**
* @param username the username to set
*/
public void setUsername(String username) {
this.username = username;
}

}

public class MoodleUsers {

public MoodleUsers() {

}

private List<MoodleUser> users;

/**
* @return the users
*/
public List<MoodleUser> getUsers() {
return users;
}

/**
* @param users the users to set
*/
public void setUsers(List<MoodleUser> users) {
this.users = users;
}

}


And then I call:

MoodleUsers response = oMapper.readValue(result, MoodleUsers.class);


What I get is an Exception reporting the following error:

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of mypackage.lms.MoodleClientRest$MoodleUsers: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
at [Source: {"users":[{"id":12,"username":"userok","firstname":"Nome test","lastname":"Cognome test","fullname":"Nome test Cognome test","email":"email@test.it","department":"","idnumber":"cftest","firstaccess":0,"lastaccess":0,"description":"","descriptionformat":1,"country":"IT","profileimageurlsmall":"http:\/\/vmoodle.local\/theme\/image.php\/clean\/core\/1475846316\/u\/f2","profileimageurl":"http:\/\/vmoodle.local\/theme\/image.php\/clean\/core\/1475846316\/u\/f1"}],"warnings":[]}
; line: 1, column: 2]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:261)
at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:1456)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1012)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1203)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:314)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3789)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2833)


I already have the default constructors in my pojo's, so I can't understand where the problem resides. Any suggestions?
Thank you.

Answer

The name of the class in the excpetion: mypackage.lms.MoodleClientRest$MoodleUsers suggests that MoodleUsers is an inner class of MoodleClientRest and in that case it has to be public static in order for jackson to successfully instantiate objects.

Comments