在 Jax-RS 应用程序中注册 JodaModule

Register JodaModule in Jax-RS Application

我正在使用 Jersey 和 Jackson2 编写 Jax-RS 应用程序以促进 JSON i/o。该服务本身运行良好,但我想通过让 Jackson 映射器自动 serialize/deserialize JodaTime 对象的日期和日期时间来改进它。

我正在按照文档 here 进行操作并添加了相关的 jar,但我对这条指令感到困惑:

Registering module

To use Joda datatypes with Jackson, you will first need to register the module first (same as with all Jackson datatype modules):

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());

我曾尝试在扩展 jax.ws.rs.core.Application 的自定义 class 中执行此操作,但我对该解决方案一点信心都没有。我目前收到此错误:

Can not instantiate value of type [simple type, class org.joda.time.DateTime] from String value ('2014-10-22'); no single-String constructor/factory method
 at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@3471b6d5; line: 7, column: 25]

除了这个模块注册需要在应用程序(servlet?)启动时发生的一般印象之外,我不知道如何处理这些信息。我是否需要用一些特别的东西来注释自定义 class 才能将其拾取?我应该延长一些 class 吗?

我在 Whosebug 上找到的示例通常将其粘贴在 main() 中并直接调用映射器,但我依赖于 Jackson Databinding,因此示例不相关。任何方向表示赞赏。

您基本上想要 create/configure/return 中的 ObjectMapper。像

@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {

    final ObjectMapper mapper = new ObjectMapper();

    public ObjectMapperContextResolver() {
        mapper.registerModule(new JodaModule());
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return mapper;
    }  
}

如果您正在使用包扫描来发现您的资源,那么 @Provider 注释应该允许此 class 也被发现和注册。

基本上发生的事情,就是MessageBodyReader and MessageBodyWriter provided by Jackson, used for unmarshalling and marshalling, respectively, will call the getContext method in the ContextResolver, to determine the ObjectMapper to use. The reader/writer will pass in the class (in a reader it will be the type expected in a method param, in a writer it will be the type returned as-a/in-a response), meaning we are allowed to use differently configured ObjectMapper for different classes, as 。在上面的解决方案中,它用于所有 classes.