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

如何处理不服从Accept的web服务:使用Jersey和Jackson的application/json

奚无尘
2023-03-14

我使用泽西和杰克逊访问一个REST Web服务,它正确地返回格式良好的JSON数据,但具有响应头:

内容类型:文本/html;字符集=UTF-8

即使我在请求头中指定了接受:应用程序/json,结果导致泽西抛出:

org.glassfish.jersey.message.internal.MessageBodyProviderNotFound异常:找不到用于媒体类型=text/html; charset=UTF-8的MessageBodyReader

我用代码使用其他web服务,但我想知道是否有办法创建自己的MessageBodyReader来处理错误匹配,但我还没有找到正确实现它的方法。我计划要求web服务的所有者修复错误匹配,但我不抱太大希望。

共有2个答案

宗政天逸
2023-03-14

我想知道是否有一种方法来创建我自己的MessageBodyReader来处理错误匹配。

Jersey文档中的这一页解释了如何创建自定义MessageBodyReader:

  • https://jersey.java.net/documentation/latest/message-body-workers.html#d0e7151

在您的例子中,您可能能够找到通常用于JSON的阅读器的源代码,并对其进行“调整”。从理论上讲。

然而,在多读了一点之后,我发现了这个:

  • https://jersey.java.net/documentation/latest/media.html#json

这告诉我泽西已经对JSON有了广泛的支持。很有可能你可以通过简单地调整配置来解决这个问题,这样泽西就知道如何处理不寻常的内容类型。但是这将取决于你解析JSON响应体的多种可能方式中的哪一种...目前。

有人这样评论:

我认为,不管检索数据有多容易,都可以忽略标题并将其解析为json对象。

这是个坏主意。头告诉你JSON可能包含多字节字符。如果你只是忽略这一点,并将字节解码为默认字符集中的字符,如果存在多字节字符,你会得到“mojibake”。

如果您自己正在解析JSON,那么将解析器的输入流配置为使用UTF-8,或者内容类型头中表示的字符编码是什么,应该是一件简单的事情。

最后,是“谁错了”的问题。

实际上我认为这是你的错。如果你只发送一个“接受:应用程序/json”头,你就告诉服务器你不在乎字符集是什么。然后服务器可以自由地为它知道会正确代表响应文本的响应选择任何字符集。(在这种情况下是JSON的文本内容。)

如果您特别想要(比如)ASCII或Latin-1,那么您应该添加一个“Accept charset:”标题。

如果

潘琪
2023-03-14

好吧,所以我基本上按照斯蒂芬·C的建议设法弄明白了,但我想我会发布更多细节,以防其他人也在同一条船上。首先,我从《泽西岛指南》的几个章节开始,特别是这一节:

https://jersey.java.net/documentation/latest/user-guide.html#d0e6825

显然,我使用泽西javax.ws.rs.client,我使用Genson进行JSON反序列化。因此,我实现了以下类来实现MessageBodyReader:

public class BTCEURTradeMessageBodyReader 
        implements MessageBodyReader<BTCEURTrades> {

  final org.slf4j.Logger logger = 
          LoggerFactory.getLogger(BTCEURTradeMessageBodyReader.class);

  @Override
  public boolean isReadable(Class<?> type, Type genericType, 
          Annotation[] annotations, MediaType mediaType) {
    logger.info("isReadable being checked for: {} and media type: {}", type, mediaType);
    return type == BTCEURTrades.class;
  }

  @Override
  public BTCEURTrades readFrom(Class<BTCEURTrades> type, Type genericType, 
          Annotation[] annotations, MediaType mediaType, 
          MultivaluedMap<String, String> httpHeaders, InputStream entityStream) 
          throws IOException, WebApplicationException {
    logger.info("readFrom being called for: {}", type);

    BTCEURTrades btceurTrades;
    try {
      btceurTrades = new Genson().deserialize(entityStream, type);
    } catch(Exception e) {
      logger.error("Error processing JSON reponse.", e);
      throw new ProcessingException("Error processing JSON reponse.");
    }
    return btceurTrades;
  }

}

然后,在创建后,它会按照如下方式向客户端注册:

client = ClientBuilder.newClient();
client.register(BTCEURTradeMessageBodyReader.class);
 类似资料:
  • 我知道有这么多关于这个的问题...但是它们不适合我,我尝试在eclipse中重新安装maven(因为创建一个新的maven项目或转换一个现有的动态web项目给我的pom.xml错误),但它一直说已经安装了...所以我质疑这样一个事实,即不使用maven就可以从rest web服务获得json吗?我已经从ws中获得了string/xml/html,现在我创建了一个新类,如下所示: 我还引用了这些库:

  • 问题内容: 这是我的网络服务(我正在使用Jersey API)。但是我想不通一种方法,可以从Java Rest客户端调用此方法来发送和接收json数据。我尝试了以下方式编写客户端 但这显示了以下错误 问题答案: 您对@PathParam的使用不正确。它不符合javadoc 此处记录的这些要求。我相信您只想发布JSON实体。您可以在资源方法中解决此问题,以接受JSON实体。 并且,您的客户端代码应如

  • 我有一组RESTful web服务,通常部署在Glassfish服务器中。问题是,我工作的地方只与Apache一起工作,所以我不得不切换,现在是问题出现的地方。我已经成功地部署了两个RESTful资源,它们工作得很好(它们所做的只是从数据库中检索信息,并在POJO的ArrayList中返回该信息)。 我手动设置了库,甚至下载了该死的JerseyClientBuilder,但这些都不管用。提前谢谢你

  • 我正试图使Web服务与protobuf和json一起工作。问题在于,为了构建我的proto,我需要能够读取inputStream(至少我没有看到其他方法)。 我为protobuf创建了一个转换器: 在我的Spring配置中使用: 我的控制器: 问题是,如果我让控制器这样做,我会得到一个错误,因为我的webservice不支持application/octet流。 [main]信息组织。日食码头。服

  • 问题内容: 我正在使用Jersey 2.0(我从http://repo1.maven.org/maven2/org/glassfish/jersey/bundles/jaxrs- ri/2.5/jaxrs- ri-2.5.zip 下载)开发了一项休息服务。正在使用Tomcat 7.0.47。我从Eclipse运行Tomcat,而我的机器是Mac。 我正在使用Eclipse工具生成WAR并部署服务。

  • 我目前正在开发Jersey/Hibernate web服务(在Tomcat 9容器中),它应该能够使用和生成JSON(应用程序/JSON)和XML(应用程序/XML)。它支持GET和POST来使用这些类型。DELETE是受支持的,并且可以工作,对于JSON,GET和POST也是如此。但是,当我尝试使用XML内容类型时,我得到了一个500内部服务器错误。 结构如下:(检查下面的代码)歌曲列表(son