【问题标题】:Spring 3.2 and Jackson 2: add custom object mapperSpring 3.2 和 Jackson 2:添加自定义对象映射器
【发布时间】:2012-12-31 01:48:58
【问题描述】:

我正在 Spring MVC 中开发一个 REST Web 服务。我需要更改杰克逊 2 序列化 mongodb objectid 的方式。我不确定该怎么做,因为我找到了 jackson 2 的部分文档,我所做的是创建一个自定义序列化程序:

public class ObjectIdSerializer extends JsonSerializer<ObjectId> {


    @Override
    public void serialize(ObjectId value, JsonGenerator jsonGen,
            SerializerProvider provider) throws IOException,
            JsonProcessingException {
        jsonGen.writeString(value.toString());
    }
}

创建一个对象映射器

public class CustomObjectMapper extends ObjectMapper {

    public CustomObjectMapper() {
        SimpleModule module = new SimpleModule("ObjectIdmodule");
        module.addSerializer(ObjectId.class, new ObjectIdSerializer());
        this.registerModule(module);
    }

}

然后注册映射器

<mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
        <bean
            class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="my.package.CustomObjectMapper"></bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

我的 CustomConverter 永远不会被调用。我认为 CustomObjectMapper 的定义是错误的,我从 jackson 1.x 的一些代码中改编了它

在我的控制器中,我使用的是@ResponseBody。 我在哪里做错了?谢谢

【问题讨论】:

  • 序列化程序和注册对我来说看起来是正确的,所以我认为问题在于 xml 配置。
  • 是的,感谢您的建议,我在文件周围有一个空的 标记。它现在正在工作
  • 仅供参考,文档说要使用 StdSerializer:fasterxml.github.io/jackson-databind/javadoc/2.0.0/com/…
  • 我遇到了类似的问题。您能否发布您的最终工作解决方案?
  • 在我的项目中,我们扩展了 StdSerializer 而不是 JsonSerializer,但这不是问题。确保您使用的是 com.fasterxml.* 类而不是旧的 org.codehaus.* 类?

标签: java json spring spring-mvc jackson


【解决方案1】:

您应该使用@JsonSerialize annontation 注释相应的模型字段。在您的情况下,它可能是:

public class MyMongoModel{
   @JsonSerialize(using=ObjectIdSerializer.class)
   private ObjectId id;
}

但在我看来,最好不要使用实体模型作为 VO。更好的方法是在它们之间有不同的模型和映射。 你可以找到my example project here(我以 Spring 3 和 Jackson 2 的日期序列化为例)。

【讨论】:

    【解决方案2】:

    我会怎么做:

    创建一个注解来声明你的自定义序列化器:

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyMessageConverter{
    }
    

    在您的 mvc 配置文件中为此设置组件扫描

    <context:include-filter expression="package.package.MyMessageConverter"
                type="annotation" />
    

    并创建一个实现HttpMessageConverter&lt;T&gt; 的类。

    @MyMessageConverter
    public MyConverter implements HttpMessageConverter<T>{
    //do everything that's required for conversion.
    }
    

    创建一个extends AnnotationMethodHandlerAdapter implements InitializingBean的类。

        public MyAnnotationHandler extends AnnotationMethodHandlerAdapter implements InitializingBean{
        //Do the stuffs you need to configure the converters
        //Scan for your beans that have your specific annotation
        //get the list of already registered message converters
        //I think the list may be immutable. So, create a new list, including all of the currently configured message converters and add your own. 
        //Then, set the list back into the "setMessageConverters" method.
        }
    

    我相信这是您实现目标所需的一切。

    干杯。

    【讨论】:

    • 我相信你的方式更像是“泽西方式”。
    • 这个答案有太多不必要的复杂性。 OP 的做法是正确的。
    【解决方案3】:

    无需创建对象映射器。将 jackson-core-2.0.0.jar 和 jackson-annotations-2.0.0.jar 添加到您的项目中。

    现在,在处理服务时将以下代码行添加到您的控制器:

    @RequestMapping(value = "students", method = RequestMethod.POST, headers = "Accept=application/json", consumes = "application/json")
    
    public HashMap<String, String> postStudentForm(
                @RequestBody Student student, HttpServletResponse response)
    

    不要错过任何注释。

    【讨论】:

      猜你喜欢
      • 2012-07-08
      • 2015-12-23
      • 1970-01-01
      • 2021-05-02
      • 1970-01-01
      • 1970-01-01
      • 2019-12-05
      • 2014-02-10
      • 1970-01-01
      相关资源
      最近更新 更多