Jackson mixin不适用于Spring MVC中的嵌入式类型

时间:2011-06-04 10:34:18

标签: spring-mvc jackson

使用@ResponseBody时,我无法让Jackson mixins为嵌入式类型工作。我正在使用spring MVC 3.0和jackson 1.8。

我有一个名为EventEntry的对象。该对象具有属性用户,通过getUser方法返回User类型。我为EventEntry和User设置了mixins。 mixin只包含许多@JasonIgnoreProperties值。

当流式传输EventEntry时,正确应用mixin并忽略许多属性。但是,当流式传输属于EventEntry对象的User对象时,不会应用mixin并返回所有属性。

以下代码:

public class EventEntry {

private User user;

    public User getUser() {
        return user;
    }

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

}

用户类有很多属性,其中大多数我不想作为json对象的一部分返回。

在我的控制器中,我添加了我想要的mixins,如下所示:

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

我添加了两个mixin,一个用于EventEntry,另一个用于User。和以前一样,EventEntry包含一个getUser()方法。

两个mixins只包含大量的@JsonIgnoreProperty值:

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


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

}

正确应用了EventEntry的mixin,但是用户的mixin不是 - 整个对象都已流出。

我对杰克逊的唯一配置是

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

mixins不适用于嵌入式对象,还是我配置错误?

此外,是否有更简洁的方法来实现我想要做的事情,这主要是基于逐个视图决定哪些属性应该返回,哪些不应该?

2 个答案:

答案 0 :(得分:5)

原因是您配置了一个Jackson Mapper,但使用另一个(Spring中的那个)。

这样做:

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

然后你甚至不需要xml配置

答案 1 :(得分:1)

我不知道为什么混淆会被忽略;有时框架使用代码生成,问题是混合的目标不是由最终实例实现的,但这似乎不太可能。 如果你可以验证在Spring MVC之外也发生同样的问题,那可能是Jackson混合处理中的一个错误,所以可能首先尝试隔离问题?

至于其他方式,@ JsonView是定义每个视图排除项的最简单方法(参见http://wiki.fasterxml.com/JacksonJsonViews)。更新的选择是@JsonFilter(见http://wiki.fasterxml.com/JacksonFeatureJsonFilter);它更强大,更可配置,但需要更多的工作。