Jackson 2错误地序列化Java java.nio.file.Path

时间:2016-11-11 23:30:26

标签: json serialization jackson resteasy

我在Eclipse 4.6.1中使用RESTEasy 3.1.0.CR3和Tomcat 8.5.6,以及JSBoss resteasy-jackson2-provider。我有一个简单的JavaBean FooBar,它返回一个字符串“ID”和一个java.nio.file.Path“路径”。

Jackson使这很容易序列化为JSON。在我的JAX-RS资源中,我只需指定@Produces("application/json; charset=UTF-8")。但杰克逊没有使用Path.toString()。相反,它似乎使用Path.toURI().toString()或其他东西:

{
  "id": "foo",
  "path": "file:///C:/Users/jdoe/bar"
}

为什么!?更重要的是,我怎样才能让杰克逊只使用toString()的{​​{1}}版本?

这是我的项目依赖树:

Path

请注意,

p>

我想要一个简单的方法来挂接RESTEasy中的Jackson2并修改+- com.google.code.findbugs:jsr305:jar:3.0.1:provided +- com.google.guava:guava:jar:20.0:compile +- javax.ws.rs:javax.ws.rs-api:jar:2.0.1:provided +- org.jboss.resteasy:resteasy-jaxrs:jar:3.1.0.CR3:compile | +- org.jboss.spec.javax.ws.rs:jboss-jaxrs-api_2.0_spec:jar:1.0.1.Beta1:compile | +- org.jboss.resteasy:resteasy-jaxrs-services:jar:3.1.0.CR3:compile | +- org.jboss.spec.javax.annotation:jboss-annotations-api_1.2_spec:jar:1.0.0.Final:compile | +- javax.activation:activation:jar:1.1.1:compile | +- org.apache.httpcomponents:httpclient:jar:4.5.2:compile | | +- org.apache.httpcomponents:httpcore:jar:4.4.4:compile | | +- commons-logging:commons-logging:jar:1.2:compile | | \- commons-codec:commons-codec:jar:1.9:compile | +- commons-io:commons-io:jar:2.5:compile | +- net.jcip:jcip-annotations:jar:1.0:compile | \- org.jboss.logging:jboss-logging:jar:3.3.0.Final:compile +- org.jboss.resteasy:resteasy-servlet-initializer:jar:3.1.0.CR3:compile +- org.jboss.resteasy:resteasy-jackson2-provider:jar:3.1.0.CR3:compile | +- com.fasterxml.jackson.core:jackson-core:jar:2.8.3:compile | +- com.fasterxml.jackson.core:jackson-databind:jar:2.8.3:compile | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.8.3:compile | \- com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:jar:2.8.3:compile | +- com.fasterxml.jackson.jaxrs:jackson-jaxrs-base:jar:2.8.3:compile | \- com.fasterxml.jackson.module:jackson-module-jaxb-annotations:jar:2.8.3:compile +- junit:junit:jar:4.12:test | \- org.hamcrest:hamcrest-core:jar:1.3:test \- org.hamcrest:hamcrest-library:jar:1.3:test 属性值的序列化,而无需修改我的类或为我的类编写自定义序列化器。

1 个答案:

答案 0 :(得分:3)

此类将覆盖默认的Jackson2JsonProvider,帮助您根据需要配置ObjectMapper,就像Path.class的序列化程序从NioPathSerializer覆盖ToStringSerializer。

@Provider
@Consumes({"application/*+json", "text/json"})
@Produces({"application/*+json", "text/json"})
public class CustomJacksonProvider extends JacksonJsonProvider {

  public CustomJacksonProvider(){
    super(configureMapper(new ObjectMapper()));
  }

  public static ObjectMapper configureMapper(ObjectMapper mapper) {
    SimpleModule m = new SimpleModule("PathToString");
    m.addSerializer(Path.class,new ToStringSerializer());
    mapper.registerModule(m);
    return mapper;
  }

}

或者你也可以使用ContextResolver来使用ResteasyJackson2Provider( RestEasy默认

@Provider
@Consumes({"application/*+json", "text/json"})
@Produces({"application/*+json", "text/json"})
public class CustomJacksonProvider implements ContextResolver<ObjectMapper> {

  final ObjectMapper mapper;

  public CustomJacksonProvider(){
    mapper = new JsonMapperConfigurator(new ObjectMapper(), JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS)
            .getConfiguredMapper();
    SimpleModule m = new SimpleModule("PathToString");
    m.addSerializer(Path.class, new ToStringSerializer());
  }

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

无论您使用何种方式,都可以将此web.xml添加给您:

    <context-param>
       <param-name>resteasy.providers</param-name>
       <param-value>package.to.CustomJacksonProvider</param-value>
    </context-param>

如果您没有使用web.xml文件,请在JAX-RS应用程序的Application.getClasses()方法中返回提供程序类。

希望这有帮助。

<强>被修改

此外,在此实现中您可能会错过JAXB注释支持,您必须手动配置,因为JacksonJaxbJsonProvider并不寻找JsonMapperConfigurator的解析器/提供程序。将JsonMapperConfigurationCustomJackosnProvider中的映射器一起使用JacksonJaxbJsonProvider.DEAFULT_ANNOATIONS。理想情况下,由于没有规定提供JsonMapperConfiguration解析器/提供商和RestEasy的杰克逊提供商不公开arg构造函数,提供商是最好的选择。由于他们做出了这个决定,理想情况下他们不应该在ResteasyJackson2Provider中进行任何自定义。此外,只有ResteasyJackson2Provider中的功能是自定义json类型,并且在类级别更好地缓存mapper。

根据说明更新了代码