通过Jersey发送请求时javax.ws.rs.ProcessingException

时间:2015-12-15 03:55:02

标签: java web-services rest jersey

我正在尝试使用密钥库文件向安全的REST Web服务发送JSON请求,而我正在使用Jersey API。以下是我的代码片段

SslConfigurator sslConfigurator = SslConfigurator.newInstance().trustStoreFile("C:\\Users\\******\\test.keystore").trustStorePassword("password");
SSLContext sslContext = sslConfigurator.createSSLContext();
Client client = ClientBuilder.newBuilder().sslContext(sslContext).build();
WebTarget target = client.target("https://hostname:portnumber").path("resourse/methodname/v1");

Form form = new Form();
form.param("key1", "value1");
form.param("key2", "value2");

Response response = target.request(MediaType.APPLICATION_JSON_TYPE).post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
System.out.println(response);

但是我在最后一行上得到以下异常。

Exception in thread "main" javax.ws.rs.ProcessingException: Already connected
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:264)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:684)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:681)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:681)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:437)
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:343)
at TestMain.main(TestMain.java:29)
Caused by: java.lang.IllegalStateException: Already connected
at sun.net.www.protocol.http.HttpURLConnection.setRequestProperty(HttpURLConnection.java:3014)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.setRequestProperty(HttpsURLConnectionImpl.java:316)
at org.glassfish.jersey.client.internal.HttpUrlConnector.setOutboundHeaders(HttpUrlConnector.java:421)
at org.glassfish.jersey.client.internal.HttpUrlConnector.access$100(HttpUrlConnector.java:96)
at org.glassfish.jersey.client.internal.HttpUrlConnector$4.getOutputStream(HttpUrlConnector.java:384)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:200)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:194)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commit(CommittingOutputStream.java:262)
at org.glassfish.jersey.message.internal.OutboundMessageContext.commitStream(OutboundMessageContext.java:816)
at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:545)
at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:388)
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:285)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:255)
... 10 more

1 个答案:

答案 0 :(得分:3)

实际上,球衣中的错误是异常中的错误消息基本上是错误的。请参阅SSLHandshakeException masked by useless IllegalStateException: Already connected

基本上,这意味着服务器和客户端之间的SSL握手存在问题。

异常的原因之一与此有关:Jersey API Doc - 5.9. Securing a Client

  

... ClientBuilder还提供了一种定义自定义HostnameVerifier实现的方法。当默认主机URL验证失败时,将调用HostnameVerifier实现。

     

重要

     

HostnameVerifier的行为取决于http客户端   实现。 HttpUrlConnector和ApacheConnector正常工作,   这意味着在URL验证失败后   调用HostnameVerifier并通过它来实现   使用HostnameVerifier的自定义实现重新验证URL   继续进行手工处理。 JettyConnector和GrizzlyConnector   仅提供主机URL验证并抛出CertificateException   没有任何可能使用自定义HostnameVerifier。而且,在   JettyConnector的情况有一个属性   JettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION禁用   握手中的整个主机URL验证机制。

如果您正在使用Grizzly,则无法将其关闭,但有一种解决方法。要设置一个自定义的HostnameVerifier,验证()始终在客户端配置中返回true:

        Client c = ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier(new HostnameVerifier(){
              @Override
              public boolean verify(String paramString, SSLSession paramSSLSession) {
               return true;
             }
        }).build();