我创建的胖jar在IDE(IntelliJ)中运行时正确地从文件返回json。但是,我作为一个罐子执行它有问题。这是一个带Guice的Dropwizard应用程序。我在build.gradle中有以下内容
jar {
manifest {
attributes "Implementation-Title": "Symphony Service"
attributes "Implementation-Version": '1.0'
attributes "Main-Class" : 'com.symphony.api.SymphonyService'
}
doFirst {
from (configurations.runtime.resolve().collect {
it.isDirectory() ? it : zipTree(it)
}) {
exclude 'META-INF/MANIFEST.MF'
exclude 'META-INF/*.SF'
exclude 'META-INF/*.DSA'
exclude 'META-INF/*.RSA'
}
}
}
这在我的控制器中。
@GET
@Path("/segments/{segmentid}/result")
@Produces(MediaType.APPLICATION_JSON)
public String result(@PathParam("segmentid") String segmentId) throws IOException {
String response = null;
URL url = Resources.getResource("response.json");
try {
response = Resources.toString(url, Charsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
IDE中的一切正常。但是,当我将其打包为jar然后运行它时,我得到以下错误:
ERROR [2014-03-12 05:13:44,304] com.sun.jersey.spi.container.ContainerResponse:Java类java.lang.String
的消息正文编写器和Java类型类java.lang.String
,找不到MIME媒体类型application / json
ERROR [2014-03-12 05:13:44,305] com.sun.jersey.spi.container.ContainerResponse:与MIME媒体类型兼容的已注册邮件正文编写者是: / - >
com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider
以下是我的MessageBodyWriter的SPI文件 -
META-INF / services / javax.ws.rs.ext.MessageBodyWriter:
com.sun.jersey.core.impl.provider.entity.StringProvider
com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
com.sun.jersey.core.impl.provider.entity.FileProvider
com.sun.jersey.core.impl.provider.entity.InputStreamProvider
com.sun.jersey.core.impl.provider.entity.DataSourceProvider
com.sun.jersey.core.impl.provider.entity.RenderedImageProvider
com.sun.jersey.core.impl.provider.entity.MimeMultipartProvider
com.sun.jersey.core.impl.provider.entity.FormProvider
com.sun.jersey.core.impl.provider.entity.FormMultivaluedMapProvider
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$App
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$Text
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$App
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$Text
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$App
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$Text
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
com.sun.jersey.core.impl.provider.entity.ReaderProvider
com.sun.jersey.core.impl.provider.entity.DocumentProvider
com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider
com.sun.jersey.core.impl.provider.entity.SourceProvider$SourceWriter
com.sun.jersey.server.impl.template.ViewableMessageBodyWriter
com.sun.jersey.atom.rome.impl.provider.entity.AtomFeedProvider
com.sun.jersey.atom.rome.impl.provider.entity.AtomEntryProvider
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
com.sun.jersey.fastinfoset.impl.provider.entity.FastInfosetRootElementProvider
com.sun.jersey.fastinfoset.impl.provider.entity.FastInfosetJAXBElementProvider
com.sun.jersey.fastinfoset.impl.provider.entity.FastInfosetListElementProvider
com.sun.jersey.core.impl.provider.entity.StringProvider
com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
com.sun.jersey.core.impl.provider.entity.FileProvider
com.sun.jersey.core.impl.provider.entity.InputStreamProvider
com.sun.jersey.core.impl.provider.entity.DataSourceProvider
com.sun.jersey.core.impl.provider.entity.RenderedImageProvider
com.sun.jersey.core.impl.provider.entity.MimeMultipartProvider
com.sun.jersey.core.impl.provider.entity.FormProvider
com.sun.jersey.core.impl.provider.entity.FormMultivaluedMapProvider
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$App
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$Text
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$App
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$Text
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$App
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$Text
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
com.sun.jersey.core.impl.provider.entity.ReaderProvider
com.sun.jersey.core.impl.provider.entity.DocumentProvider
com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider
com.sun.jersey.core.impl.provider.entity.SourceProvider$SourceWriter
com.sun.jersey.server.impl.template.ViewableMessageBodyWriter
com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider
我觉得这种情况正在发生,因为条目
com.sun.jersey.core.impl.provider.entity.StringProvider
在META-INF / services / javax.ws.rs.ext.MessageBodyWriter文件中重复。 当我从该文件中删除重复项后手动创建jar时,它可以正常工作。 我还没有找到一种方法来正确合并文件。尝试使用影子插件进行gradle但无法使其工作。
-Amith
修复:让gradle shadow插件正常工作,现在无需任何调整即可使用
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:0.8'
}
}
apply plugin: 'shadow'
jar {
manifest {
attributes "Implementation-Title": "Symphony Service"
attributes "Implementation-Version": '1.0'
attributes "Main-Class" : 'com.experian.symphony.api.SymphonyService'
}
/*excludes {
exclude 'META-INF/MANIFEST.MF'
exclude 'META-INF/*.SF'
exclude 'META-INF/*.DSA'
exclude 'META-INF/*.RSA'
} */
}
shadow {
destinationDir = 'build/distributions'
classifier = '1.0'
exclude 'META-INF/MANIFEST.MF'
exclude 'META-INF/*.SF'
exclude 'META-INF/*.DSA'
exclude 'META-INF/*.RSA'
}
答案 0 :(得分:0)
如果您在web.xml中设置此项,则表示您不会收到错误消息。如果映射基本类型,这就是我为克服这个问题所做的。
我认为基本问题是默认的MessageWriter使用jaxb注释(@XmlRootElement)来处理对象,因为像String,Number,Double,Integer等基类没有这些,你必须使用默认的pojo mapper将处理使用jackson的ObjectMapper类。您可以使用的其他选项是将String包装在另一个要返回的对象中,或者实现一个实现MessageBodyWriter<String>
的@Provider,它将字符串转换为json。希望这可以帮助。
https://jersey.java.net/documentation/1.18/json.html
Web.xml配置
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
Guice配置
@Override
protected void configureServlets() {
serve("/rest/v1/*").with(GuiceContainer.class, createJerseyParams());
}
private Map<String, String> createJerseyParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("com.sun.jersey.api.json.POJOMappingFeature", "true");
return params;
}