【问题标题】:'Already Connected' exception trying to do POST request using Jersey Client API尝试使用 Jersey 客户端 API 执行 POST 请求的“已连接”异常
【发布时间】:2015-05-11 04:18:30
【问题描述】:

我正在使用 arquillian 为部署在 Tomcat 8 上的 JAX-RS/Jersey Webservice 创建集成测试。

我正在尝试执行这样的 POST 请求:

E dummy = dummyFactory.manufacturePojo(getSubClassType());
dummy.setId(null);

Client client = ClientBuilder.newClient();
WebTarget target = client.target(BASE_URI).path("bandeira");

Response response = target.request(MediaType.APPLICATION_JSON)
            .header(HttpHeaders.AUTHORIZATION, CHAVE_TESTE)
            .header(HttpHeaders.CONTENT_TYPE, "application/json")
            .post(Entity.entity(dummy, MediaType.APPLICATION_JSON));

当我这样做时,我得到了这个异常:

Caused by: java.lang.IllegalStateException: Already connected
at sun.net.www.protocol.http.HttpURLConnection.setRequestProperty(HttpURLConnection.java:3000)
at org.glassfish.jersey.client.HttpUrlConnector.setOutboundHeaders(HttpUrlConnector.java:364)
at org.glassfish.jersey.client.HttpUrlConnector.access$100(HttpUrlConnector.java:91)
at org.glassfish.jersey.client.HttpUrlConnector$4.getOutputStream(HttpUrlConnector.java:327)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:201)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:195)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commit(CommittingOutputStream.java:263)
at org.glassfish.jersey.message.internal.OutboundMessageContext.commitStream(OutboundMessageContext.java:816)
at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:546)
at org.glassfish.jersey.client.HttpUrlConnector._apply(HttpUrlConnector.java:331)
at org.glassfish.jersey.client.HttpUrlConnector.apply(HttpUrlConnector.java:243)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:246)
... 149 more

我可以使用一些启发式方法,因为 我仍在学习 arquillian 和 Jersey 客户端 API :) 谢谢

【问题讨论】:

  • 我不认识 arquillian,但我觉得这件球衣客户的作品还不错。您可以调试并查看您的标头是否正确编写?您可以从响应中看到它。

标签: java jersey client jboss-arquillian


【解决方案1】:

可能java.lang.IllegalStateException: Already connected 只屏蔽了SSLHandshakeException。请查看问题#3000(以前称为JERSEY-2728 错误)。

【讨论】:

  • 看起来像,但是在这种情况下,解决方法是什么? @Grzesiek D.
  • @MarcosJ.CKichel 这意味着您的连接有问题,所以请仔细检查您的BASE_URI。您也可以尝试使用纯 http 而不是 https(因为 https 需要提供 SSLContext,但我在您的代码中没有看到它)。
  • hmmmmm,好吧,反正我没有使用 https.. 但我一定会检查 uri.. 谢谢 :D @Grzesiek D.
  • 谢谢你! FFS,这是一个可怕的错误。
  • 链接失效:Jersey 代码和错误现在在 github 中:github.com/jersey/jersey/issues/3000(为什么 Oracle 会关闭 java.net - 叹息)
【解决方案2】:

这可能是由于网络连接问题。 自从我的 VPN 失去连接后,我遇到了这个问题。 在jackson序列化邮件正文期间报告了“Already connected”的异常。(我导入了Jersey和jackson-jaxrs-base的源代码进行调试)。 在我删除邮件正文后,出现了带有错误“Unknown hostname”的新异常。

登录我的 VPN 后,一切正常。

我对 Jersey 客户端异常 "Already connected" 感到非常不满,这让我感到困惑。

【讨论】:

  • 当我不在公司网络或 VPN 上时会发生这种情况!
【解决方案3】:

问题可能出在 SSL 协商中。尝试添加“trustall”客户端初始化逻辑。

SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, new TrustManager[] { new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}

@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}

@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}

} }, new java.security.SecureRandom());

Client client = ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier((s1, s2) -> true)
.register(MultiPartFeature.class)
.register(new EncodingFeature("gzip", GZipEncoder.class))
.build();

【讨论】:

  • 根本问题是 SSL 协商失败并且异常被吞没;但即使添加一个完全信任的信任管理器也不能解决我的问题。我求助于 Apache HTTP Client 4.4 连接提供程序并安装了一个完全信任的信任管理器来解决问题
  • 这是一个非常糟糕的主意 :(。请修复问题,以便您可以正确地信任证书,而不是放弃使用 TLS 应该获得的完整性。
  • @AndrewAylett 基本上:是的。就我而言,我根本不想使用 SSL,但对方强迫我这样做。
【解决方案4】:

您可能在调用 connection.connect() 后在 http 连接上设置 header 属性;

【讨论】:

  • 为我工作。我在 connection.getOutputStream() 之前移动了我的 connection.setRequestProperty 并取得了成功。谢谢!
【解决方案5】:

它可能是一个 SSL 异常被已连接的异常所掩盖。验证/调试 SSL 异常的最简单方法是添加以下 JVM 标志:

-Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager -Djava.security.debug=access:stack

这将告诉 JVM 打印一整套 SSL 握手信息,包括任何异常。从这些信息中您应该能够看到问题所在。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-16
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多