Backstory:
I have a WSDL that was created by the customer (non-negotiable) that mixes several web standards into a single service. This one soap service has four soap ports that refer to bindings in referenced (wsdl:import) WSDL files that import XSDs resulting in a dependency tree that is significantly complex.
Since this is done by imports, the top level WSDL isn't that big. WSDL2Java and wsimport choke on it, but I have a library of the schemas compiled into JAXB objects to work with. So I created a CXF service that has all of the required operations and I was able to test it with SoapUI (it imported the top level WSDL fine since it didn't have to make java classes).
Since all the soap ports point to the same address, and that service handles all the operations from the various ports, the client doesn't know that the server thinks all the operations belong to the same port.
Problem:
This breaks down when it comes to CXF generating the WSDL. It puts all the operations on one port with the same namespace. In the customer provided WSDL, the service, ports and bindings are not all in the same namespace. I have tried to supply the service with the WSDL using the #WebService(wsdlLocation="") annotation, but it tries to parse it and match it to the code (as it would in a sane world).
Question:
I would like to intercept/override the http://example.com/service?wsdl operation and return the customer provided wsdl. Is there a way to do this in CXF?
I ended up splitting the ports out into separate services, but I still needed a custom WSDL that had info for all the ports. The way to do this with CXF is to create an interceptor.
I followed the example of the CXF interceptor that regularly handles WSDL generation: http://grepcode.com/file/repo1.maven.org/maven2/org.apache.cxf/cxf-rt-frontend-simple/2.4.0/org/apache/cxf/frontend/WSDLGetInterceptor.java. I read in my custom WSDL and replace the placeholder hostname with the hostname that comes from the request URL.
You need to then add the custom interceptor when you make your service (I use spring for my configuration). More info on that at http://cxf.apache.org/docs/interceptors.html.
Related
Previously, I've written SOAP clients in Python and used the SUDS library. Without getting into the details, the "stub" generation is really quite dynamic as it's done at runtime and, with Python being so typeless, I'm able to reference the expected methods generated by the WSDL without a pre-compiled stub. I'm fine with generating a stub with something like wsimport, because it's great to have the composition of SOAP messages being handled via a nice Java object structure. So, I'm not looking for a dynamic generation mechanism akin to SUDS in python.
My problem is that all the simple JAX-WS examples I see are for what I'll call a "statically located web service". What I'm trying to do is connect to a web service with a known WSDL from which I could generate stubs at compile time but whose location is only known at runtime. For example, say I want to access Microsoft SharePoint Web Services. Wherever my application is deployed, there will a different SharePoint server (or servers) running which will need to be specified at runtime. All the simple examples I've seen have the service location URL hard-coded into the stubs through wsimport. Is there a way to generate stubs but supply the service location at runtime?
I'm really surprised not to find any examples of this because I figure what I'm trying to do should be very common as Web Services go. Perhaps the answer is that I can't be lazy and get a nice objectified version of the WSDL methods if the server location is only known at runtime. I've seen SAAJ examples but there, of course, I have to generate the SOAP messages by hand myself. That would be such a shame when the WSDL is known at compile time. Can't I have my cake and eat it too?
If I understand your question right, you want to connect to multiple web services that expose the same WSDL but are located at different addresses and your client contains only the address of the service used to generate it?
In that case have a look at this post: Changing WSDL url (endpoint) in JAX-WS client.
I am using JAX-WS to export some SOAP Web Service Endpoints.
I know I can access the WSDL by appending ?WSDL to the web service endpoint. (Like http://localhost:8888/web_service/test?WSDL
Is there any other information I can get by appending things to the URL?
If you have a look at the generated WSDL (if you're using #WebService annotation) you can see that you can find the XSD with "?xsd=1".
I don't know how standard this is, though, and if there are cases where you could have different values than 1.
I created a Web Service using JaxWs. I belive that exist two ways to consume a web service in the client.
using wconsume e putting the generated classes as stubs in the client.
using Dynamic Proxy, whitch means, there wil be no files to be send to client as stubs.
I imagine that the only advantage of this approach is that if the wsdl changed, there will be not need to generat stubs files. However it doesn't look too practical, as I will probably need to change something in the client code and recompiled anyway. I didn't use this tecnichy yet. I found this option when I was reaserching the reason why I need to generate proxy file when developping Java client but I didn't when I using .Net.
Then, I have two question:
What's the difference between stubs and Dynamic Proxy tecnich?
Why .Net client doesn't need proxies files? Or is there the files automaticlly generated and I don't know where to find? Am I loosing performance or security when using stubs versus dynamic proxy?
1.What's the difference between stubs and Dynamic Proxy tecnich?
JAX-RPC is deprecated.
The new standard is JAX-WS.
JAX-WS allows programmers to invoke a web service, as if they were making a local method call.
For this to happen a standard mapping from WSDL to Java has been defined.
This mapping correlates a wsdl:port definition with a Java Interface which is called Service Endpoint Interface (SEI).
The SEI is the Java representation of the web service endpoint.
At runtime JAX-WS creates an instance of a SEI that can be used to make web service calls by simply making method calls on the SEI.
Now the way used to create an instance of a SEI is via the dynamic proxy class.
It is called dynamic proxy since it is created dynamically.
No stubs are need to implement a proxy, but the SEI must already have been implemented in order to be used.
The proxy uses/is based on the stub classes to function, which have been generated by the WSDL.
So the stubs are a prerequisite.
So there is no separation of techniques as you say in your post.
You have misunderstood the concept
I'm creating a Spring WS client. I have a huge WSDL from a third-party company. They provide a set of classes that maps to their WSDL via the Axis' WSDL2Java. I don't want to use Axis or any dependencies from them.
Since this is a web service client, I'm free to choose any framework. My problem is how do I generate a mapping class for the WSDL without using Axis's WSDL2Java. Am I stuck with manipulating pure XML? Take note I'm using Spring WS.
Edit:
Is it true if the service provider has built their service with Axis 1, you're basically stuck with making a client that's also based on Axis 1? I read it from this answer JAX-WS client with Axis service. I thought web services are supposed to be decoupled or at least independent from the platform that it was created, allowing you to have a .Net based web service to be accessed from a Java based client and vice versa?
If you want to use Spring-WS, then your best bet is to use the wsimport tool that ships with Java 6 (or use the JAX-WS RI, if you're on Java5). This will generate JAX-WS stubs for the web service. Included in these stubs will be standard JAXB bindings for the WSDL's schema, and those can be used with Spring-WS (wsimport will generate other service stubs that you won't need for Spring-WS).
If you are only interested in generating the POJOs from the WSDL, I think you could just get the XSD from the WSDL and use XJC tool to generate only the JAXB beans. This would avoid generating useless JAX-WS stubs.
I want to build a web services client that takes wsdl link as the input and generates java classes. I know we can do this directly using Netbeans IDE where we provide the wsdl location during project setup. But I want the wsdl location to be provided when the client starts running. How do I do this?
Is the location that will be provided just used to specify the SOAP endpoint (for a web service whose WSDL was known at development time), or will it be a completely arbitrary WSDL?
In the first case, the web service client that was created by Netbeans has methods that accept an alternate SOAP endpoint URL. You can call those to use the client with a server whose location is not hard-coded in the client.
If however, the WSDL describes a completely unrelated service, how are you going to write Java code against it? You cannot use any interfaces derived from the WSDL (because they are not known at development time). You could only have a very generic SOAP client, where the user almost directly types in the XML that will be sent.