'Already Connected' 尝试使用 Jersey Client API 执行 POST 请求时出现异常

'Already Connected' exception trying to do POST request using Jersey Client API

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

我正在尝试执行这样的 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.access0(HttpUrlConnector.java:91)
at org.glassfish.jersey.client.HttpUrlConnector.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 :) 谢谢

可能 java.lang.IllegalStateException: Already connected 只掩盖了 SSLHandshakeException。请查看问题 #3000 (previously known as JERSEY-2728 错误)。

问题可能出在 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();

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

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

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

您可能在调用 connection.connect();

后在 http 连接上设置 header 属性

可能是一个 SSL 异常被已经连接的异常屏蔽了。 verify/debug SSL 异常的最简单方法是添加以下 JVM 标志:

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

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