JAX-WS 웹 서비스 클라이언트에 대한 제한 시간을 어떻게 설정합니까?


93

JAXWS-RI 2.1을 사용하여 WSDL을 기반으로 웹 서비스 용 인터페이스를 만들었습니다. 웹 서비스와 아무 문제없이 상호 작용할 수 있지만 웹 서비스에 요청을 보내는 시간 제한을 지정할 수 없습니다. 어떤 이유로 든 응답하지 않으면 클라이언트가 바퀴를 영원히 돌리는 것처럼 보입니다.

주위의 사냥을 통해 아마도 다음과 같은 것을 시도해야 할 것입니다.

((BindingProvider)myInterface).getRequestContext().put("com.sun.xml.ws.request.timeout", 10000);
((BindingProvider)myInterface).getRequestContext().put("com.sun.xml.ws.connect.timeout", 10000);

또한 보유하고있는 JAXWS-RI 버전에 따라 다음 속성을 대신 설정해야 할 수도 있음을 발견했습니다.

((BindingProvider)myInterface).getRequestContext().put("com.sun.xml.internal.ws.request.timeout", 10000);
((BindingProvider)myInterface).getRequestContext().put("com.sun.xml.internal.ws.connect.timeout", 10000);

내가 가진 문제는 위의 어느 것이 옳든 상관없이 어디서 이것을 할 수 있는지 모르겠다 는 것입니다. 내가 가진 것은 Service웹 서비스에 대한 자동 생성 인터페이스를 구현 하는 하위 클래스이며 WSDL이 응답하지 않는 경우 속성을 설정하기에는 이미 너무 늦었습니다.

MyWebServiceSoap soap;
MyWebService service = new MyWebService("http://www.google.com");
soap = service.getMyWebServiceSoap();
soap.sendRequestToMyWebService();

누구든지 올바른 방향으로 나를 가리킬 수 있습니까?!


5
답이없는 것 같은데 질문이 문제 해결에 도움이되었습니다. com.sun.xml.ws.request.timeout 속성에 대해서는 알고 있었지만 com.sun.xml.internal.ws.request.timeout 속성에 대해서는 알지 못했습니다.
Ron Tuffin

답변:


90

나는 이것이 오래되었고 다른 곳에서 대답했다는 것을 알고 있지만 희망적으로 이것은 이것을 닫습니다. WSDL을 동적으로 다운로드하려는 이유가 무엇인지 모르겠지만 시스템 속성은 다음과 같습니다.

sun.net.client.defaultConnectTimeout (default: -1 (forever))
sun.net.client.defaultReadTimeout (default: -1 (forever))

JAX-WS가 사용하는 HttpURLConnection을 사용하여 모든 읽기 및 연결에 적용해야합니다. 원격 위치에서 WSDL을 가져 오는 경우 문제가 해결되지만 로컬 디스크에있는 파일이 더 좋습니다!

다음으로 특정 서비스에 대한 시간 제한을 설정하려면 프록시를 만든 후 BindingProvider (이미 알고 있음)로 캐스팅하고 요청 컨텍스트를 가져와 속성을 설정해야합니다. 온라인 JAX-WS 문서가 잘못되었습니다. 이것은 올바른 속성 이름입니다.

MyInterface myInterface = new MyInterfaceService().getMyInterfaceSOAP();
Map<String, Object> requestContext = ((BindingProvider)myInterface).getRequestContext();
requestContext.put(BindingProviderProperties.REQUEST_TIMEOUT, 3000); // Timeout in millis
requestContext.put(BindingProviderProperties.CONNECT_TIMEOUT, 1000); // Timeout in millis
myInterface.callMyRemoteMethodWith(myParameter);

물론 이것은 작업을 수행하는 끔찍한 방법입니다. 원하는 시간 제한을 삽입 할 수있는 이러한 바인딩 공급자를 생성하기위한 멋진 팩토리를 만들겠습니다.


10
REQUEST_TIMEOUT / CONNECT_TIMEOUT 속성은 실제로 SUN 내부 클래스 com.sun.xml.internal.ws.developer.JAXWSProperties에서 상속되며 (적어도 32 비트 Linux에서는) javac 1.6.0_27 및 javac 1.7.0_03이 실패합니다. 이 코드를 컴파일하십시오 ( bugs.sun.com/view_bug.do?bug_id=6544224 와 유사 ) ... -XDignore.symbol.file을 javac에 전달해야 작동합니다.
JavaGuy

작동하지 않는 것은 무엇입니까? 나는 이것을 두 번 확인했고 그것은 나를 위해 일하고 있습니다.
alpian

방금 JAX-WS RI 2.2.8 및 JDK 1.7에서 이것을 사용했고 잘 작동했음을 확인했습니다. 감사합니다!
bconneen 2014-06-10

정규화 된 이름에 "내부"가있는 클래스와 매개 변수는 공급 업체에 따라 다르므로 다른 JDK 구현간에 이식 할 수 없기 때문에 사용해서는 안됩니다. 예를 들어, jax-ws 매개 변수의 경우 해당 비 내부 등록 정보는 com.sun.xml.ws.client.BindingProviderProperties 클래스에 있습니다.
폴라 레토 2015.12.16

1
@ Matt1776 예 물론 빠졌습니다. JAX-WS는 API 사양이지만 라이브러리 구현이 필요합니다 (이 경우 JDK의 일부가 아닌 jaxws-ri.jar 또는 jaxws-rt.jar). 다운로드하여 ptoject에 추가하기 만하면 해당 속성을 사용할 수 있습니다.
Polaretto

41

허용 된 답변의 속성이 JAX-WS의 JBoss 구현을 사용하고 있기 때문에 작동하지 않았습니다.

다른 속성 집합 ( JBoss JAX-WS 사용자 가이드에 있음 )을 사용하면 다음과 같이 작동합니다.

//Set timeout until a connection is established
((BindingProvider)port).getRequestContext().put("javax.xml.ws.client.connectionTimeout", "6000");

//Set timeout until the response is received
((BindingProvider) port).getRequestContext().put("javax.xml.ws.client.receiveTimeout", "1000");

2
나는 JBoss를 사용하고 있지 않지만,이 주석의 속성 만이 나를 위해 일했고 다른 것은 아무것도하지 않았습니다.
PaulP 2015 년

2
특성 이름은 JAX-WS 구현에 따라 다릅니다. 목록은 여기에서 찾을 수 있습니다 : java.net/jira/browse/JAX_WS-1166
fabstab

3
java.net 링크가 끊어졌습니다. github.com/javaee/metro-jax-ws/issues/1166
trunkc

12

내 작업 솔루션은 다음과 같습니다.

// --------------------------
// SOAP Message creation
// --------------------------
SOAPMessage sm = MessageFactory.newInstance().createMessage();
sm.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");
sm.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "UTF-8");

SOAPPart sp = sm.getSOAPPart();
SOAPEnvelope se = sp.getEnvelope();
se.setEncodingStyle("http://schemas.xmlsoap.org/soap/encoding/");
se.setAttribute("xmlns:SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/");
se.setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
se.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");

SOAPBody sb = sm.getSOAPBody();
// 
// Add all input fields here ...
// 

SOAPConnection connection = SOAPConnectionFactory.newInstance().createConnection();
// -----------------------------------
// URL creation with TimeOut connexion
// -----------------------------------
URL endpoint = new URL(null,
                      "http://myDomain/myWebService.php",
                    new URLStreamHandler() { // Anonymous (inline) class
                    @Override
                    protected URLConnection openConnection(URL url) throws IOException {
                    URL clone_url = new URL(url.toString());
                    HttpURLConnection clone_urlconnection = (HttpURLConnection) clone_url.openConnection();
                    // TimeOut settings
                    clone_urlconnection.setConnectTimeout(10000);
                    clone_urlconnection.setReadTimeout(10000);
                    return(clone_urlconnection);
                    }
                });


try {
    // -----------------
    // Send SOAP message
    // -----------------
    SOAPMessage retour = connection.call(sm, endpoint);
}
catch(Exception e) {
    if ((e instanceof com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl) && (e.getCause()!=null) && (e.getCause().getCause()!=null) && (e.getCause().getCause().getCause()!=null)) {
        System.err.println("[" + e + "] Error sending SOAP message. Initial error cause = " + e.getCause().getCause().getCause());
    }
    else {
        System.err.println("[" + e + "] Error sending SOAP message.");

    }
}

3
이러한 구성이 "javax.xml.ws.client.connectionTimeout"및 "javax.xml.ws.client.receiveTimeout"과 동일합니까?
Jose Tepedino

11
ProxyWs proxy = (ProxyWs) factory.create();
Client client = ClientProxy.getClient(proxy);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(0);
httpClientPolicy.setReceiveTimeout(0);
http.setClient(httpClientPolicy);

이것은 나를 위해 일했습니다.


감사! 저에게도 정말 쉬운 방법입니다
kosm 2014

4
이것은 Apache CXF 클래스를 사용하지만 대답에 이것을 추가하는 것이 가장 좋습니다. CXF 항아리에 포함 된 링크도 많은 도움이 될 것입니다.
JBert 2014

@JBert 동의합니다. 나는 몇 년 전에 대답했고 기억이 나지 않는다. 대답을 자유롭게 편집하십시오.
Daniel Kaplan

8

JDK6에서 JAX-WS를 사용하는 경우 다음 특성을 사용하십시오.

com.sun.xml.internal.ws.connect.timeout  
com.sun.xml.internal.ws.request.timeout

System.setProperty ( "com.sun.xml.internal.ws.connect.timeout", "300"); System.setProperty ( "com.sun.xml.internal.ws.request.timeout", "300")가 저에게 효과적이었습니다.
2787184

2
일부 컨텍스트에서는 런타임에 어떤 JAXWS 버전 (내부 또는 독립형)이 사용 될지 프로그래밍 시간에 알 수 없습니다. 이 시간 제한 기능을 제외하고는 두 가지가 매우 호환됩니다. 키는 키 를 정의하는 클래스 (또는 인터페이스) ( / vs / ) 도 다릅니다 ( com.sun.xml.internal.ws.connect.timeoutvs ). 내 가장 좋은 아이디어는 리터럴 값을 키로 사용하여 둘 다 설정하는 것입니다. com.sun.xml.ws.connect.timeoutcom.sun.xml.internal.ws.developer.JAXWSPropertiescom.sun.xml.internal.ws.client.BindingProviderPropertiescom.sun.xml.ws.developer.JAXWSPropertiescom.sun.xml.ws.client.BindingProviderProperties
Lorinczy Zsigmond

5

앱 서버가 WebLogic (저에게는 10.3.6) 인 경우 시간 초과를 담당하는 속성은 다음과 같습니다.

com.sun.xml.ws.connect.timeout 
com.sun.xml.ws.request.timeout

3

이것이 당신의 맥락에서 도움이 될지 확실하지 않습니다 ...

soap 개체를 BindingProvider로 캐스팅 할 수 있습니까?

MyWebServiceSoap soap;
MyWebService service = new MyWebService("http://www.google.com");
soap = service.getMyWebServiceSoap();
// set timeouts here
((BindingProvider)soap).getRequestContext().put("com.sun.xml.internal.ws.request.timeout", 10000);
    soap.sendRequestToMyWebService();

반면에 MyWebService 개체의 초기화에 대한 시간 제한을 설정하려는 경우 도움이되지 않습니다.

이것은 개별 WebService 호출을 시간 초과하고 싶을 때 나를 위해 일했습니다.


2

SEI를 인스턴스화 할 때 원격 WSDL의 느린 검색을 피하는 가장 쉬운 방법은 런타임에 원격 서비스 엔드 포인트에서 WSDL을 검색하지 않는 것입니다.

이는 서비스 제공자가 영향을 미치는 변경을 수행 할 때마다 로컬 WSDL 사본을 업데이트해야 함을 의미하지만, 서비스 제공자가 영향을 미치는 변경을 수행 할 때마다 로컬 사본을 업데이트해야 함을 의미합니다.

클라이언트 스텁을 생성 할 때 클래스 경로의 미리 결정된 위치에서 WSDL을 읽는 방식으로 SEI에 주석을 달도록 JAX-WS 런타임에 지시합니다. 기본적으로 위치는 서비스 SEI의 패키지 위치에 상대적입니다.


<wsimport
    sourcedestdir="${dao.helter.dir}/build/generated"
    destdir="${dao.helter.dir}/build/bin/generated"
    wsdl="${dao.helter.dir}/src/resources/schema/helter/helterHttpServices.wsdl"
    wsdlLocation="./wsdl/helterHttpServices.wsdl"
    package="com.helter.esp.dao.helter.jaxws"
    >
    <binding dir="${dao.helter.dir}/src/resources/schema/helter" includes="*.xsd"/>
</wsimport>
<copy todir="${dao.helter.dir}/build/bin/generated/com/helter/esp/dao/helter/jaxws/wsdl">
    <fileset dir="${dao.helter.dir}/src/resources/schema/helter" includes="*" />
</copy>

wsldLocation 속성은 WSDL을 찾을 수있는 위치를 SEI에 알려주고 사본은 wsdl (및 지원 xsd .. 등)이 올바른 위치에 있는지 확인합니다.

위치는 SEI의 패키지 위치에 상대적이므로 wsdl이라는 새 하위 패키지 (디렉토리)를 만들고 여기에 모든 wsdl 아티팩트를 복사합니다.

이 시점에서해야 할 일은 클라이언트 스텁 아티팩트 jar 파일을 만들 때 모든 * .class 외에도 모든 * .wsdl, * .xsd를 포함하는 것입니다.

(호기심이 많은 경우 @webserviceClient 주석은이 wsdl 위치가 실제로 Java 코드에서 설정되는 곳입니다.

@WebServiceClient(name = "httpServices", targetNamespace = "http://www.helter.com/schema/helter/httpServices", wsdlLocation = "./wsdl/helterHttpServices.wsdl")
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.