2011-06-04 1 views
1

J'ai du mal à faire en sorte que les mixins Jackson fonctionnent pour les types intégrés lors de l'utilisation de @ResponseBody. J'utilise Spring MVC 3.0 et jackson 1.8.Jackson mixin ne fonctionne pas pour les types incorporés dans Spring MVC

J'ai un objet appelé EventEntry. Cet objet a un utilisateur de propriété, renvoyant le type Utilisateur via la méthode getUser. J'ai mis en place des mixins pour EventEntry et User. Les mixins consistent simplement en beaucoup de valeurs @JasonIgnoreProperties.

Lorsqu'un événement EventEntry est diffusé, le mixin est correctement appliqué et de nombreuses propriétés sont ignorées. Toutefois, lorsque l'objet Utilisateur qui fait partie de l'objet EventEntry est diffusé, le mixin n'est pas appliqué et toutes les propriétés sont renvoyées.

code ci-dessous:

public class EventEntry { 

private User user; 

    public User getUser() { 
     return user; 
    } 

    public void setUser(User user) { 
     this.user = user; 
    } 

} 

La classe utilisateur a beaucoup de propriétés, dont la plupart je ne veux pas revenir dans le cadre de l'objet JSON.

Dans mon contrôleur, j'ajouter mixins que je veux à l'utilisateur comme ci-dessous:

@RequestMapping(value = "/event/view/{eventIdentifier}/entries/json", method = RequestMethod.GET) 
    public @ResponseBody List<EventEntry> viewMyEventsJson(HttpServletResponse response, @PathVariable("eventIdentifier") String eventIdentifier){    
     ObjectMapper mapper = new ObjectMapper();     
     SerializationConfig serializationConfig = mapper.getSerializationConfig(); 
     serializationConfig.addMixInAnnotations(EventEntry.class, BasicEventEntryJsonMixin.class); 
     serializationConfig.addMixInAnnotations(User.class, BasicPublicUserJsonMixin.class);   
     List<EventEntry> eventEntryList = getEventEntries(eventIdentifier); 
     try {      
      mapper.writValue(response.getOutputStream(), eventEntryList);    
     } catch (IOException ex) { 
      logger.error(ex); 
     } 
     return null; 
    } 

J'ai ajouté deux mixins, un pour eventEntry, l'autre pour l'utilisateur. Comme précédemment, EventEntry contient une méthode getUser().

Les deux mixins contiennent simplement beaucoup de valeurs @JsonIgnoreProperty:

@JsonIgnoreProperties({"eventId","lastUpdatedOn","lastUpdatedBy"}) 
public class BasicEventEntryJsonMixin extends EventEntry{ 
    //Empty by design  
} 


@JsonIgnoreProperties({"emailAddress","lastUpdatedOn","lastUpdatedBy"}) 
public class BasicPublicUserJsonMixin extends User { 

} 

Le mixin pour eventEntry est correctement appliquée, mais le mixin pour l'utilisateur n'a pas - tout l'objet est transmis en continu sur.

La seule config que j'ai pour jackson est

<bean id="messageAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> 
     <property name="messageConverters"> 
      <list> 
       <!-- Support JSON --> 
       <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/> 
      </list> 
     </property> 
    </bean> 

Ne mixins applique pas aux objets incorporés ou ai-je mal configuré quelque chose?

De même, y a-t-il une façon plus simple de réaliser ce que je veux faire qui consiste essentiellement à décider, vue par vue, quelles propriétés devraient être retournées et lesquelles ne devraient pas l'être?

Répondre

5

La raison est que vous configurez un Jackson Mapper, mais en utilisez un autre (celui de Spring).

Est-ce que cette façon:

@RequestMapping(value = "/event/view/{eventIdentifier}/entries/json", 
       method = RequestMethod.GET) 
public @ResponseBody String viewMyEventsJson(
      @PathVariable("eventIdentifier") String eventIdentifier) 
      throws JsonGenerationException, JsonMappingException, IOException{ 
    ObjectMapper mapper = new ObjectMapper(); 
    SerializationConfig serializationConfig = mapper.getSerializationConfig(); 
    serializationConfig.addMixInAnnotations(EventEntry.class, 
              BasicEventEntryJsonMixin.class); 
    serializationConfig.addMixInAnnotations(User.class, 
              BasicPublicUserJsonMixin.class); 

    return mapper.writeValueAsString(getEventEntries(eventIdentifier)); 
} 

vous même ne pas besoin de la configuration xml

1

Je ne sais pas pourquoi les mix-ins seraient ignorés; parfois les frameworks utilisent la génération de code et le problème est que la cible des mix-ins n'est pas implémentée par une instance éventuelle, mais cela ne semble pas probable ici. Si vous pouvez vérifier que le même problème se produit également en dehors de Spring MVC, cela pourrait être un bug dans la gestion des mixages de Jackson, donc peut-être d'abord essayer d'isoler le problème? Pour d'autres façons, @JsonView est la façon la plus simple de définir des exclusions par vue (voir http://wiki.fasterxml.com/JacksonJsonViews). Une nouvelle alternative est @JsonFilter (voir http://wiki.fasterxml.com/JacksonFeatureJsonFilter); il est plus puissant et configurable mais nécessite un peu plus de travail.

Questions connexes