JAXWS — how to change the endpoint address [duplicate]
Asked Answered
P

4

50

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

Petulance answered 1/3, 2011 at 18:10 Comment(3)
See #649519Countryman
Does dynamically mean at runtime?Ritualist
See https://mcmap.net/q/343501/-overriding-or-setting-web-service-endpoint-at-runtime-for-code-generated-with-wsimportBellyband
P
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);
Petulance answered 2/3, 2011 at 16:6 Comment(5)
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: https://mcmap.net/q/343501/-overriding-or-setting-web-service-endpoint-at-runtime-for-code-generated-with-wsimportActivator
@HelterScelter : agreed, but in some situations this price is neglectable, for example when an application only needs to map this port once at startup.Yaker
It does work only if server "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)Lilt
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.Murrain
This wasn't an option for me. The WSDL wasn't available directly from the service endpoint.Erdah
N
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();
Natant answered 23/1, 2012 at 17:9 Comment(8)
Is it possible to set the endpoint address for the whole service and not for each method separtely?Silique
This changes for the service, cache the port object and use it as many times as you wantNatant
This is exactly what I like as sometimes wsdl is not available on the server side.Fruiter
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:)Misadventure
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.Frederigo
This didn't work for me. It still defaulted to the address in the WSDL. I used CXF for the conversion to Java.Erdah
January 2019 : worked for me apache-cxf-3.2.7 and java8. I used wsdl2java tool from CXF downloaded here cxf.apache.org/download.html . On runtime I use : cxf-rt-frontend-jaxws and cxf-rt-transports-httpHaberdasher
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.Jitters
P
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);
Petulance answered 2/3, 2011 at 16:6 Comment(5)
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: https://mcmap.net/q/343501/-overriding-or-setting-web-service-endpoint-at-runtime-for-code-generated-with-wsimportActivator
@HelterScelter : agreed, but in some situations this price is neglectable, for example when an application only needs to map this port once at startup.Yaker
It does work only if server "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)Lilt
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.Murrain
This wasn't an option for me. The WSDL wasn't available directly from the service endpoint.Erdah
V
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>[email protected]</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);*/
    }
Vaticinal answered 21/7, 2015 at 10:21 Comment(0)
B
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.

Bicyclic answered 1/3, 2011 at 18:15 Comment(1)
I'm seeking for a solution using wsimport. Can't use Intellij IDEAPetulance

© 2022 - 2024 — McMap. All rights reserved.