2015-12-15 2 views
1

Я пытаюсь отправить запрос JSON на безопасный веб-сервис REST с использованием файла хранилища ключей, и я использую API Джерси. Ниже приведен фрагмент моего кодаjavax.ws.rs.ProcessingException при отправке запроса через Jersey

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 

ответ

3

На самом деле это ошибка в трикотаже, что сообщение об ошибке в исключении в основном неверно. См. SSLHandshakeException masked by useless IllegalStateException: Already connected

Таким образом, это означает, что в SSL-связи между сервером и клиентом возникает проблема.

Одной из причин исключения связана с этим: Jersey API Doc - 5.9. Securing a Client

... ClientBuilder также предлагает метод для определения реализации пользовательских HostnameVerifier. Реализации HostnameVerifier вызывается, когда проверка хоста по умолчанию не выполняется.

Важно

поведение HostnameVerifier зависит от HTTP-клиента реализации. HttpUrlConnector и ApacheConnector работают правильно, Это означает, что после неудачной проверки URL-адреса Вызывается имя хоста Hoster, и с помощью можно переутвердить URL-адрес, используя пользовательскую реализацию HostnameVerifier и , продолжая обрабатывать handskahe. JettyConnector и GrizzlyConnector предоставляют только проверку URL-адреса хоста и выдают исключение CertificateException без возможности использования пользовательского HostnameVerifier. Более того, в случае с JettyConnector в существует свойство JettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION, чтобы отключить механизм проверки всего URL-адреса в рукопожатии.

Если вы используете Grizzly, вы не можете отключить его, но есть обходной путь. Он должен установить настраиваемый HostnameVerifier, чтобы verify() всегда возвращал значение true в конфигурации клиента:

 Client c = ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier(new HostnameVerifier(){ 
       @Override 
       public boolean verify(String paramString, SSLSession paramSSLSession) { 
       return true; 
      } 
     }).build(); 
Смежные вопросы