2010-04-05 12 views
3

J'ai une question concernant la désérialisation de Json avec Jackson. Je voudrais désérialiser un fichier JSON en utilisant une classe comme celle-ci: (extrait de http://wiki.fasterxml.com/JacksonInFiveMinutes)Json Jackson désérialisation sans classes intérieures

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; } 
} 

Un fichier JSON peut être désérialisé en utilisant la de cette façon que l'on appelle « la liaison de données Full »:

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

Mon problème est l'utilisation de la classe interne "Nom". Je voudrais faire la même chose sans utiliser les classes internes. La classe « Utilisateur » serait devenu comme ça:

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; } 
} 

Cela signifie trouver un moyen de spécifier au mappeur toutes les classes nécessaires pour effectuer la désérialisation.

Est-ce possible? J'ai regardé la documentation mais je ne trouve aucune solution. Mon besoin vient du fait que j'utilise la librairie Javassist pour créer de telles classes, et ne supporte pas les classes internes ou anonymes.

Nous vous remercions à l'avance

Répondre

6

Il devrait y avoir aucune différence entre la classe interne statique Name et la classe de niveau supérieur du même nom. Le runtime de Jackson ne devrait pas être en mesure de faire une distinction significative entre les deux situations.

Avez-vous essayé de déplacer la classe Name sur User, en la transformant en classe de premier niveau? Cela devrait encore fonctionner comme avant.

edit: J'ai juste essayé ceci, et ça fonctionne très bien quand Name est une classe de haut niveau. L'exemple l'a eu comme une classe intérieure par souci de concision, je soupçonne.

+0

Merci beaucoup skaffman! Je ne m'en suis pas rendu compte. –

+3

@Eto: Un upvote et en cochant la réponse sont les méthodes traditionnelles de remerciements :) – skaffman

1

mr. La réponse de Skaffman est juste. La seule chose supplémentaire à mentionner est que contrairement à JAXB, Jackson ne vous oblige généralement pas à spécifier les classes sur lesquelles vous opérez, à l'exception de la classe racine (et pas toujours même si vous utilisez Polymorphic Handling).

+0

JAXB non plus - vous devez seulement spécifier les éléments racine, plus ceux qui ne peuvent être atteints que par des associations polymorphes. – skaffman