はじめに
Webサービス / Metro [9] ~ タイムアウトを設定する / クライアントサイドhttps://blogs.yahoo.co.jp/dk521123/36559479.html
で、クライアントサイドのタイムアウトを設定した。 しかし、上記の関連記事のタイムアウト値はあくまで、 下記「クライアント-Webサービス間のシーケンス図」で言うと 「[3] Call Web Service API(WebサービスのAPI呼び出し)」と 「[4] Result from API(WebサービスのAPIからの結果・レスポンス)」 に対してのタイムアウト値で、 「[1] Request WSDL file(WSDLファイルの取得リクエスト)」と 「[2] Response WSDL file(WSDLファイルの取得レスポンス)」 に対してのタイムアウト値ではなかった。 色々試したが、タイムアウト値を設定できなかったが、 一つの解決案として、クライアント側に予めWSDLファイルを置いておくという 方法があったので、その方法について、記述する。 (ローカルにあれば、ネットに繋ぐ必要もないので、タイムアウト値が不要になる)
クライアント-Webサービス間のシーケンス図
Client Web Service | | +--- [1] Request WSDL file -------->| | | |<-- [2] Response WSDL file --------+ | | | | +--- [3] Call Web Service API ----->| | | |<-- [4] Result from API -----------+ | | | |
サンプル
Webサービス側
* サービスを立ち上げておく* 以下の関連記事を参照のこと。Webサービス / Metro [1] ~入門編 / サーバサイドの構築 ~
http://blogs.yahoo.co.jp/dk521123/36139336.html
クライアント側
【WSDLファイル】SampleWebService.wsdl[[https://localhost:8443/SampleWebService/services/SampleWebService.ws?wsdl]]
をブラウザなどでアクセスし、ファイル「SampleWebService.wsdl」として保存
<!-- Published by JAX-WS RI (http://jax-ws.java.net). RI's version is Metro/2.3.1 (UNKNOWN_BRANCH-false; 2015-01-15T16:53:43+0100) JAXWS-RI/2.2.10 JAXWS-API/2.2.11 JAXB-RI/2.2.10-b140802.1033 JAXB-API/2.2.12-b140109.1041 svn-revision#unknown. --> <!-- Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is Metro/2.3.1 (UNKNOWN_BRANCH-false; 2015-01-15T16:53:43+0100) JAXWS-RI/2.2.10 JAXWS-API/2.2.11 JAXB-RI/2.2.10-b140802.1033 JAXB-API/2.2.12-b140109.1041 svn-revision#unknown. --> <definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://webservice.sample.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://webservice.sample.com/" name="SampleWebServiceService"> <types> <xsd:schema> <!-- ★「schemaLocation」属性の値を必要であれば書き直す★ --> <xsd:import namespace="http://webservice.sample.com/" schemaLocation="">https://localhost:8443/SampleWebService/services/SampleWebService.ws?xsd=1"/> </xsd:schema> </types> <message name="sayYourAge"> <part name="parameters" element="tns:sayYourAge"/> </message> <message name="sayYourAgeResponse"> <part name="parameters" element="tns:sayYourAgeResponse"/> </message> <portType name="SampleWebService"> <operation name="sayYourAge"> <input wsam:Action="http://webservice.sample.com/SampleWebService/sayYourAgeRequest" message="tns:sayYourAge"/> <output wsam:Action="http://webservice.sample.com/SampleWebService/sayYourAgeResponse" message="tns:sayYourAgeResponse"/> </operation> </portType> <binding name="SampleWebServicePortBinding" type="tns:SampleWebService"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <operation name="sayYourAge"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> <service name="SampleWebServiceService"> <port name="SampleWebServicePort" binding="tns:SampleWebServicePortBinding"> <!-- ★「location」属性の値を必要であれば書き直す★ --> <soap:address location="">https://localhost:8443/SampleWebService/services/SampleWebService.ws"/> </port> </service> </definitions>【Javaコード】Main.java
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.security.GeneralSecurityException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.util.Map; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.xml.ws.BindingProvider; public class Main { public static void main(String[] args) { System.out.println("Start!"); try { SSLContext sslContext = SSLContext.getInstance("TLS"); char[] keyPass = "changeit".toCharArray(); try (FileInputStream fileInputStream = new FileInputStream("./etc/client.keystore")) { KeyStore keyStore = creatKeyStore(fileInputStream, keyPass); KeyManager[] keyManagers = creatKeyManagers(keyStore, keyPass); TrustManager[] trustManager = creatTrustManagers(keyStore); SecureRandom secureRandom = SecureRandom.getInstanceStrong(); System.out.println("Algorithm : " + secureRandom.getAlgorithm()); sslContext.init(keyManagers, trustManager, secureRandom); HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); HostnameVerifier hostnameVerifier = creatHostnameVerifier(); HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier); } // ★ここ(ポイントは「file:///【ローカルのWSDLファイルパス】」)★ URL url = new URL("file:///C:/workspace/SampleCode/conf/SampleWebService.wsdl"); SampleWebServiceService service = new SampleWebServiceService(url); SampleWebService proxy = service.getSampleWebServicePort(); Map<String, Object> context = ((BindingProvider) proxy).getRequestContext(); // コネクションを確立するまでの時間[ミリ秒] context.put("com.sun.xml.internal.ws.request.timeout", 2 * 1000); // レスポンスを受け取るまでの時間[ミリ秒] context.put("com.sun.xml.internal.ws.connect.timeout", 2 * 1000); long start = System.currentTimeMillis(); String result = proxy.sayYourAge("Ken", 11L); long end = System.currentTimeMillis(); System.out.println((end - start) + "ms"); System.out.println("Result : " + result); } catch (Exception ex) { ex.printStackTrace(); } System.out.println("Done"); } private static KeyStore creatKeyStore(InputStream inputStream, char[] trustpass) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException { KeyStore keyStore = KeyStore.getInstance("JKS"); keyStore.load(inputStream, trustpass); return keyStore; } private static KeyManager[] creatKeyManagers(KeyStore keyStore, char[] keyPass) throws GeneralSecurityException, IOException { String algorithm = KeyManagerFactory.getDefaultAlgorithm(); KeyManagerFactory factory = KeyManagerFactory.getInstance(algorithm); factory.init(keyStore, keyPass); return factory.getKeyManagers(); } private static TrustManager[] creatTrustManagers(KeyStore trustStore) throws NoSuchAlgorithmException, KeyStoreException { String algorithm = KeyManagerFactory.getDefaultAlgorithm(); TrustManagerFactory factory = TrustManagerFactory.getInstance(algorithm); factory.init(trustStore); return factory.getTrustManagers(); } private static HostnameVerifier creatHostnameVerifier() { return new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { System.out.println("verify " + hostname + " " + session.getPeerHost()); return true; } }; } }
実行結果
Start! Algorithm : Windows-PRNG 1047ms Result : [0] Ken's age is 11. Done
トラブルシューティング
例外「java.net.MalformedURLException: unknown protocol: c」発生する
* 以下の関連記事を参照https://blogs.yahoo.co.jp/dk521123/36872203.html