如何在我的客户端中注册我的自定义MessageBodyReader? [英] How to register my custom MessageBodyReader in my CLIENT?

查看:58
本文介绍了如何在我的客户端中注册我的自定义MessageBodyReader?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

也许有人可以帮助我找出解决方法.

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客户端来构建一个独立的应用程序(没有Servlet容器或其他任何东西,只有Java类),并与RESTFUL API进行通信,并且一切正常,直到我尝试处理"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:

将实体提供者与JAX-RS客户端API结合使用

            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开始引入了向后不可更改的更改,因此我不知道如何在版本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.

这篇关于如何在我的客户端中注册我的自定义MessageBodyReader?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆