当前位置: 首页 > 知识库问答 >
问题:

如何在我的客户机中注册我的自定义MessageBodyReader?

易弘阔
2023-03-14

也许有人能帮我找到解决办法。

我使用的是jersey apache客户端1.17

我尝试使用泽西客户端构建一个独立的应用程序(没有Servlet容器或其他什么,只是Java类),它与RESTFUL API通信,一切都很好,直到我尝试处理媒体类型“text/csv; charset=utf-8”,这是服务器发送的CSV流。

问题是,我可以用以下代码读取此流:

    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中。但是写了这段代码后,我就是不能让客户端使用以下类:

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客户机中实现这一功能的首选方法是使用以下代码注册消息体读取器:

将实体提供者与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。我必须从一个以另一种方式构造客户机的特定类进行扩展,而我无权更改该构造。

因此,当我从服务器收到响应时,客户端失败,出现以下异常:

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吗?

共有1个答案

胡新
2023-03-14

好啊如果有人碰到我的问题,我从泽西1.17升级到2.9版,解开了这个谜团。我上面链接的文档也涵盖了这个版本,而不是旧版本,这就是困惑的根源。

Jersey从版本2开始引入了向后不兼容的更改,所以我不知道如何在版本1.17中配置它。

在版本2中,提议的解决方案运行良好。

 类似资料:
  • 我正在编写一个oauth2提供程序,不确定如何实现客户端注册。oauth2规范没有涵盖这方面: 客户端向授权服务器注册的方法超出了本规范的范围,但通常涉及终端用户与HTML注册表单的交互。 此外,文档对数据模型有以下说明: 通常的做法是将每个客户端与一个现有用户链接起来。无论是否将客户端和用户关联,都要确保能够保护自己免受恶意客户端的攻击。 null

  • 问题内容: 我想在定义类时注册一个类的实例。理想情况下,以下代码可以解决问题。 不幸的是,此代码生成错误。 发生的事情是在我尝试实例化a的行上,但装饰器尚未返回,因此它不存在。 是否使用元类解决了这个问题? 问题答案: 是的,元类可以做到这一点。元类的方法返回该类,因此只需在返回之前注册该类。 前面的示例在Python 2.x中有效。在Python 3.x中,的定义略有不同(虽然未更改,但未显示-

  • 显然,可以创建一个TypeDef来根据方言切换实现。 我的问题是hibernate似乎没有识别它,值得注意的是,有一次我将“uuid-custom”作为类型中的静态字符串,并直接在中引用它,所以它并不是实际上不在类路径上。

  • 好的,在laravel 4中,如果我想添加自己的自定义类,例如:库\myFunction.php然后我执行以下步骤: 添加myFunctions.php到app/库/myFunctiosn.php 在app/start/global.php,在ClassLoader::addDirectory(数组(,我添加app_path()。 为了在我的刀片视图中调用它,我添加了以下代码 它是有效的。 但是如

  • 在我的应用程序中,我必须知道,从一个列表中有一个服务器地址,这些地址是向上的。我发现的解决方案是从Spring引导执行器调用健康endpoint,对它们每个。JSon reponse是: 在应用程序的其他部分,我使用Spring-Cloud中的Feign客户机,这些客户机使用注释定义,它工作得很好: 不幸的是,这种配置不允许重用同一个客户机来调用不同地址上的同一个endpoint。因此,我必须定义