4

我在追查背后的问题时遇到了麻烦SEVERE: A message body writer for Java class java.lang.Boolean, and Java type class java.lang.Boolean, and MIME media type application/json was not found

这是我尝试过的:

  • 使用jersey-bundle而不是这些单独的包
  • POJOMappingFeature 已启用
  • 将 Jackson 添加为依赖项

我不清楚我还需要做什么。这在本地运行良好,所以我不清楚为什么一两个依赖项没有与应用程序的其余部分一起打包。

pom.xml

    <jersey-version>1.17.1</jersey-version>

...

    <!-- Jersey -->
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-server</artifactId>
        <version>${jersey-version}</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-servlet</artifactId>
        <version>${jersey-version}</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>${jersey-version}</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey.contribs</groupId>
        <artifactId>jersey-spring</artifactId>
        <version>${jersey-version}</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

Jersey Servlet

//add jersey servlet support
ServletRegistration jerseyServletRegistration = ctx.addServlet("JerseyServlet", new SpringServlet());
jerseyServletRegistration.setInitParameter("com.sun.jersey.config.property.packages", "com.company.product.resource");
jerseyServletRegistration.setInitParameter("com.sun.jersey.spi.container.ContainerResponseFilters", "com.company.product.resource.ResponseCorsFilter");
jerseyServletRegistration.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature", Boolean.TRUE.toString());
jerseyServletRegistration.setInitParameter("com.sun.jersey.config.feature.DisableWADL", Boolean.TRUE.toString());
jerseyServletRegistration.setInitParameter("org.codehaus.jackson.map.DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY", Boolean.TRUE.toString());
jerseyServletRegistration.setLoadOnStartup(1);

我的构建过程

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals><goal>shade</goal></goals>
                    <configuration>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <mainClass>com.company.product.Main</mainClass>
                            </transformer>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <skip>true</skip>
            </configuration>
        </plugin>

例外:

SEVERE: A message body writer for Java class java.lang.Boolean, and Java type class java.lang.Boolean, and MIME media type application/json was not found
SEVERE: The registered message body writers compatible with the MIME media type are:
*/* ->
  com.sun.jersey.server.impl.template.ViewableMessageBodyWriter

产生错误的代码:

@Path("/system")
public class SystemResource extends BaseResource {
    @GET
    @Path("/isOnline")
    public Boolean isOnline () {
        return Boolean.TRUE;
    }
}

@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public class BaseResource {

}

我已经通过包日志验证了 jersey-json 包含在我的 jar 中。对我来说不确定的一个领域是哪个包/类实际上为布尔值提供了消息正文编写器?

添加了赏金,因为这阻止了我在我们的生产环境中运行,我们真的需要解决这个问题。

4

4 回答 4

4

我假设您正在创建一个jar包含您的类和所有其他依赖项的大文件。如果这是正确的(也只有一个提供者的发布异常让我做出了这个假设)然后确保你的依赖项中的所有javax.ws.rs.ext.MessageBodyReader(和javax.ws.rs.ext.MessageBodyWriter)文件都组合在一起,而不仅仅是被添加到你的最新 jar 中的文件替换超级罐子。

确保您javax.ws.rs.ext.MessageBodyWriter在 uber-jar (in META-INF\services) 中的文件包含来自该文件的提供程序,该文件存在于jersey-json

com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$Wadl
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General
com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$App
com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$General
com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$App
com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$General
com.sun.jersey.json.impl.provider.entity.JSONWithPaddingProvider
com.sun.jersey.json.impl.provider.entity.JacksonProviderProxy

最后一个在您的情况下特别重要,因为您使用 Jackson 作为 JSON 提供程序(通过设置POJOMappingFeaturetrue)。

编辑 1

Jersey 1.x 中的许多模块使用META-INF/services查找 JAX-RS 提供的机制(即MessageBodyReaders,...)。这意味着您可以在 jar(即jersey-json.jar!META-INF/services/javax.ws.rs.ext.MessageBodyReader)中找到一个服务文件,其中定义了 Jersey 运行时使用的类(即从输入/输出读取/写入实体)。创建 uber-jar 的问题是您还需要将相同服务的内容(由META-INF/services/依赖项中具有相同名称的文件定义)组合到一个文件中,并将其捆绑到您的可执行 jar 中(即组合META-INF/services/javax.ws.rs.ext.MessageBodyReaderjersey-core存储jersey-json它在META-INF/services/javax.ws.rs.ext.MessageBodyReader你的罐子里)。

如果是泽西岛,您可以jersey-bundle按照其他地方所述使用,但请确保META-INF/services来自的文件jersey-bundle位于生成的 jar 中。

于 2013-10-15T12:50:39.910 回答
1

尝试包括杰克逊:

<jackson.version>1.9.12</jackson.version>
...
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-core-asl</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-jaxrs</artifactId>
        <version>${jackson.version}</version>
    </dependency>
于 2013-10-10T13:59:32.460 回答
1

在 jar 创建期间覆盖META-INF/services似乎是根本原因(如第一个答案中所述)。在我的情况下添加:

<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>

<transformers>pom.xml 中的 maven-shade-plugin的配置已经解决了这个问题。包括一个完整的jersey-bundle似乎是一个矫枉过正。

于 2014-06-04T22:37:38.893 回答
0

无需添加 3rd-party 库,因为它已包含在 jersey-json 包中。代码似乎不对,应该是:

@Path("/system")
public class SystemResource extends BaseResource {
    @GET
    @Path("/isOnline")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    public Boolean isOnline () {
        return Boolean.TRUE;
    }
}

public class BaseResource {

}
于 2013-10-15T02:31:19.140 回答