如何在我的 CLIENT 中注册我的自定义 MessageBodyReader? [英] How to register my custom MessageBodyReader in my CLIENT?
问题描述
也许有人可以帮我找出解决这个问题的方法.
Maybe somebody can help me find out how to solve this.
我正在使用 jersey-apache-client 1.17
I am using jersey-apache-client 1.17
我尝试使用 Jersey 客户端构建一个与 RESTFUL API 通信的独立应用程序(没有 Servlet 容器或其他任何东西,只有 Java 类),并且在我尝试处理媒体类型text/csv;charset"之前一切正常=utf-8" 是服务器发送的CSV流.
I tried to use Jersey client to build a standalone application (no Servlet container or whatever, just the Java classes) which communicates with a RESTFUL API, and everything worked fine until I tried to handle the mediatype "text/csv; charset=utf-8" which is a CSV stream sent by the server.
问题是我可以使用以下代码读取此流:
The thing is that I can read this stream with the following code:
InputStreamReader reader = new InputStreamReader(itemExportBuilder
.get(ClientResponse.class).getEntityInputStream());
Csv csv = new Csv();
Input input = csv.createInput(reader);
try {
String[] readLine;
while ((readLine = input.readLine()) != null) {
LOG.debug("Reading CSV: {}", readLine);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
但我想将其封装并放入 MessageBodyReader 中.但是写完这段代码,我就是不能让客户端使用下面的类:
But I'd like to encapsulate it and put it into a MessageBodyReader. But after writing this code, I just can't make the client use the following class:
package client.response;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Provider
public class ItemExportMessageBodyReader implements MessageBodyReader<ItemExportResponse> {
private static final Logger LOG = LoggerFactory.getLogger(ItemExportMessageBodyReader.class);
private static final Integer SKU = 0;
private static final Integer BASE_SKU = 1;
public boolean isReadable(Class<?> paramClass, Type type, Annotation[] annotations,
MediaType mediaType) {
LOG.info("Cheking if content is readable or not");
return paramClass == ItemExportResponse.class && !mediaType.isWildcardType()
&& !mediaType.isWildcardSubtype()
&& mediaType.isCompatible(MediaType.valueOf("text/csv; charset=utf-8"));
}
public ItemExportResponse readFrom(Class<ItemExportResponse> paramClass, Type paramType,
Annotation[] paramArrayOfAnnotation, MediaType paramMediaType,
MultivaluedMap<String, String> paramMultivaluedMap, InputStream entityStream)
throws IOException, WebApplicationException {
InputStreamReader reader = new InputStreamReader(entityStream);
Csv csv = new Csv();
Input input = csv.createInput(reader);
List<Item> items = new ArrayList<Item>();
try {
String[] readLine;
while ((readLine = input.readLine()) != null) {
LOG.trace("Reading CSV: {}", readLine);
Item item = new Item();
item.setBaseSku(readLine[BASE_SKU]);
items.add(item);
}
} catch (IOException e) {
LOG.warn("Item export HTTP response handling failed", e);
} finally {
try {
input.close();
} catch (IOException e) {
LOG.warn("Could not close the HTTP response stream", e);
}
}
ItemExportResponse response = new ItemExportResponse();
response.setItems(items);
return response;
}
}
以下文档说明了在 JAX-RS 客户端中使用以下代码注册消息正文阅读器的首选方法:
The following documentation says that the preferred way of making this work in a JAX-RS client to register the message body reader with the code below:
Client client = ClientBuilder.newBuilder().register(MyBeanMessageBodyReader.class).build();
Response response = client.target("http://example/comm/resource").request(MediaType.APPLICATION_XML).get();
System.out.println(response.getStatus());
MyBean myBean = response.readEntity(MyBean.class);
System.out.println(myBean);
现在的问题是我不能使用 ClientBuilder.我必须从以另一种方式构造客户端的特定类进行扩展,并且我无权更改构造.
Now the thing is that I can't use the ClientBuilder. I have to extend from a specific class which constructs the client another way, and I have no access to change the construction.
所以当我收到服务器的响应时,客户端失败并出现以下异常:
So when I receive the response from the server, the client fails with the following Exception:
com.sun.jersey.api.client.ClientHandlerException: A message body reader for Java class client.response.ItemExportResponse, and Java type class client.response.ItemExportResponse, and MIME media type text/csv; charset=utf-8 was not found
还有其他方法可以注册我的 MessageBodyReader 吗?
Any other way to register my MessageBodyReader?
推荐答案
好的.如果有人碰到我的问题,我通过从 Jersey 1.17 升级到 2.9 版解决了这个谜团.我上面链接的文档也涵盖了这个版本而不是旧版本,这就是混乱的根源.
OK. If anybody would bump into my question I solved this mystery by upgrading from Jersey 1.17 to version 2.9. The documentation I linked above also covers this version not the old one, this is where the confusion stems from.
Jersey 从版本 2 开始引入了向后的 INCOMPATIBLE 更改,所以我不知道如何在版本 1.17 中配置它.
Jersey introduced backward INCOMPATIBLE changes starting from version 2, so I have no clue how to configure it in version 1.17.
在第 2 版中,建议的解决方案运行良好.
In version 2 the proposed solution worked fine.
这篇关于如何在我的 CLIENT 中注册我的自定义 MessageBodyReader?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!