views:

558

answers:

2

Hi everyone,

I have a question concerning Json deserialization using Jackson. I would like to deserialize a Json file using a class like this one: (taken from http://wiki.fasterxml.com/JacksonInFiveMinutes)

public class User 
{
    public enum Gender { MALE, FEMALE };
    public static class Name {
      private String _first, _last;
      public String getFirst() { return _first; }
      public String getLast() { return _last; }
      public void setFirst(String s) { _first = s; }
      public void setLast(String s) { _last = s; }
    }
    private Gender _gender;
    private Name _name;
    private boolean _isVerified;
    private byte[] _userImage;
    public Name getName() { return _name; }
    public boolean isVerified() { return _isVerified; }
    public Gender getGender() { return _gender; }
    public byte[] getUserImage() { return _userImage; }
    public void setName(Name n) { _name = n; }
    public void setVerified(boolean b) { _isVerified = b; }
    public void setGender(Gender g) { _gender = g; }
    public void setUserImage(byte[] b) { _userImage = b; }
}

A Json file can be deserialized using the so called "Full Data Binding" in this way:

ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(new File("user.json"), User.class);

My problem is the usage of the inner class "Name". I would like to do the same thing without using inner classes. The "User" class would became like that:

import Name;
import Gender;
public class User 
{
    private Gender _gender;
    private Name _name;
    private boolean _isVerified;
    private byte[] _userImage;
    public Name getName() { return _name; }
    public boolean isVerified() { return _isVerified; }
    public Gender getGender() { return _gender; }
    public byte[] getUserImage() { return _userImage; }
    public void setName(Name n) { _name = n; }
    public void setVerified(boolean b) { _isVerified = b; }
    public void setGender(Gender g) { _gender = g; }
    public void setUserImage(byte[] b) { _userImage = b; }
}

This means to find a way to specify to the mapper all the required classes in order to perform the deserialization.

Is this possible? I looked at the documentation but I cannot find any solution.

My need comes from the fact that I use the Javassist library to create such classes, and it does not support inner or anonymous classes.

Thank you in advance

+3  A: 

There should be no difference between the static inner class Name, and the top-level class of the same name. The Jackson runtime should not be able to meaningfully distinguish between the two situations.

Have you tried moving the Name class out of User, changing it into a top-level class? It should still work as before.

edit: I just tried this, and it works fine when Name is a top-level class. The example had it as an inner class for the sake of brevity, I suspect.

skaffman
Thank you very much skaffman!I did not realize that.
Eto Demerzel
@Eto: An upvote and ticking the answer are the traditional methods of thanks :)
skaffman
A: 

mr. Skaffman's answer is right on. The only additional thing to mention is that unlike JAXB, Jackson does not generally require you to specify classes you operate on, except for the root class (and not always even that, if you use Polymorphic Handling).

StaxMan
JAXB doesn't either - you need only specify the root elements, plus those only reachable by polymorphic associations.
skaffman