50

How can I dynamically change the address which my JAXWS client is using? This client was generated by wsimport.

ЯegDwight
  • 24,821
  • 10
  • 45
  • 52
Kico Lobo
  • 4,374
  • 4
  • 35
  • 48

4 Answers4

109

You can achieve that using the BindingProvider interface.

JAX-WS custom endpoint

/**
 * The following snippets shows how to set a custom endpoint for a JAX-WS generated WebClient on runtime
 */

// Get the service and the port
SampleService service = new SampleService();
Sample port = service.getESamplePort();

// Use the BindingProvider's context to set the endpoint
BindingProvider bp = (BindingProvider)port;
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://www.aviramsegal.com/ws/sample");

/* Optional  credentials */
bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "user");
bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "password");
port.callSampleMethod();
Aviram Segal
  • 10,962
  • 3
  • 39
  • 52
  • 1
    Is it possible to set the endpoint address for the whole service and not for each method separtely? – T3rm1 Feb 08 '12 at 10:50
  • 3
    This changes for the service, cache the port object and use it as many times as you want – Aviram Segal Feb 15 '12 at 08:01
  • This is exactly what I like as sometimes wsdl is not available on the server side. – havexz Sep 12 '13 at 17:52
  • thank you man I have been searching for this for 3 hours. That even supports even if service does not publish its wsdl at the server:) – fatih tekin Oct 20 '14 at 21:31
  • 4
    Thanks,it worked well ! CXF is so easy to use ... I mean, who's not clever enough to figure out that we need to use BindingProvider interface in order to modify a Port endpoint ? Moreover, the documentation is so up to date about this ! Still got the local conf XML file overriding the attribute referenced. – Alex May 09 '16 at 12:34
  • 1
    This didn't work for me. It still defaulted to the address in the WSDL. I used CXF for the conversion to Java. – TastyWheat Dec 27 '18 at 15:56
  • January 2019 : worked for me `apache-cxf-3.2.7` and `java8`. I used `wsdl2java` tool from CXF downloaded here http://cxf.apache.org/download.html . On runtime I use : cxf-rt-frontend-jaxws and cxf-rt-transports-http – Maxence Jan 23 '19 at 15:47
  • 2
    An important note on this: You need to use the same port object after setting these values. If you get a new one, it'll have the default WSDL values, and a new one is created every time you call `getPort`. – Christopher Schneider Mar 12 '19 at 21:47
15

Solved the problem using Apache CXF.

With just two lines of code! Here is the snippet:

URL url_wsdl = new URL("http://myserver/myservice?wsdl");
Service service = Service.create(url_wsdl, new QName("http://myaddress...", "ServiceName"));
return service.getPort(MyJAXWSPortClass.class);
Kico Lobo
  • 4,374
  • 4
  • 35
  • 48
  • 1
    this does/should work, however constructing a new service object like this is not a good solution. it causes the WSDL to be re-parsed from the new endpoint and is very expensive to do. @McDowell's referenced post is the best way to do what it being asked: http://stackoverflow.com/questions/3569075/jaxws-service-client – Helter Scelter Mar 09 '11 at 22:55
  • @HelterScelter : agreed, but in some situations this price is neglectable, for example when an application only needs to map this port once at startup. – BxlSofty Mar 08 '14 at 16:26
  • 1
    It does work only if server "http://myserver/myservice?wsdl" in online. If you has several applications, it means deploy them in straightly defined order, that could be a problem (and even impossible in case of cyclic dependencies) – Grigory Kislin Nov 28 '16 at 16:37
  • I switched form this to the BindingProvider solutions, simply because our code gets broken from time to time, when the customer releases the new WSDL. I don't want to dig to deep into the jaxws implementation detail, but the BindingProvider way is preferred solution. – Junchen Liu Jan 31 '18 at 17:29
  • This wasn't an option for me. The WSDL wasn't available directly from the service endpoint. – TastyWheat Dec 27 '18 at 15:57
3

I am new to PayPal integration, i am not sure about Adaptive Payment api. But we have a privilege to check whether specific email id having account in PayPal or not using GetVerifiedStatus method.

Please use below sandbox wsdl URL for verifying email

URL : https://svcs.sandbox.paypal.com/AdaptiveAccounts?wsdl

Response will be like below

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body>
      <ns2:GetVerifiedStatusResponse xmlns:ns2="http://svcs.paypal.com/types/aa">
         <responseEnvelope>
            <timestamp>2015-07-20T23:42:46.661-07:00</timestamp>
            <ack>Success</ack>
            <correlationId>5cea9a8575ab9</correlationId>
            <build>17345626</build>
         </responseEnvelope>
         <accountStatus>UNVERIFIED</accountStatus>
         <countryCode>IN</countryCode>
         <userInfo>
            <emailAddress>anandg.saga@gmail.com</emailAddress>
            <accountType>PERSONAL</accountType>
            <accountId>6KD7EVWM2E2AQW</accountId>
            <name>
               <salutation/>
               <firstName>anand</firstName>
               <middleName/>
               <lastName>anand</lastName>
               <suffix/>
            </name>
            <businessName/>
         </userInfo>
      </ns2:GetVerifiedStatusResponse>
   </soapenv:Body>
</soapenv:Envelope>

Note: while creating stub don't forgot to set endpoint as below. if we are not setting this, we can't get expected output.

String endpointURL = "https://svcs.sandbox.paypal.com/AdaptiveAccounts/GetVerifiedStatus";

use below method to add endpoint

private static void addEndPoint(AdaptiveAccountsPortType port,
            String endpointURL) {
        BindingProvider bp = (BindingProvider)port;
        bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointURL);

        /*List hchain = bp.getBinding().getHandlerChain();
        if (hchain == null) {
          hchain = new ArrayList();
        }
        hchain.add(new HTTPUserAgentHandler());
        bp.getBinding().setHandlerChain(hchain);*/
    }
Anand saga
  • 1,433
  • 11
  • 23
0

I am not sure on how to do that if you use wsimport. I had the same issue, so I used Intellij IDEA (version 9) to create client code for me. It provided a service endpoint constructor that takes in the wsdl url.

uncaught_exceptions
  • 21,712
  • 4
  • 41
  • 48