Im a bit confused. I have a WS which has different "message format" than another WS I have seen in the past.
The vendor provided me a set of messages which they can accecpt (I have tested in SoapUI and it really works - well)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"xmlns:urn="urn:SAMPLE">
<soapenv:Header/>
<soapenv:Body>
<urn:CustomEnvelope>
The problem is, that in place where CustomEnvelope is used I would expect any method name (something like urn:calculateSum).
When I have tried to generate java client using Axis2, than in case od ADB databinding method I got uncompileable code. When I have used another one, I had on my Stub object only method named (for example) calculateSum and generated message doesn't correspond to the expected schema (instead od CustomEnvelope) there was used calculateSum.
My question is. Do you know what this strange format means? And have you any suggestion how to integrate such strange WS? I think about creating the whole XML using JAXB (vendor has provided a XSD files) and sending to the WS or creating SOAPMessages using standard Java API. But I am not sure what is there the best sollution.
Thanks, Ondrej
I had this issue during the Axis 2 client side stub generation, which gives you uncompileable code. Error is at the ADBDataSource class.
If this is your problem then here is the solution. What I did in my project, we are using WebSphere as the web application server and it contains a jar file (Something)ThinClient.jar in the class path of your project.
Now this jar also contains same class called ADBDataSource but its an abstract class. Which conflicts with our stubs because it creates object of ADBDataSource.
I suggest try to find out that do you have a such jar or not.
Solution
Remove (Something)ThinClient.jar or one which has same class from your class path.
If removing (Something)ThinClient.jar creates problem, then change the approach and use Jax-Ws insteadof Axis 2, which is part of Java it self. (This is what I did.)
Related
I have created a SOAP web-service, running in a tomcat container, using CXF and a WSDL contract approach. The Java code was generated from the WSDL using the maven plugin "cxf-codegen-plugin".
Now, I would like to also expose the web-service as a custom HTTP / JSON web-service by mapping the XML data into JSON data. But I haven't been successful yet and I would appreciate any help to achieve that.
I found that old documentation https://cxf.apache.org/docs/json-support.html on CXF's website (which has also been recently duplicated and not corrected here https://cwiki.apache.org/confluence/display/CXF20DOC/JSON+Support). I got it running with a small fix : sf.setBindingId(HTTPBinding.HTTP_BINDING); instead of sf.setBindingId(HttpBindingFactory.HTTP_BINDING_ID); since HttpBindingFactory does not exist anymore in CXF 3.x versions.
The first issue with that solution is that it depends on jettison-json whose last release was published in July 2016. The project looks dead. I could not find any suitable replacement. I only found StAXON which is worst : last release in February 2014.
Is there any other library that is well maintained and that implements StAX ?
The second issue is that the example uses a server bean while I already have a container. For the SOAP service, I simply use the public static Endpoint publish(String address, Object implementor) function.
How can I use both the Tomcat container and the JSON/XML conversion ?
The third issue is that I could not send a valid JSON request so far. The absence of documentation does not help. Still, I managed to get as far as sending a valid JSON equivalent of the SOAP header content. But I could not manage to guess how to make CXF also reads the equivalent of the SOAP body. The Java interface of the web-service is public Response get(Header header, Body body); and I keep getting errors : org.apache.cxf.interceptor.Fault: wrong number of arguments while invoking public abstract Response ServicePort.get(Header,Body) with params [Header#88f6973[user=bbcc2545-27ea-43cd-a1fe-c4a194258e0f]]. Obviously the body is missing.
Is there anyone who knows the right JSON syntax to send a request to a CXF HTTP / JSON web-service that relies on jettison-json ? (Or where could one find a comprehensive documentation ?)
So I have a web service in NetBeans 8.1, for which I've written the wsdl with embedded XSD (and an external ref also).
Now I need to be able call the SOAP service on other instances of the application:
i.e. have instance X call a method on instance Y, as a secondary goal of the application.
I don't like to use NetBeans automatic SOAP client wizards, as I would be pointing to the very service which I'm building - it would potentially be a chicken and the egg type of thing during building. Secondly, I already have all the required JAXB types used by the web service, so it should be easy to construct a client right?
Well my trouble starts when I want to use JAXB to marshal my request object into a javax.xml.soap.SOAPBodyElement (my current strategy is to use SAAJ for the client part), but how to add a Schema to the marshaller? the schema is embedded in the wsdl, and I can't figure out how to reference it.
I figured that I could split out the schema part into a separate XSD file, but I'm missing an annotation option for #WebService, where I can provide an XSD file, just like I can provide a wsdl file (currently the 'wsdlLocation' points to both wsdl & xsd as it is embedded).
I guess I may have to live with not doing XSD validation on the client side(it is enabled server-side), as it seems tricky to get a Schema object from the wsdl - is that possible somehow?
You can read the .wsdl as an InputStream and transform it to a DOMResult. You can then get the "schema" node from the DOMResult and turn it into a DOMSource. With that, you can make a Schema object using the Source[] constructor.
I haven't got it to work myself, I had too many imports and it became hell to manage the namespaces. The only code I found on this was in "SOA Using Java Web Services" by Mark Hansen, chapter 7.5.1: Validation. I don't think I can put that code here, but all the code you should need for this use case is in there.
From a colleague I have received a WSDL file that describes the web service he is offering, and which I am supposed to call from my code. I would now like to do two things:
1) Implement the client
2) Have a stub server that I can use for testing, until I have access to the real server.
What I tried is the following:
wsimport -clientjar foo.jar foo.wsdl
This gives me a jar file that contains the Datatype that will contain the data to be posted to the web service, and also an ObjectFactory. I guess I will have to use it as follows:
TestDataType testDataType = new TestDataType();
testDataType.setFoo("foo");
testDataType.setBar("bar");
ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<TestDatatype> request = objectFactory.createTestRequest(testDatatype);
Now how do I send this request?
Also a class TestDemoService annotated with #WebServiceClient has been generated. How do I run this class?
Any advice is highly appreciated.
You've created the client. To use this client you need to set the endpoint(if not already set) and call the service using the generated api.
This site should be a good reference.
Using wsimport
I generate WSDL files for several web services (from the server service definitions) where I have already XML schemas (*.XSD) for the beans used as parameters. How do I tell java2ws to reference these (include the external XSD) and not generate its own into the WSDL?
I have tried the -createxsdimports, but that does generate its own XSD files.
Is there a Java Annotation that I can use to let CXF know where the XSD for each file/package is?
Try the #XmlSchema annotation. It includes a location parameter that is used to tell JAXB that a real schema exists:
#XmlSchema(location="http://www.example.com/xsds/foo.xsd")
package com.example.foo;
I have a CXF Webservice that imports external schema files. When I built it; I spent quite a bit of time trying to sort out the exact scenario you're trying to achieve. Unfortunately, it appears that CXF does not respect the #XmlSchema(location="") annotation when generating WSDL from java. Daniel Kulp, the main CXF dev told me at the time this was a known issue but not enough people are complaining about it so it's not high on their list of priorities to fix.
So I ended up writing the WSDL by hand and then generating the SEI from the WSDL file. Of course, if you hand-write the WSDL you can do whatever you want.
Do bear in mind that one side-effect of this is that the external schema file needs to be accessible by an HTTP GET - both while generating the SEI AND when the webservice app starts up - CXF will retrieve the schema file on startup. Same goes for when you generate the client, of course. This does create a bit of a messy architectural dependency; but there appears to be no way to tell CXF "myschema.xsd" is available at http://myurl.com/myschema.xsd but ALSO in /src/main/schema/myschema.xsd.
I am using axis2 to expose a method of existing class as a web service (bottom-up approach). The method takes a complex object (non-primitive type) as a parameter and returns a complex object as well.
I understand that axis2 will try to generate the schema for me in the wsdl file when I expose the method as a web service, and I can get the wsdl file by visiting the web service url and append ?wsdl into the end of it.
But upon closer examination, some of the attributes of the complex type in the parameters are represented as xs:anyType in the schema part of the resulting wsdl. The attributes that are converted into xs:anyType is a List. The bad thing with this is that when I generate the stub code for the client code, the method signature to set that particular attributes will take in an object as a parameter i.e. setAttribute(Object obj).
So my solution to this is to use JAXB 2.0 to generate the xml schema of the classes I need and then, import the xsd into the wsdl file that is generated by axis2 (downloaded from the web service url + ?wsdl) and use the edited wsdl instead of the one automatically generated. This solution seems to be working well for the client side. The method signature to set the attributes generated by the stub code will take in the proper type i.e. setAttribute(AnotherComplexType abcd). And by using tcpmon, I can see that the xml that is sent from the client to the server seems to be correct.
However, this approach does not work well for the server side because axis2 does not use the JAXB 2.0 annotation to convert the xml received back into the classes that the exposed method will be able to process.
My question is, is there anyway to solve my problem? The possible ways I can think of is either to modify the way axis2 process the xml after receiving it (I'm okay with processing it manually if there is indeed a way), or to make axis2 work well with JAXB 2.0 annotation? Or maybe any other idea?
Note: I'm not using the JAX-WS part of axis2
In the end I solved this myself. I generated the stub code for server side using the wsdl, modify the messageReceivers to use the generated message receiver instead, write a wrapper class that implements the generated interface, write a converter to convert the object from generated types in the parameter of the wrapper class methods going to be exposed to my internal types and expose the wrapper class instead.