Web services Spring、Jackson和定制(例如CustomDeserializer)
由于对Spring仍然有点不熟悉,我遇到了一个问题,这使得有必要为Jackson实现一个定制的反序列化程序。这个过程在一个小文档中描述,但是,我被Spring卡住了。我不明白,在哪里Web services Spring、Jackson和定制(例如CustomDeserializer),web-services,json,spring,spring-mvc,jackson,Web Services,Json,Spring,Spring Mvc,Jackson,由于对Spring仍然有点不熟悉,我遇到了一个问题,这使得有必要为Jackson实现一个定制的反序列化程序。这个过程在一个小文档中描述,但是,我被Spring卡住了。我不明白,在哪里 ObjectMapper mapper = new ObjectMapper(); 在Spring中,当json被控制器类的方法反序列化时,执行MVC。因此,我不知道如何用自定义反序列化程序替换默认反序列化程序 欢迎任何建议。我希望能更好地了解SpringMVC,但对于Jersey和RESTeasy等Jax-R
ObjectMapper mapper = new ObjectMapper();
在Spring中,当json被控制器类的方法反序列化时,执行MVC。因此,我不知道如何用自定义反序列化程序替换默认反序列化程序
欢迎任何建议。我希望能更好地了解SpringMVC,但对于Jersey和RESTeasy等Jax-RS实现,可以注册提供者。也许Spring也有类似的功能?您没有说明如何在Spring中使用Jackson,因此我假设您是通过
和@RequestBody
和/或@ResponseBody
注释来使用它的
所做的一件事是注册一个注释方法HandlerAdapter
bean,该bean附带许多预配置的HttpMessageConverter
bean,包括MappingJacksonHttpMessageConverter
,它处理与Jackson注释模型类之间的编组
现在MappingJacksonHttpMessageConverter
有一个setObjectMapper()
方法,允许您覆盖默认的ObjectMapper
。但是由于映射JacksonHttpMessageConverter
是由
在幕后创建的,因此您无法访问它
然而,
只是一条方便的捷径。声明您自己的AnnotationMethodHandlerAdapter
bean,向其中注入您自己的MappingJacksonHttpMessageConverter
bean(通过messageConverters
属性),并向其中注入您自己定制的ObjectMapper
,同样有效
然后,您就遇到了如何构建自定义的ObjectMapper
的问题,因为它不是一个非常友好的Spring类。我建议你写一封信
所以你最终会得到这样的结果:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper">
<bean class="com.x.MyObjectMapperFactoryBean"/>
</property>
</bean>
</property>
</bean>
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="customObjectMapper"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
映射JacksonHttpMessageConverter状态的spring文档: 2.4.5映射JacksonHttpMessageConverter HttpMessageConverter实现,可以使用Jackson JSON处理器的ObjectMapper读取和写入JSON。JSON映射可以根据需要通过使用Jackson提供的注释进行定制。当需要进一步控制时,对于需要为特定类型提供自定义JSON序列化程序/反序列化程序的情况,可以通过ObjectMapper属性注入自定义ObjectMapper。默认情况下,此转换器支持(application/json)
难道你不能自动连接对ObjectMapper的访问以修改它的行为吗?Rakesh引用的解决方案可能适用于Spring MVC 3.0,但也适用于3.1部分MVC基础设施。因此,您可能没有在应用程序上下文中注册
AnnotationMethodHandlerAdapter
bean,并且在初始化时会出现BeanCreationException
对于Spring MVC 3.1,MVC:annotation-driven
元素将为您创建一个类型,因此您应该自动关联该类型。它仍将提供对已注册HttpMessageConverter列表的访问,并允许您在MappingJacksonHttpMessageConverter
上设置ObjectMapper属性。这还需要在init
中进行轻微更改。方法设置为HttpMessageConverters引用的类型
更新后的类如下所示:
@Component
public class JacksonFix {
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
private CustomObjectMapper objectMapper;
@PostConstruct
public void init() {
List<HttpMessageConverter<?>> messageConverters = requestMappingHandlerAdapter.getMessageConverters();
for (HttpMessageConverter<?> messageConverter : messageConverters) {
if (messageConverter instanceof MappingJacksonHttpMessageConverter) {
MappingJacksonHttpMessageConverter m = (MappingJacksonHttpMessageConverter) messageConverter;
m.setObjectMapper(objectMapper);
}
}
}
// this will exist due to the <mvc:annotation-driven/> bean
@Autowired
public void setRequestMappingHandlerAdapter(RequestMappingHandlerAdapter requestMappingHandlerAdapter) {
this.requestMappingHandlerAdapter = requestMappingHandlerAdapter;
}
@Autowired
public void setObjectMapper(CustomObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
}
@组件
公共类JacksonFix{
私有RequestMappingHandlerAdapter RequestMappingHandlerAdapter;
私有CustomObjectMapper对象映射器;
@施工后
公共void init(){
在Spring 3.1中列出实现此功能的新方法:
允许您执行以下操作:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper">
<bean class="com.x.MyObjectMapperFactoryBean"/>
</property>
</bean>
</property>
</bean>
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="customObjectMapper"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
在我的例子中(Spring 3.2.4和Jackson 2.3.1),自定义序列化程序的XML配置:
<mvc:annotation-driven>
<mvc:message-converters register-defaults="false">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="serializers">
<array>
<bean class="com.example.business.serializer.json.CustomObjectSerializer"/>
</array>
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
CustomObjectSerializer.java
公共类CustomObjectSerializer扩展JsonSerializer{
@凌驾
public void序列化(CustomObject值,JsonGenerator jgen,
SerializerProvider提供程序)引发IOException、JsonProcessingException{
jgen.writeStartObject();
jgen.writeNumberField(“y”,value.getValue());
jgen.writeEndObject();
}
@凌驾
公共类handledType(){
返回CustomObject.class;
}
}
我的解决方案中不需要XML配置((…)
)
public class CustomObjectSerializer extends JsonSerializer<CustomObject> {
@Override
public void serialize(CustomObject value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,JsonProcessingException {
jgen.writeStartObject();
jgen.writeNumberField("y", value.getValue());
jgen.writeEndObject();
}
@Override
public Class<CustomObject> handledType() {
return CustomObject.class;
}
}