My first web client giving “MessageBodyWriter not found for media type…” (JSON)

强颜欢笑 提交于 2019-12-11 04:43:50

问题


I'll give you the short story first. If I, in Eclipse, export my jar file with jar files (the Runnable Jar wizard and select "Package required libraries...") instead of "Extract required libraries", every thing works, but it is excruciatingly slow to get going. If I build my jar with the extracting method the code will cause an eventual

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=application/json

I'm not using Maven. I don't know it yet. I am mostly inexperienced with Eclipse for the most part, but I am getting there. I thought Genson would give me what I need to create JSON.

If I list my jar file and grep for MessageBodyWriter, I get

1220 Tue Nov 15 10:29:02 CST 2016 javax/ws/rs/ext/MessageBodyWriter.class             
  47 Tue Nov 15 10:29:02 CST 2016 META-INF/services/javax.ws.rs.ext.MessageBodyWriter 

To get to the longer story, I created a simple Java project in Eclipse, added external jars to my build path. Eclipse doesn't complain about anything missing. There is only one or two warnings about unused this-and-thats in my code. The export works fine either way I do it, no problems. Only execution reveals some irritation.

In my request class, I believe I have set up everything correctly. This is the simplest POST client imaginable. I have the requisite empty constructor, the correct annotations.

@XmlRootElement
@Produces(MediaType.APPLICATION_JSON)

public class QQNotificationRequest {

    @JsonProperty("id")
    private int id;
    @JsonProperty("subId")
    private int subId;
    @JsonProperty("type")
    private int type;
    @JsonProperty("scode")
    private int scode;
    @JsonProperty("datetime")
    private String datetime;
    ...

This is my ultimate call that fails

Response resp = m_webTarget.request(MediaType.APPLICATION_JSON).post(Entity.json(message));

These are my external jars

javax.ws.rs-api-2.0.1.jar
aopalliance-repackaged-2.5.0-b05.jar
hk2-api-2.5.0-b05.jar
hk2-locator-2.5.0-b05.jar
hk2-utils-2.5.0-b05.jar
javassist-3.20.0-GA.jar
javax.annotation-api-1.2.jar
javax.inject-2.5.0-b05.jar
javax.servlet-api-3.0.1.jar
jaxb-api-2.2.7.jar
jersey-guava-2.24.jar
org.osgi.core-4.2.0.jar
osgi-resource-locator-1.0.1.jar
persistence-api-1.0.jar
validation-api-1.1.0.Final.jar
jersey-client.jar
jersey-common.jar
jersey-container-servlet.jar
jersey-container-servlet-core.jar
jersey-media-jaxb.jar
jersey-server.jar
jargs.jar
genson-1.4.jar
jt400.jar
log4j-api-2.7.jar
log4j-core-2.7.jar

I feel like there is something in the jar that isn't being 'exported' correctly, but I'm not sure. Just guessing here that because Java has to go through the process of exploding all of the jars inside the big jar, that it finds what it needs to begin execution, whereas with the .classes inside the big jar, it doesn't.

Lost for the moment, but plugging along. I appreciate any pointers.


回答1:


The problem is that there are files in the META-INF/services directory of each Jersey jar, that need to be present at runtime. These files are used to automatically load and register provider classes.

When all the jars are kept separate and just add to the classpath, all the files remain in tact. But when you create a single jar, those files overlap (they all have the same name), so only one of each file with the same name will be included. So the file with Genson is probably not the one included.

You could just explicitly register Genson as a provider with the application. I don't really use Genson, so I'm not sure the correct way to do this. But quickly looking through the codebase, it looks like you need to register the GensonJsonConverter.

This may work, but it doesn't solve the main problem about the services files not being included. There may be other automzatically registered components that aren't being registered.

I'm not really an Eclipse user, so I'm not sure how to fix this problem. I know that if you are using Maven, you would use the maven-shade-plugin, as mentioned here. What this plugin would do is concatenate all the files content into one single file. This would solve the problem.

So I guess this is only really half the answer, since I am not sure how to do something similar when using Eclipse. But at least you know the problem now.

FYI, this file, is the one you are mainly concerned about. If you look through other Jersey jars, you will see that there are similar files. This is what I'm talking about when I say only one will be used. You need to find a way to concatenate their contents into one file when you build the jar



来源:https://stackoverflow.com/questions/40615573/my-first-web-client-giving-messagebodywriter-not-found-for-media-type-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!