Jersey 客户端错误 - 无法解析无效的内容类型标头需要解决方法

如何解决Jersey 客户端错误 - 无法解析无效的内容类型标头需要解决方法

我相信我正在使用 Jersey 客户端 2.29
处理请求时,服务器以 Content-Type = application/ 响应(当然,这是一个假值,它应该是 application/json)。 jersey 爆炸,因为它无法解析媒体类型的子类型:

java.util.concurrent.CompletionException: org.glassfish.jersey.message.internal.HeaderValueException: Unable to parse "Content-Type" header value: "application/"
    at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:314)
    at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:319)
    at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1702)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.glassfish.jersey.message.internal.HeaderValueException: Unable to parse "Content-Type" header value: "application/"
    at org.glassfish.jersey.message.internal.InboundMessageContext.exception(InboundMessageContext.java:314)
    at org.glassfish.jersey.message.internal.InboundMessageContext.singleHeader(InboundMessageContext.java:309)
    at org.glassfish.jersey.message.internal.InboundMessageContext.getMediaType(InboundMessageContext.java:422)
    at com.test.web.ext.filter.LoggingFilter.filter(LoggingFilter.java:94)
    at org.glassfish.jersey.client.ClientFilteringStages$ResponseFilterStage.apply(ClientFilteringStages.java:109)
    at org.glassfish.jersey.client.ClientFilteringStages$ResponseFilterStage.apply(ClientFilteringStages.java:97)
    at org.glassfish.jersey.process.internal.Stages.process(Stages.java:147)
    at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:259)
    at org.glassfish.jersey.client.JerseyInvocation.lambda$invoke$1(JerseyInvocation.java:743)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:205)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:390)
    at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:741)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:432)
    at org.glassfish.jersey.client.JerseyCompletionStageRxInvoker.lambda$method$1(JerseyCompletionStageRxInvoker.java:46)
    at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700)
    ... 3 more
Caused by: javax.ws.rs.ProcessingException: java.lang.IllegalArgumentException: Error parsing media type 'application/'
    at org.glassfish.jersey.message.internal.InboundMessageContext$5.apply(InboundMessageContext.java:428)
    at org.glassfish.jersey.message.internal.InboundMessageContext$5.apply(InboundMessageContext.java:422)
    at org.glassfish.jersey.message.internal.InboundMessageContext.singleHeader(InboundMessageContext.java:307)
    ... 18 more
Caused by: java.lang.IllegalArgumentException: Error parsing media type 'application/'
    at org.glassfish.jersey.message.internal.MediaTypeProvider.fromString(MediaTypeProvider.java:69)
    at org.glassfish.jersey.message.internal.MediaTypeProvider.fromString(MediaTypeProvider.java:37)
    at javax.ws.rs.core.MediaType.valueOf(MediaType.java:196)
    at org.glassfish.jersey.message.internal.InboundMessageContext$5.apply(InboundMessageContext.java:426)
    ... 20 more
Caused by: java.text.ParseException: End of header.
    at org.glassfish.jersey.message.internal.HttpHeaderReaderImpl.getNextCharacter(HttpHeaderReaderImpl.java:155)
    at org.glassfish.jersey.message.internal.HttpHeaderReaderImpl.next(HttpHeaderReaderImpl.java:116)
    at org.glassfish.jersey.message.internal.HttpHeaderReaderImpl.next(HttpHeaderReaderImpl.java:111)
    at org.glassfish.jersey.message.internal.HttpHeaderReader.nextToken(HttpHeaderReader.java:104)
    at org.glassfish.jersey.message.internal.MediaTypeProvider.valueOf(MediaTypeProvider.java:90)
    at org.glassfish.jersey.message.internal.MediaTypeProvider.fromString(MediaTypeProvider.java:67)
    ... 23 more

github-MediaTypeProvider
我无法控制这个 3rd 方服务器,我必须能够处理这个请求。
反正有这个吗?
一些属性、设置、注册自定义媒体类型提供程序,还有什么?

附言 我已经成功地使用 ByteBuddy 在运行时重新定义了这个方法,并用一些额外的特殊调味料处理了错误,但这是一个主要的黑客......如果存在,我希望有更好的选择。

客户端配置

final Client client = ClientBuilder.newBuilder()
  .property(ClientProperties.REQUEST_ENTITY_PROCESSING,RequestEntityProcessing.CHUNKED)
  .property(ClientProperties.FOLLOW_REDIRECTS,false)
  .sslContext(tls)
  .hostnameVerifier(new NoOpHostnameVerifier())
  .register(new CookiePersistFilter(NARRATIVE)) // @Priority(HEADER_DECORATOR)
  .register(new LoggingFilter(NARRATIVE))       // @Priority(USER)
  .register(MyFilter.class)                     // @Priority(50000)
  .register(JsonReader.class)
  .register(JsonWriter.class)
  .register(HTMLReader.class)
  .register(MultiPartFeature.class)
  .build();

过滤器按以下顺序执行:

  1. 我的过滤器
  2. 日志过滤器
  3. CookiePersistFilter

解决方法

正如 Paul Samsotha 指出的那样,我可以使用高优先级的 ClientResponseFilter 解决这个问题。这是一种方法。

import javax.annotation.Priority;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientResponseContext;
import javax.ws.rs.client.ClientResponseFilter;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;

import com.selinc.winchester.common.narrative.INarrative;
import com.selinc.winchester.sentinel.Sentinel;
import com.selinc.winchester.wrestler.ResponsePriorities;

@Provider
@Priority(25000) // Note the priority ordering is reverse of ClientRequestFilter
public final class ResponseHeaderWorkaroundFilter implements ClientResponseFilter
{
  @Override
  public void filter(final ClientRequestContext requestContext,final ClientResponseContext responseContext)
  {
    try
    {
      // Attempt to read the Content-Type header.
      responseContext.getMediaType();
    }
    catch (Throwable error)
    {
      // On error,set the Content-Type header to some default value.
      responseContext.getHeaders()
        .putSingle(HttpHeaders.CONTENT_TYPE,MediaType.APPLICATION_JSON);
    }
  }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?