我无法找出 SEVERE 背后的问题:Java 类 java.lang.Boolean 和 Java 类型类 java.lang.Boolean 和 MIME 媒体类型 application/json 的消息正文编写器是未找到
。
这是我尝试过的:
- 使用
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 中。对我来说不确定的一个方面是哪个包/类实际上为 boolean 值提供消息正文编写器?
添加了赏金,因为这会阻止我在我们的生产环境中运行,我们确实需要解决这个问题。
最佳答案
我假设您正在创建一个大的 jar
文件,其中包含您的类和所有其他依赖项。如果这是正确的(也只有一个提供者的发布异常导致我做出这个假设)然后确保来自您的依赖项的所有 javax.ws.rs.ext.MessageBodyReader
(和 javax.ws.rs.ext.MessageBodyWriter
)文件被组合在一起,而不仅仅是被已添加的最新 jar 中的文件替换给你 super jar 。
确保 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 运行时使用的类(即从输入/输出读取/写入实体)。创建 uber-jar 的问题是您还需要将相同服务的内容(由依赖项中 META-INF/services/
中具有相同名称的文件定义)合并到一个文件中并将其捆绑到您的可执行 jar 中(即合并 META-INF/services/javax.ws.rs.ext.MessageBodyReader
来自 jersey-core
和jersey-json
并将其存储在您的 jar 中的 META-INF/services/javax.ws.rs.ext.MessageBodyReader
中)。
如果是 Jersey,您可以像其他地方提到的那样使用 jersey-bundle
,但要确保来自 META-INF/services
的 jersey-bundle
文件在生成的 jar 中。
关于java - 部署时 java.lang.Boolean 的 Jersey 正文编写器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19283039/