Generating stub classes for 3rd party WS - web-services

I need to incorporate a pretty complex 3rd party web service into my Grails app. My plan was to use WSDL2Java to generate the stub classes from the wsdl, and this was the method recommended in the 3rd party's documentation (complete with examples). First i tried to use the Axis2 codegen plugin for Eclipse but eventually came up against an InvocationTargetexception. I debugged the plugin and found it was because the wsdl is defined with RPC encoding.
Some people have recommended using Axis 1.4 instead, so I've now installed that too but have come up against an IO Exception - Type {http://xml.apache.org/xml-soap}DataHandler is referenced but not defined.
Can anyone suggest a method for creating the java classes from this wsdl without having to hack the wsdl apart?

I ended up using the Axis2 wdsl2java and copying the required annotated code into the service and used the CXF plugin. I also put in my service the following code
static expose=['cxfjax']
The reason why I had to do this was because there was a "complicated" (for grails) structure my methods look like
#WebMethod(operationName = "authenticate", action = "http://betterhidethis/authenticate")
#WebResult(name = "authenticateResult", targetNamespace = "http:/betterhidethis/")
public ArrayOfString authenticate(
#WebParam(name = "strUserName", targetNamespace = "http://betterhidethis/")
String strUserName,
#WebParam(name = "strPassword", targetNamespace = "http://betterhidethis/")
String strPassword) {
Of cause the Geneerator also created the ArrayOfString class which I use later.
Hope this helps.

Related

Creating webservice and client with JBossWS using Complex objects as arguments and return types

I am developing a WebService and Client for it using JBoss 5.1.0GA. The JBossWs stack was already preinstalled with the binary that I downloaded and as I understand it is JBossWs 3.1.2GA
I have developed a web service using this setup and have also created a client successfully. This is what I have.
A pojo web service deployed as a war file.
#WebService
public class Service{
#WebMethod
public CompleObj getConfiguration() {
CompleObj oConf = new CompleObj ();
for (int i = 0; i < 10; i++) {
NestObj oInst = new BOpRepoInstance("Val1", "Val2", "Val3", "Val4");
oConf.addRepoInstance(oInst);
}
return oConf;
}
}
Here,
CompleObj => is a Complex Object that has a list of type NestObj. Its
getter/setters, toString and some other methods.
NextObj => has 4 variables of Type String. Its getter/setters,
toString, hashCode, equals and some other methods.
Got this web service deployed successfully.
Later created a client using the eclipse wizard for generating Web Service Client using WSDL document. It also created a sample client file which would call the webservice and fetch the return value. This also worked like a charm.
Now my problem is, when eclipse generated stubs for clients it created classes for CompleObj and NestObj. These classes only has the variables and its getters/setters (this make sense as these are being generated from WSDL doc). Thus i loose a lot of other methods that includes toString, hasCode, equals etc, which I want to use at the Client side as well.
Now how can I make use of the actual class files defined in the WebService project directly and avoid the client to use the generated ones. I can provide the class files as .jar binary for the Client project, I cant really get how to achieve this.
Another question is, the web service location is embedded in the stubs directly, what can i do to have the webservice location passed as part of the argument to the invocation code?
The classes which are generated in the client side are just place
holders it is not deserilized version of your own classes,When you
invoke the service it is used to carry your object to server then
the JBOOSWS will do the JAXB mapping to the actual classes. So you
can not make the your own classes to be used in the client side
though they are look same.
URL will be fixed in the stub code, since in eclipse while generating WS client the first
thing you must provide is, the WSDL URL,then eclipse will generate the
client code accordingly,so generated code is specific to the WSDL
you provided. If you want to pass the WSDL dynamically,then you
need to have your own code to generate the client stubs by passed
WSDL URL using any WSDLtoJAVA or any other utility.

Flex Webservice

I'm using Flash Builder 4.5 and flex 4.5 language.
I'm using a webservice to retrieve data in json calling a .php.
<webservice:Webservice id="webservice" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/>
<s:CallResponder id="testResult" result="onTestResult(event)"/>
...
private function onTestResult(e:ResultEvent):void{
Alert.show(ObjectUtil.toString(testResult.lastResult));
}
In the "Test Operation" window of Flash Builder I made my call and the return is a json Object made by arrays.
If I call the same webservice from the code instead, it returns a (object)#0 so an empty Object. No errors thown, just an empty Object.
Anyone has some tips?
The ns prefix of your Webservice class susggests you're using a custom implementation, rather than the framework WebService class. However, you don't provide any specifics, so I'm gonna take a swing in the dark:
If your custom service is based off the HTTPService class, make sure you're setting the resultFormat='text'. The default is XML, which will be causing you problems.
If you're using the Framework WebService class, well - you can't, as it's designed for SOAP webservices, not JSON. (From the Docs for mx.rpc.soap.WebService:)
The WebService class provides access to SOAP-based web services on
remote servers.
If it's some other implementation, please provide more details.

JAX-WS changing namespace for WebParam

We're working with JAX-WS in conjuntion with JAXB (2.1).
First, we've created the Java classes linked to the XSDs types.
Then, using CXF (2.1.3), Spring (2.0.8) and JAX-WS we've published a Webservice from a JAXB type (in fact a #XmlType), like this:
#WebMethod(operationName = "addExample")
public #WebResult void addExample(
#WebParam(name = "EXAMPLE") EXAMPLETYPE exemple);
We know that the webservice is published using the package name of the interface (inverse) or using the #WebService annotation the "targetNamespace" we could define. In fact, we did it with something like:
#WebService(targetNamespace = "http://blablabla")
At this time, we need to maintain the whole targetNameSpace of the WebService but we need to change the namespace of the #java.jws.WebParam (i.e EXAMPLE param in our case).
It is possible? The annotation never works for us, doing things like that:
#WebMethod(operationName = "addExample")
public #WebResult void addExample(
#WebParam(name = "EXAMPLE", targetNamespace = "http://thats.all.folks") EXAMPLETYPE exemple);
We are really lost...
Thank you,
I think you need to upgrade to a newer (and supported) version of CXF. I believe this was a bug that was fixed a very long time ago.

What Java library that would auto-generate all the boiler-plate code for calling Web Service?

There is wsimport command that generates all the types referenced in WSDL. But this does not do anything with all the remaining boilerplate of calling a web service method, parsing XML into Java objects etc.
Suppose a web service as defined by the service provider WSDL called CustomerService provides an operation getCustomerAddress(String CustomerID) and returns object of type CustomerAddress.
wsimport only generates types such as CustomerAddress. What I am looking for is auto-generated code like:
String AppID = "" ; // autogenerated (if there was such parameter specified in WSDL)
String endpointA = "some end point";
CustomerAddress getCustomerAddress(String customerID) {
// all the bolierplate of actaully calling the webservice, unmarshalling the XML response
// including error/exception handling etc.
return result;
}
I like Spring web services, especially if you're already using Spring.

Add custom SOAP header in PowerShell using New-WebServiceProxy

In C# I can do the following:
var header = MessageHeader.CreateHeader("MyHeader", "http://mynamespace", "Header value");
OperationContext.Current.OutgoingMessageHeaders.Add(header);
That adds the following to the SOAP message:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<MyHeader xmlns="http://mynamespace">Header value</MyHeader>
....
</s:Header>
...
How can I similarly add a custom outgoing SOAP message header when calling methods on a proxy generated by the New-WebServiceProxy PowerShell commandlet?
Edit:
To clarify, I can make the same calls in PowerShell that I show in the C# above, but OperationContext.Current is always null. I get around that in C# by creating an OperationContextScope, but that requires the inner channel of the web service proxy, which PowerShell's proxy doesn't seem to provide.
Your C# code is using the OperationContext class from WCF. PowerShell's New-WebServiceProxy cmdlet does not use WCF, instead it creates classes based on the System.Web.Services.Protocols.SoapHttpClientProtocol class.
To get an instance of SoapHttpClientProtocol to send custom SOAP headers, you use SoapExtension, as described here:
http://blogs.msdn.com/b/kaevans/archive/2007/08/06/programmatically-insert-soapheader-into-soap-request-with-asmx-soapextensions.aspx
Due to the need to create a new class inheriting from SoapExtension, porting the content of the blog post to PowerShell will most likely involve use of embedded C# via the Add-Type cmdlet's TypeDefinition parameter.