部署时,对于java.lang.Boolean,Jersey body writer出错

时间:2013-10-09 21:24:38

标签: java jersey

我无法找到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
  • 添加杰克逊作为依赖

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

的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中。对我来说,一个不确定的领域是哪个包/类实际上为布尔提供了消息体编写器?

添加了

Bounty ,因为这阻止了我在我们的生产环境中运行,我们确实需要解决这个问题。

4 个答案:

答案 0 :(得分:4)

我假设您正在创建一个包含您的类和所有其他依赖项的大jar文件。如果这是正确的(也是只有一个提供商的发布的例外导致我这个假设),那么请确保来自您的依赖项的所有javax.ws.rs.ext.MessageBodyReader(和javax.ws.rs.ext.MessageBodyWriter)文件组合在一起而不是仅仅替换为1来自最新的罐子,已添加到你的超级罐子里。

确保uber-jar中的javax.ws.rs.ext.MessageBodyWriter文件(位于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提供者(通过将POJOMappingFeature设置为true)。

编辑1

Jersey 1.x中的许多模块使用META-INF/services机制来查找JAX-RS提供的内容(即MessageBodyReader s,...)。这意味着您可以在jar(即jersey-json.jar!META-INF/services/javax.ws.rs.ext.MessageBodyReader)中找到一个服务文件,其中包含Jersey运行时使用的定义类(即从/向输入/输出读/写实体)。创建超级jar的问题在于,您还需要将相同服务的内容(由依赖项中META-INF/services/中具有相同名称的文件定义)组合到一个文件中,并将其捆绑到可执行jar中(即组合来自META-INF/services/javax.ws.rs.ext.MessageBodyReaderjersey-core的{​​{1}}并将其存储在您的广告素材中的jersey-json中。

如果是泽西岛,您可以使用其他地方提到的META-INF/services/javax.ws.rs.ext.MessageBodyReader,但请确保jersey-bundle中的META-INF/services个文件位于您生成的广告文件中。

答案 1 :(得分: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>

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:0)

无需添加第三方库,因为它已包含在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 {

}