Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Web services Spring、Jackson和定制(例如CustomDeserializer)_Web Services_Json_Spring_Spring Mvc_Jackson - Fatal编程技术网

Web services Spring、Jackson和定制(例如CustomDeserializer)

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

由于对Spring仍然有点不熟悉,我遇到了一个问题,这使得有必要为Jackson实现一个定制的反序列化程序。这个过程在一个小文档中描述,但是,我被Spring卡住了。我不明白,在哪里

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