部署时java.lang.Boolean的Jersey正文编写器错误 [英] Jersey body writer errors for java.lang.Boolean when deployed
问题描述
我无法找到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
背后的问题.
I'm having trouble hunting down the the problem behind 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添加为依赖项
- using
jersey-bundle
instead of these individual packages - POJOMappingFeature is already enabled
- Adding Jackson as a dependency
我不清楚我还需要做什么.这在本地运行良好,所以我不清楚为什么没有在应用程序的其余部分中打包一两个依赖项.
I'm unclear on what else I need to do. This runs fine locally, so I'm unclear on why a dependency or two are not being packaged with the rest of the application.
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 {
}
我已经通过软件包日志验证了我的jar中包含jersey-json.对我来说,不确定的一个方面是哪个包/类实际上为Boolean提供了消息正文编写器?
I've verified that via the package log that jersey-json is being included in my jar. One area of uncertainty for me is which package/class actually provides the message body writer for Boolean?
赏金,因为这使我无法在生产环境中运行,我们确实需要解决此问题.
Bounty was added because this is preventing me from running in our production environment and we really need this resolved.
推荐答案
我假设您正在创建一个大的jar
文件,其中包含您的类和所有其他依赖项.如果这是正确的(同样只有一个提供程序的异常发布使我想到了这一假设),那么请确保依赖项中的所有javax.ws.rs.ext.MessageBodyReader
(和javax.ws.rs.ext.MessageBodyWriter
)文件都合并在一起,而不仅仅是被最新jar中的文件代替已添加到您的uber-jar中.
I assume that you're creating a one big jar
file that contains your classes and all other dependencies. If this is correct (also the posted exception with only one provider leads me to this assumption) then make sure that all javax.ws.rs.ext.MessageBodyReader
(and javax.ws.rs.ext.MessageBodyWriter
) files from your dependencies are combined together and not just replaced by ones from the latest jar that has been added to you uber-jar.
确保uber-jar(在META-INF\services
中)的javax.ws.rs.ext.MessageBodyWriter
文件包含jersey-json
中存在的该文件中的提供程序:
Make sure that your javax.ws.rs.ext.MessageBodyWriter
file in the uber-jar (in META-INF\services
) contains providers from this file that is present in 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
),最后一个在您的情况下尤其重要.
The last one is especially important in your case since you're using Jackson as your JSON provider (by setting POJOMappingFeature
to true
).
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中(即合并jersey-core
和jersey-json
中存储,然后将其存储在您的jar中的META-INF/services/javax.ws.rs.ext.MessageBodyReader
中.
Many modules in Jersey 1.x uses META-INF/services
mechanism to lookup for JAX-RS provides (i.e. MessageBodyReader
s, ...). This means that you can find a service file in a jar (i.e. jersey-json.jar!META-INF/services/javax.ws.rs.ext.MessageBodyReader
) in which are defined classes that Jersey runtime uses (i.e. to read/write entity from/to input/output). The issue with creating an uber-jar is that you also need to combine contents of same services (defined by the files with same name in META-INF/services/
in your dependencies) into one file and bundle it into your executable jar (i.e. combine META-INF/services/javax.ws.rs.ext.MessageBodyReader
from jersey-core
and jersey-json
and store it in META-INF/services/javax.ws.rs.ext.MessageBodyReader
in your jar).
对于泽西岛,您可以使用其他地方提到的jersey-bundle
,但请确保来自jersey-bundle
的META-INF/services
文件位于您生成的jar中.
In case of Jersey you can use jersey-bundle
as mentioned elsewhere but make sure the META-INF/services
files from jersey-bundle
are in your resulting jar.
这篇关于部署时java.lang.Boolean的Jersey正文编写器错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!