■ はじめに
* 以下の Metro のユーザズガイドhttps://metro.java.net/1.5/guide/HTTP_Timeouts.html
に従って、以下【ダメだった例】のように実装したが、タイムアウトが発生しなかった。 # サーバが、GlassFishじゃなかったから? ただ、タイムアウトを実現できたので、メモしておく
【ダメだった例】タイムアウトが発生しなかった実装
Map<String, Object> context = ((BindingProvider)proxy).getRequestContext(); // 接続にかかった時間 context.put("com.sun.xml.ws.request.timeout", 2 * 1000); // データ取得にかかった時間 context.put("com.sun.xml.ws.request.timeout", 2 * 1000);JAXWSProperties.CONNECT_TIMEOUT について
https://jax-ws.java.net/nonav/jax-ws-20-fcs/arch/constant-values.html#com.sun.xml.ws.developer.JAXWSProperties.CONNECT_TIMEOUT
■ ポイント
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);
補足
* ただし、この方法では、WSDLファイル取得時のタイムアウトにはならない。 詳細および解決案などについて、以下の関連記事を参照。Webサービス / Metro [10] ~ WSDLファイルをクライアントのローカルに置く ~
https://blogs.yahoo.co.jp/dk521123/36872164.html
■ サンプル
動作環境
* Windows10 * Java1.8 * Eclipse Mars.2 Release (4.5.2) * Tomcat v8.5.8 * metro-2.3.1
サーバ側
http://blogs.yahoo.co.jp/dk521123/36139336.htmlをベースに...
import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; import javax.xml.bind.annotation.XmlElement; @WebService(name = "SampleWebService") public class SampleWebService { @WebMethod public String sayYourAge(@XmlElement(required = true, nillable = false) @WebParam(name = "name") String name, @XmlElement(required = false, nillable = true) @WebParam(name = "age") Long age) { // ★ここで、実験のため、意図的にサーバ側に時間が掛かるようにした★ try { Thread.sleep(10 * 1000L); } catch (InterruptedException ex) { ex.printStackTrace(); } return name + "'s age is " + age + "."; } }
クライアント側
http://blogs.yahoo.co.jp/dk521123/36140561.htmlをベースに...
import java.net.URL; import java.util.Map; import javax.xml.ws.BindingProvider; public class Main { public static void main(String[] args) { System.out.println("Start!"); try { URL url = new URL("http://localhost:8080/SampleWebService/services/SampleWebService.ws?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"); } }
出力結果
Start! javax.xml.ws.WebServiceException: java.net.SocketTimeoutException: Read timed out at com.sun.xml.internal.ws.transport.http.client.HttpClientTransport.readResponseCodeAndMessage(HttpClientTransport.java:195) at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.createResponsePacket(HttpTransportPipe.java:226) at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:217) at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.processRequest(HttpTransportPipe.java:130) at com.sun.xml.internal.ws.transport.DeferredTransportPipe.processRequest(DeferredTransportPipe.java:95) at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:1121) at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:1035) at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:1004) at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:862) at com.sun.xml.internal.ws.client.Stub.process(Stub.java:448) at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(SEIStub.java:178) at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:93) at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:77) at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:147) at com.sun.proxy.$Proxy35.sayYourAge(Unknown Source) at com.sample.webservice.client.stub.Main2.main(Main2.java:29) ... 15 more Done
■ あとがき
今回、Webサービスのアクセスする際にタイムアウト値を設けたが、 場合によって、時間がかかる場合があった。 その解決案は、以下の関連記事を記載してあるhttps://blogs.yahoo.co.jp/dk521123/36904908.html
参考文献
http://stackoverflow.com/questions/2148915/how-do-i-set-the-timeout-for-a-jax-ws-webservice-client* 今後役に立つかもしれないサイト
https://metro.java.net/guide/ch05.html#http-timeouts
https://jax-ws.java.net/nonav/jax-ws-20-fcs/arch/constant-values.html#com.sun.xml.ws.developer.JAXWSProperties.SSL_SOCKET_FACTORY