Spring,Jackson和Customization(例如CustomDeserializer)

Ta *_*Sas 21 spring json web-services spring-mvc jackson

由于对Spring仍然有点不熟悉,我遇到了一个问题,需要为Jackson实现我的自定义反序列化器.该过程在一个小教程中描述,但是,我坚持使用Spring.我不明白,在哪里

 ObjectMapper mapper = new ObjectMapper();
Run Code Online (Sandbox Code Playgroud)

在Spring中,当json通过控制器类的方法反序列化时执行MVC.所以我不知道怎么做才能用自定义反序列化器替换默认的反序列化器.

任何建议最受欢迎.

ska*_*man 19

你不说怎么你在春季使用杰克逊,所以我会假设你使用它通过<mvc:annotation-driven/>@RequestBody和/或@ResponseBody注释.

其中一件事<mvc:annotation-driven/>就是注册一个AnnotationMethodHandlerAdapter带有许多预先配置的HttpMessageConverterbean的bean,包括MappingJacksonHttpMessageConverter处理与Jackson注释的模型类之间的编组.

现在MappingJacksonHttpMessageConverter有一个setObjectMapper()方法,允许您覆盖默认值ObjectMapper.但是既然MappingJacksonHttpMessageConverter是在幕后制作的<mvc:annotation-driven/>,你就无法实现它.

但是,<mvc:annotation-driven/>这只是一个方便的捷径.它是一个有效的声明你自己的AnnotationMethodHandlerAdapterbean,注入你自己的MappingJacksonHttpMessageConverterbean(通过messageConverters属性),并将自己的自定义ObjectMapper注入其中.

然后你有了如何构建自定义的问题ObjectMapper,因为它不是一个非常适合Spring的类.我建议编写自己的简单实现FactoryBean.

所以你最终得到这样的东西:

<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>
Run Code Online (Sandbox Code Playgroud)


Rya*_*lls 7

在Spring 3.1中执行此操作的新方法:http:
//magicmonster.com/kb/prg/java/spring/webmvc/mvc_spring_config_namespace.html

http://blog.springsource.org/2011/02/21/spring-3-1-m1-mvc-namespace-enhancements-and-configuration/

允许您执行以下操作:

<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>
Run Code Online (Sandbox Code Playgroud)


kyl*_*esm 5

Rakesh引用的解决方案可能适用于Spring MVC 3.0,但3.1版本的一些MVC基础架构已发生变化.因此,您可能没有AnnotationMethodHandlerAdapter在应用程序上下文中注册bean,并且最终会BeanCreationException在初始化时结束.

对于Spring MVC 3.1,mvc:annotation-driven元素将为您创建一个RequestMappingHandlerAdapter,因此您应该自动装配该类型.它仍然提供对已注册的HttpMessageConverters列表的访问,并允许您在其上设置ObjectMapper属性MappingJacksonHttpMessageConverter.这也需要在内部稍作改动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;
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:事实证明,使用Spring 3.1绝对最简单的方法是为MVC配置添加一些额外的配置:

<mvc:annotation-driven conversion-service="applicationConversionService">
    <mvc:message-converters register-defaults="true">
        <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
            <property name="objectMapper" ref="customObjectMapper" />
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>
Run Code Online (Sandbox Code Playgroud)

这将MappingJacksonHttpMessageConverter在任何默认的HttpMessageConverters(由于它仍然存在register-defaults="true")之前添加自定义ObjectMapper 的新实例.