仍然有点不熟悉春天,我遇到了一个 问题 这使得有必要为杰克逊(Jackson)实施我的自定义Deserialzer。该过程在一个小的 教程, 但是,我被春天困住了。我不明白,哪里

 ObjectMapper mapper = new ObjectMapper();

在春季MVC中,当通过控制器类的方法进行jSON时,进行了MVC。因此,我不知道该怎么做才能用自定义的Deserialiser替换默认的Deserializer。

任何最欢迎的建议。

有帮助吗?

解决方案

您不会说您在春季如何使用杰克逊,所以我假设您正在使用它 <mvc:annotation-driven/>@RequestBody 和/或 @ResponseBody 注释。

一件事之一 <mvc:annotation-driven/> 做是注册 AnnotationMethodHandlerAdapter 带有许多预先配置的豆 HttpMessageConverter 豆,包括 MappingJacksonHttpMessageConverter, ,它处理往返于杰克逊注销模型类的编组。

现在 MappingJacksonHttpMessageConverter 有一个 setObjectMapper() 方法,这使您可以覆盖默认值 ObjectMapper. 。但由于 MappingJacksonHttpMessageConverter 是通过幕后创建的 <mvc:annotation-driven/>, ,您无法做到。

然而, <mvc:annotation-driven/> 只是一个方便的捷径。这是一个有效的声明自己的 AnnotationMethodHandlerAdapter 豆,注入自己的 MappingJacksonHttpMessageConverter 豆(通过 messageConverters 属性),并注入您自己的自定义 ObjectMapper 进入那。

然后,您遇到了如何构建自定义的问题 ObjectMapper, ,因为这不是一个春天的班级。我建议写你的 自己的简单实施 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>

其他提示

在春季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-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>

Rakesh引用的解决方案可能与Spring MVC 3.0一起使用,但有3.1个MVC基础架构 已经改变. 。结果,您可能没有 AnnotationMethodHandlerAdapter 在您的应用程序上下文中注册的豆,最终您会得到一个 BeanCreationException 在初始化时。

对于春季MVC 3.1 mvc:annotation-driven 元素将创建一个 requestMappingHandlerAdapter 对于您来说,因此您应该自动自动使用该类型。它仍将提供对已注册的httpmessageconverters列表的访问权限,并允许您在“ ObjectMapper”属性上设置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;
    }
}

更新: :事实证明,对于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>

这将添加一个新实例 MappingJacksonHttpMessageConverter 在任何默认的httpmessageconverters之前,使用自定义对象mapper(由于 register-defaults="true").

在我的情况下(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>

用无法解释的方式覆盖了某些东西。

这对我有用:

customObject.java

@JsonSerialize(using = CustomObjectSerializer.class)
public class CustomObject {

    private Long value;

    public Long getValue() {
        return value;
    }

    public void setValue(Long value) {
        this.value = value;
    }
}

customObjectSerializer.java

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

无XML配置(<mvc:message-converters>(...)</mvc:message-converters>我的解决方案需要)。

我希望我更好地了解春季MVC,但是有了JAX-RS实施,例如Jersey和Resteasy,一个注册提供商。也许春天有类似的事情?

MappingJacksonHttpMessageConverter状态的春季文档:

2.4.5 MappingJacksonHttpMessageConverter

可以使用Jackson Json Processor的ObjectMapper读取和编写JSON的HTTPMessAgeConverter实现。可以通过使用杰克逊提供的注释根据需要定制JSON映射。当需要进一步的控制时,可以通过对ObjectMapper属性注入自定义的对象模型,对于需要为特定类型提供自定义JSON Serializer/Deserializers的情况。默认情况下,此转换器支持(应用程序/JSON)。

您不能只是自动访问对objectMapper即可修改其行为吗?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top