Spring MVC + Jackson:动态 Json 序列化
我正在使用 Spring MVC 3.0.5 和 Jackson 1.7.2。
我希望实现动态 Bean 序列化器分配机制,例如,假设我的 MVC 控制器返回 (@ResponseBody
) 类型为 MyObject 的对象。默认情况下,Jackson 的 SerializerFactory 将寻找最合适的序列化器,包括我的自定义序列化器(例如 CustomSerializer extends JsonSerializer
)。
但是,我希望触发我的自定义序列化器,以防某些标志处于活动状态(比方说,附加到 ThreadLocal 的布尔变量)。否则,我想使用 Jackson 提供的序列化器,保持 MappingJacksonHttpMessageConverter 的默认行为不变。
有什么方法可以实现这一点吗?
我已经将自己的 ObjectMapper、SerializerFactory 和 CustomSerializer 注册到 Spring 的
默认 MappingJacksonHttpMessageConverter
中。
public class ConvertingPostProcessor implements BeanPostProcessor {
private ObjectMapper jacksonJsonObjectMapper;
public Object postProcessBeforeInitialization(Object bean, String name)
throws BeansException {
if (bean instanceof AnnotationMethodHandlerAdapter) {
HttpMessageConverter<?>[] convs = ((AnnotationMethodHandlerAdapter) bean).getMessageConverters();
for (HttpMessageConverter<?> conv: convs) {
if (conv instanceof MappingJacksonHttpMessageConverter) {
((MappingJacksonHttpMessageConverter) conv).setObjectMapper(jacksonJsonObjectMapper);
}
}
}
return bean;
}
public Object postProcessAfterInitialization(Object bean, String name)
throws BeansException {
return bean;
}
public void setJacksonJsonObjectMapper(ObjectMapper jacksonJsonObjectMapper) {
this.jacksonJsonObjectMapper = jacksonJsonObjectMapper;
}
}
spring-mvc.xml 是:
<mvc:annotation-driven />
...
<bean id="jacksonJsonObjectMapper" class="org.mycode.serialize.CustomObjectMapper">
<property name="customSerializerFactory" ref="jacksonJsonCustomSerializerFactory" />
</bean>
<bean id="jacksonJsonCustomSerializerFactory" class="org.mycode.serialize.CustomSerializerFactoryRegistry">
<property name="serializers">
<map>
<entry key="org.mycode.domain.MyObject" value-ref="customSerializer" />
</map>
</property>
</bean>
<bean id="customSerializer" class="org.mycode.serialize.CustomSerializer">
<property name="jacksonJsonCustomSerializerFactory" ref="jacksonJsonCustomSerializerFactory" />
</bean>
<bean id="convertingPostProcessor" class="org.mycode.serialize.ConvertingPostProcessor">
<property name="jacksonJsonObjectMapper" ref="jacksonJsonObjectMapper" />
</bean>
提前致谢!!
I'm using Spring MVC 3.0.5 with Jackson 1.7.2.
I wish to implement a Dynamic Bean serializer assignment mechanism, for example, let's say that my MVC Controller returns (@ResponseBody
) an Object of type MyObject. By default, Jackson's SerializerFactory will look for the most appropriate Serializer, including my custom Serializers (like for example CustomSerializer extends JsonSerializer<MyObject>
).
However, I want my custom Serializers to be triggered just in case some flag is active (let's say, a boolean variable attached to ThreadLocal). Otherwise, I want to use Jackson provided Serializers, keeping MappingJacksonHttpMessageConverter
's default behaviour intact.
Is there any way to implement an approach to that?
I've already registered my own ObjectMapper, SerializerFactory and CustomSerializers into Spring's <mvc:annotaion-driven />
default MappingJacksonHttpMessageConverter
.
public class ConvertingPostProcessor implements BeanPostProcessor {
private ObjectMapper jacksonJsonObjectMapper;
public Object postProcessBeforeInitialization(Object bean, String name)
throws BeansException {
if (bean instanceof AnnotationMethodHandlerAdapter) {
HttpMessageConverter<?>[] convs = ((AnnotationMethodHandlerAdapter) bean).getMessageConverters();
for (HttpMessageConverter<?> conv: convs) {
if (conv instanceof MappingJacksonHttpMessageConverter) {
((MappingJacksonHttpMessageConverter) conv).setObjectMapper(jacksonJsonObjectMapper);
}
}
}
return bean;
}
public Object postProcessAfterInitialization(Object bean, String name)
throws BeansException {
return bean;
}
public void setJacksonJsonObjectMapper(ObjectMapper jacksonJsonObjectMapper) {
this.jacksonJsonObjectMapper = jacksonJsonObjectMapper;
}
}
And spring-mvc.xml would be:
<mvc:annotation-driven />
...
<bean id="jacksonJsonObjectMapper" class="org.mycode.serialize.CustomObjectMapper">
<property name="customSerializerFactory" ref="jacksonJsonCustomSerializerFactory" />
</bean>
<bean id="jacksonJsonCustomSerializerFactory" class="org.mycode.serialize.CustomSerializerFactoryRegistry">
<property name="serializers">
<map>
<entry key="org.mycode.domain.MyObject" value-ref="customSerializer" />
</map>
</property>
</bean>
<bean id="customSerializer" class="org.mycode.serialize.CustomSerializer">
<property name="jacksonJsonCustomSerializerFactory" ref="jacksonJsonCustomSerializerFactory" />
</bean>
<bean id="convertingPostProcessor" class="org.mycode.serialize.ConvertingPostProcessor">
<property name="jacksonJsonObjectMapper" ref="jacksonJsonObjectMapper" />
</bean>
Thanks in advance!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Jackson 库目前还不够成熟。所以渲染模型对象有问题。它提供了一些注释和过滤器来自定义渲染的 json,但还不够。所以我建议您为视图创建新的 java 类,并使用 < 映射域对象到此视图类href="http://dozer.sourceforge.net/" rel="nofollow">dozer 框架最终在responsebody中返回此视图类。
Jackson library not enough mature for now.So rendering model object problematic.It provide a few annotation and filter to customize rendered json but not enough.So i suggest you create new java classes for just views and map domain objects to this view class using dozer framework end return this view classes in responsebody.