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

发布于 2024-11-13 02:29:22 字数 2648 浏览 3 评论 0原文

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

我有一个名为 EventEntry 的对象。该对象有一个属性 user,通过 getUser 方法返回 User 类型。我为 EventEntry 和 User 设置了 mixin。 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;
    }

}

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

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

两个 mixin 都只包含大量 @JsonIgnoreProperty 值:

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


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

}

EventEntry 的 mixin 已正确应用,但 User 的 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>

混合不适用于嵌入式对象还是我配置错误了?

另外,是否有一种更简洁的方法来实现我想要做的事情,本质上是在逐个视图的基础上决定哪些属性应该返回,哪些属性不应该返回?

I'm having trouble getting Jackson mixins working for embedded types when using @ResponseBody. I'm using spring MVC 3.0 and jackson 1.8.

I have an object called EventEntry. That object has a property user, returning the type User via the getUser method. I set up mixins for both EventEntry and User. The mixins just consist of lots of @JasonIgnoreProperties values.

When an EventEntry is streamed out, the mixin is correctly applied and many properties are ignored. However, when the User object that is part of the EventEntry object is streamed out, the mixin is not applied and all properties are returned.

Code below:

public class EventEntry {

private User user;

    public User getUser() {
        return user;
    }

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

}

The user class has lots of properties, most of which I do not want to return as part of the json object.

In my controller, I add the mixins I want to user as below:

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

I have added two mixins, one for EventEntry, the other for User. As before, EventEntry contains a getUser() method.

Both mixins simply contain a whole lot of @JsonIgnoreProperty values:

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


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

}

The mixin for EventEntry is correctly applied, but the mixin for the User is not - the entire object is streamed out.

The only config I have for jackson is

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

Do mixins not apply to embedded objects or have I misconfigured something?

Also, is there a neater way to achieve what I want to do which is essentially to decided on a view-by-view basis which properties should be returned and which shouldn't?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

全部不再 2024-11-20 02:29:22

原因是您配置了一个 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 配置

The reason is that you configure one Jackson Mapper, but use an other one (the one from Spring).

Do it this way:

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

then you even do not need the xml configuration

枕梦 2024-11-20 02:29:22

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

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

I don't know why mix-ins would be ignored; sometimes frameworks use code generation and problem is that target of mix-ins is not implemented by eventual instance, but that does not seem likely here.
If you can verify that the same problem also occurs outside of Spring MVC it could be a bug in Jackson's mix-in handling, so maybe first try to isolate the problem?

As to other ways, @JsonView is the simplest way to define per-view exclusions (see http://wiki.fasterxml.com/JacksonJsonViews). A newer alternative is @JsonFilter (see http://wiki.fasterxml.com/JacksonFeatureJsonFilter); it is more powerful and configurable but needs bit more work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文