在哪里为我的REST服务应用程序注册自定义ObjectMapper?

时间:2017-04-19 10:35:34

标签: java spring jaxb jersey jackson

我正在使用Spring和Jersey构建REST服务应用程序。

“响应内容类型”可以是JSON或XML,这就是我在POJO的字段上使用JAXB注释的原因,到目前为止效果很好。无需配置即可实现此功能,我只需将所需的.jars放在类路径上。

现在,我想为Java 8日期/时间对象的(反)序列化添加自定义行为,并注册杰克逊的JavaTimeModule

哪里是注册模块的正确位置?我知道代码片段应该是这样的:

ObjectMapper tmpMapper = new ObjectMapper();
tmpMapper.registerModule(new JavaTimeModule());

但我在哪里实际放置此代码?

我想到的是来自泽西岛的ResourceConfig课程。它看起来像这样:

@ApplicationPath("/rest")
public class ApplicationResourceConfig extends ResourceConfig {
    public ApplicationResourceConfig() {
    // Not needed because since jersey 2.9 JacksonFeature implements AutoDiscoverable
    // register(JacksonFeature.class);

    register(WadlFeature.class);

    // Registers our own request listener for monitoring purposes
    register(RestServiceApplicationEventListener.class);

    // Registers the package that contains our REST resources
    packages(PingResource.class.getPackage().getName());
}

我现在所做的是在构造函数的底部添加以下行:

ObjectMapper tmpMapper = new ObjectMapper();
tmpMapper.registerModule(new JavaTimeModule());
JacksonJaxbJsonProvider tmpProvider = new JacksonJaxbJsonProvider();
tmpProvider.setMapper(tmpMapper);
register(tmpProvider);

DateTime转换现在有效。但是,一些JAXB行为发生了变化,导致其他bean的反序列化中断。以下是不再适用的内容:

我有超类,它定义了一个字段的getter:

public abstract class SuperClass {
   @XmlElement(name = "yourField")
   public abstract String getMyField();
}

(这会将字段的内部名称映射到暴露给外部的不同名称)

public class SubClass {
    private String myField;

    @Override
    public String getMyField() {
        return myField;
    }
}

这种机制以前用过,我可以用定义SubClass类型的POST参数,使用如下所示的JSON片段调用该方法:

{
    "yourField" : "hello world"
}

现在尝试这个时,我得到了例外:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "yourField" (class com.myProject.SubClass), not marked as ignorable (1 known property: "myField"])
at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@728b1889; line: 4, column: 14] (through reference chain: com.myProject.Subclass["yourField"])

但请注意,基本的JAXB功能仍然有效,仅在此特定的超类/子类示例中。

是否明确注册JacksonJaxbJsonProvider以某种方式改变了如何处理JAXB注释bean的默认行为?有没有办法可以检索现有的JacksonJaxbJsonProvider(必须以某种方式隐式注册)或现有的ObjectMapper对象并注册JavaTimeModule而不是创建新的Mapper对象和一个新的Provider对象?

0 个答案:

没有答案