Alex Alex - 1 year ago 85
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 Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download