Java 在哪里为我的REST服务应用程序注册自定义ObjectMapper?
我正在用Spring和Jersey构建一个REST服务应用程序 “响应内容类型”可以是JSON或XML,这就是为什么我在POJO的字段上使用JAXB注释的原因,到目前为止效果很好。不需要配置就可以工作,我只是将必需的.jar放在类路径上 现在,我想为Java8日期/时间对象的(反)序列化添加自定义行为,并从Jackson注册Java 在哪里为我的REST服务应用程序注册自定义ObjectMapper?,java,spring,jaxb,jersey,jackson,Java,Spring,Jaxb,Jersey,Jackson,我正在用Spring和Jersey构建一个REST服务应用程序 “响应内容类型”可以是JSON或XML,这就是为什么我在POJO的字段上使用JAXB注释的原因,到目前为止效果很好。不需要配置就可以工作,我只是将必需的.jar放在类路径上 现在,我想为Java8日期/时间对象的(反)序列化添加自定义行为,并从Jackson注册JavaTimeModule 注册模块的正确地点在哪里?我知道代码片段应该是这样的: ObjectMapper tmpMapper = new ObjectMapper();
JavaTimeModule
注册模块的正确地点在哪里?我知道代码片段应该是这样的:
ObjectMapper tmpMapper = new ObjectMapper();
tmpMapper.registerModule(new JavaTimeModule());
@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());
}
{
"yourField" : "hello world"
}
但是我应该把这个代码放在哪里呢
我想到的地方是泽西岛的ResourceConfig
类。看起来是这样的:
ObjectMapper tmpMapper = new ObjectMapper();
tmpMapper.registerModule(new JavaTimeModule());
@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());
}
{
"yourField" : "hello world"
}
我现在做的是在构造函数的底部添加以下行:
ObjectMapper tmpMapper = new ObjectMapper();
tmpMapper.registerModule(new JavaTimeModule());
JacksonJaxbJsonProvider tmpProvider = new JacksonJaxbJsonProvider();
tmpProvider.setMapper(tmpMapper);
register(tmpProvider);
日期时间转换现在起作用了。然而,一些JAXB行为发生了变化,这导致其他bean的反序列化中断。以下是不再有效的内容:
我有一个超类,它定义了一个字段的getter:
public abstract class SuperClass {
@XmlElement(name = "yourField")
public abstract String getMyField();
}
(这会将字段的内部名称映射到暴露在外部的不同名称)
这种机制以前是有效的,例如,我可以定义一个SubClass类型的POST参数,用一个JSON片段调用该方法,如下所示:
ObjectMapper tmpMapper = new ObjectMapper();
tmpMapper.registerModule(new JavaTimeModule());
@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());
}
{
"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对象?它仍然会给我相同的错误消息。我刚刚意识到,如果我也用@xmlement(name=“yourField”)注释子类中的字段,并且您说它在尝试使用自定义ObjectMapper之前工作,那么这种情况也会发生?是的。这就好像注释现在被忽略一样。请尝试向ObjectMapper注册JaxbAnnotationModule