需要一种方法从 JAX RS 服务中的 List<Map<String,String> 生成 JSON。 杰克逊2



在我的POM.xml中有以下内容更新完整的pom:

<dependencies>
                <dependency>
                <groupId>org.glassfish.jersey.containers</groupId>
                <artifactId>jersey-container-servlet</artifactId>
                <version>2.19</version>
            </dependency>
            <dependency>
                <groupId>org.glassfish.jersey.media</groupId>
                <artifactId>jersey-media-json-jackson</artifactId>
                <version>2.19</version>
            </dependency>
            <!-- <dependency>
                <groupId>org.glassfish.jersey.media</groupId>
                <artifactId>jersey-media-moxy</artifactId>
                <version>2.19</version>
            </dependency> -->

            <dependency>
                <groupId>org.mvel</groupId>
                <artifactId>mvel2</artifactId>
                <version>2.2.1.Final</version>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.0</version>
            </dependency>
            <dependency>
                <groupId>com.google.code.gson</groupId>
                <artifactId>gson</artifactId>
                <version>2.2.4</version>
            </dependency>
            <dependency>
                <groupId>org.apache.drill.exec</groupId>
                <artifactId>drill-jdbc-all</artifactId>
                <version>1.1.0</version>
            </dependency>

        </dependencies>

我想从List<Map<String,String>>生成一个JSON。最后总是得到MessageBodyWriter not found for media type=application/json, type=class java.util.LinkedHashMap, genericType=jav a.util.Map<String,String>

我甚至尝试用简单的map

@GET
      @Path("/test")
      @Produces(MediaType.APPLICATION_JSON)
      public Map<String, String> getMap() {
          Map<String, String> map = new HashMap<String, String>();
          map.put("some key", "some value");
          return map;
      }

即使这样也会产生相同的错误信息。

更新异常堆栈跟踪:

Jul 29, 2015 9:23:29 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [CustomerDataService] in context with path [/CustomerDataService] threw exception 
[org.glassfish.jersey.server.ContainerException: java.lang.AbstractMethodError: com.fasterxml.jackson.jaxrs.json.Jackson
JaxbJsonProvider.isWriteable(Ljava/lang/Class;Ljava/lang/reflect/Type;[Ljava/lang/annotation/Annotation;Ljavax/ws/rs/cor
e/MediaType;)Z] with root cause
java.lang.AbstractMethodError: com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider.isWriteable(Ljava/lang/Class;Lja
va/lang/reflect/Type;[Ljava/lang/annotation/Annotation;Ljavax/ws/rs/core/MediaType;)Z
    at org.glassfish.jersey.message.internal.MessageBodyFactory.isWriteable(MessageBodyFactory.java:1158)
    at org.glassfish.jersey.message.WriterModel.isWriteable(WriterModel.java:86)
    at org.glassfish.jersey.message.internal.MessageBodyFactory._getMessageBodyWriter(MessageBodyFactory.java:798)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.getMessageBodyWriter(MessageBodyFactory.java:756)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterc
eptorExecutor.java:241)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
    at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:106)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
    at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInter
ceptor.java:86)

MOXy不能很好地处理地图,因为它在底层使用JAXB,而JAXB对地图的处理很糟糕。用杰克逊代替。摆脱对MOXy的依赖。MOXy是默认的,所以如果它在类路径上,它将被用于所有其他类路径。一旦你把它拿出来,Jackson就会被使用。


更新

所以drill-jdbc-all实际上重新包装了Jackson 1。x Jackson 2.x。您可以将它们从jersey-media-json-jackson依赖项中排除,因为drill已经包含了它们。

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.19</version>
    <exclusions>
        <exclusion>
            <groupId>com.fasterxml.jackson.jaxrs</groupId>
            <artifactId>jackson-jaxrs-base</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.fasterxml.jackson.jaxrs</groupId>
            <artifactId>jackson-jaxrs-json-provider</artifactId>
        </exclusion> 
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
        </exclusion>
    </exclusions>
</dependency>

更新2

我想以上仍然不起作用。我能够开始工作的一种方法是添加jackson-jaxrs-json-provider(您还需要取出jersey-media-json-jackson和jersey-media-moxy)。

<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.4.0</version>
</dependency>
<dependency>
    <groupId>org.apache.drill.exec</groupId>
    <artifactId>drill-jdbc-all</artifactId>
    <version>1.1.0</version>
</dependency>
关键是它必须在apache-jdbc-drill之前声明。是的,它看起来更像是一个工作,而不是一个解决方案。但是,drill打包依赖是一个问题。当Jersey扫描时,它会首先添加我们的,而忽略drill的。

然后您需要将提供程序添加到Jersey配置

<init-param>
    <param-name>jersey.config.server.provider.classnames</param-name>
    <param-value>
        com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider
    </param-value>
</init-param>

我的意思是我还没有测试过这10,000次,但是在我测试的10到20次中,依赖项的顺序是决定它是否有效的因素。再一次,就像我说的,这似乎是一个解决办法。

并将其添加到Jersey配置

不能序列化集合和映射。创建一个容器类。

例如:

@XmlRootElement
public class Container {
    public Map<String, String> data;
}
public Container getMap() {
      Map<String, String> map = new HashMap<String, String>();
      map.put("some key", "some value");
      // wrap content int container object
      Container container = new Container();
      container.data = map;
      return container ;
}

这个问题的原因是,XML总是必须有一个根元素

相关内容

最新更新