I am trying to write a module for a Java application that accesses a WSDL-described webservice. The source WSDL was downloaded straight from what I believe to be an ASP.NET webservice; the service URL ends in a .asmx extension, and viewing the service URL in a browser shows a link which can be used to download the WSDL.
A key requirement for me is to be able to switch out the service URL without recompiling. The URL given to me is obviously a test server and I know that in production I will be given a production URL to use. I would also like to be able to create a mock server myself for testing, and retain the ability to specify a new URL in the future without recompiling if the service is moved. In fact, I would like for an installation of our application to be able to instantiate multiple instances of the webservice at different URLs.
But my conception doesn't seem to match up with what the wsimport tool is doing for me. Following f1sh's answer here, I generated Java code from my downloaded WSDL with this command:
wsimport -Xnocompile -keep -b binding.xml wsdlFile.wsdl
What I find is that the generated code has a hardcoded reference to my downloaded wsdlFile.wsdl, which contains the service URL. Our application is not going to be running in such a way that it con be configured by editing a WSDL file at runtime. I need to have code that is compiled into my application at build time and can have the service URL set at instantiation time.
I'm not entirely sure why the WSDL even needs to be parsed at runtime; it was my understanding that WSDL provides enough information to generate code which can access the webservice, so I am not sure what it is providing to the generated code other than the service URL, and I am not sure why the service URL is not provided in a constructor or configurable through a method on the generated webservice class. I must be missing something.
What is the general practice for this scenario? Do most people regenerate code for each individual URL that they are going to be using? Is code generated at runtime? Is there another WSDL tool I can use that will build client code with a configurable URL?
This approach requires me to also supply a javax.xml.namespace.QName object, which I don't yet understand, as the second argument.
Copy the one from your generated source. A QName
is an XML qualified name - a "unique" identity.
I still don't understand why the WSDL is needed at runtime.
I can't say I know for sure, but a WSDL is basically a schema. By providing it, I'm guessing you give JAX-WS a mechanism to validate the SOAP response. I don't think the JAXB bindings are enough to do this.
I always use the two-argument constructor in the generated service to provide a URL via the ClassLoader.getResource method to embed the WSDL in my jar. As with any schema, using a remote or file system URL for this is stupid less than optimal.
See this question for how to set the end-point at runtime:
HelloService service = new HelloService();
Hello port = service.getHelloPort();
BindingProvider bindingProvider = (BindingProvider) port;
bindingProvider.getRequestContext().put(
BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://foo:8086/HelloWhatever");
String response = port.sayHello(name);