Java: Invoke web service using Axis2 stub class - java

I'm new to web services. With all difficulty I have generated a simple 'Hello World' web service :D. I want to invoke the web service using java. The web service has a hard coded value shown as the output. Here is what I have tried.
I have created a new Dynamic web Project in Eclipse for web service client.
To this project generated stub classes for the web service using Axis2 and Eclipse.
I am not able to understand what the generated stub class basically contain, and how to use the stub class to invoke the webservice.
The stub class generated has too many lines of code. which i cannot paste it here; Is there any particular class that i need to concentrate on inorder to invoke a method in the webservice?
Part of the wsdl look like this
<wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://sample.com/Webservice/wsTest" targetNamespace="http://sample.com/Webservice/wsTest">
<xsd:element name="test" type="tns:test"/>
<xsd:element name="testResponse" type="tns:testResponse"/>
<xsd:complexType name="test">
<xsd:sequence></xsd:sequence>
</xsd:complexType>
<xsd:complexType name="testResponse">
<xsd:sequence>
<xsd:element name="outputString" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="wsTest_PortType_test">
<wsdl:part name="parameters" element="tns:test"></wsdl:part>
</wsdl:message>
Could you please let me know how to invoke a web service using Java in eclipse.
Later part: In case my webservice has input(eg: web service for addition) how do i pass the request parameters and get an output as a response.

I think this will definitely helps you
Just go through step by step procedure according to it,then you can achieve easily your Requirement.
the Link is here:
http://www.ibm.com/developerworks/webservices/library/ws-apacheaxis/index.html?ca=dat

Related

How to generate case sensitive fields in java from wsdl using cxf-codegen-plugin?

I'm using cxf-codegen-plugin and try to generate java from wsdl.
In my xsd schema I have following element
<xsd:element name="SomeElement">
<xsd:complexType>
<xsd:attribute name="version" type="xsd:string" use="optional">
</xsd:attribute>
<xsd:attribute name="Version" type="xsd:string" use="optional">
</xsd:attribute>
</xsd:complexType>
</xsd:element>
CXF tries to generate both attributes into field version and throws exception that property already exists.
Is there any way to generate properties as they described in XML? e.g.
protected String version;
protected String Version;
I know, that I can define binding and rename one of the properties, but I have ~100 wsdl, so I don't want write bindings for each file.
I also tried to add -autoNameResolution argument, but it didn't help.

Java SOAP WebService - How to accept single input parameter

I'm developing a SOAP based Webservice API which would be used by a third party system. WSDL file and endpoint URL would be shared with them and they invoke my Web service by passing an input parameter and get the response back
So far, I have created the Web Service API including WSDL, Services Classes, Helper Classes, DAO, Ibatis) and tested using SOAP UI by passing the input parameter, the request hits the databse and returning the response fine. Attached the WSDL file and SOAP request and response.
I got two questions,
The 3rd Party system is asking for an API documentation and SOAP Envelope. What should I give?
The 3rd party system has to invoke my service by passing the input parameter sQuoteRef. How would they usually do it? I'm not concerned about the client code here but how would the request from 3rd party look like and what changes I should make in my WSDL or Java classes to receive the input parameter and pass on to my service class?
Any inputs would be helpful in completing my task. Many Thanks!
WSDL File
<?xml version="1.0" encoding="UTF-8"?><wsdl:definitions name="EmpService" targetNamespace="http://emp.provider.integration.gi.sample.ie/EmpService/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://Emp.provider.integration.gi.sample.ie/EmpService/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xsd:schema targetNamespace="http://Emp.provider.integration.gi.sample.ie/EmpService/">
<xsd:element name="EmpRequestVO">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="sQuoteRef" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="EmpResponseVO">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="0" name="sQuoteStatus" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
<wsdl:message name="GetEmpTransactionSoapIn">
<wsdl:part element="tns:EmpRequestVO" name="parameters"/>
</wsdl:message>
<wsdl:message name="GetEmpTransactionSoapOut">
<wsdl:part element="tns:EmpResponseVO" name="parameters"/>
</wsdl:message>
<wsdl:portType name="EmpServiceSoap">
<wsdl:operation name="getEmpTransaction">
<wsdl:input message="tns:GetEmpTransactionSoapIn"/>
<wsdl:output message="tns:GetEmpTransactionSoapOut"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="EmpServiceSoap" type="tns:EmpServiceSoap">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getEmpTransaction">
<soap:operation soapAction="getEmpTransaction" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="PLUSEmpServices">
<wsdl:port binding="tns:EmpServiceSoap" name="EmpServiceSOAP">
<soap:address location="http://localhost:9080/WebServices/services/EmpServiceSOAP"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
End Point URL
http://localhost:9080/PLUSEmpServices/services/EmpServiceSOAP
SOAP REQUEST in SOAP UI
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rtw="http://emp.provider.integration.gi.sample.ie/EmpService/">
<soapenv:Header/>
<soapenv:Body>
<rtw:EmpRequestVO>
<sQuoteRef>12123118</sQuoteRef>
</rtw:EmpRequestVO>
</soapenv:Body>
</soapenv:Envelope>
SOAP RESPONSE in SOAP UI
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header/>
<soapenv:Body>
<p900:EmpResponseVO xmlns:p900="http://emp.provider.integration.gi.sample.ie/EmpService/">
<sQuoteStatus>Active</sQuoteStatus>
</p900:EmpResponseVO>
</soapenv:Body>
</soapenv:Envelope>
The 3rd Party system is asking for an API documentation and SOAP Envelope. What should I give?
To start APIs integration with external parties, your clients require a technical API document that will be a reference to complete APIs integration and a base for any technical communication between the teams. The technical document may includes the following details:
Brief description for different available web-services APIs and their requirements.
APIs communications flow. This will be useful in case the clients need to call more than one services in specific sequence. Including flow diagram will be possible option to explain the system flow.
Test environment details like WSDL URL and access credentials like username, password, agent code, etc.
Detailed description for all fields needed to send a valid request to the server. Fields details may include the following:
a. Filed name.
b. Description.
c. Data Type.
d. Max length.
e. Mandatory, Optional or Conditional.
f. Possible values if any.
All possible response codes a long with their description sent by server API to client API which indicates the successful or failure of transaction process(s). For example (0000 means Success, E001 means validation error, E002 system error, 9999 unknown error, etc.).
Note: Response codes should cover various rejection cases.
Security Section that explain how the data is exchange securely between client and server application.
a. Mention additional Encryption mechanism for part or all request data if any.
b. Communication type with the client wither it is over VPN or accessed public
over https URL. Note the URL you mentioned in your question is deployed in your local machine and it will not be available publicly.
Sample SOAP request(s) and response(s) xml format for all available API’s web methods.
Mention any additional rules or constrains on APIs connectivity.
The 3rd party system has to invoke my service by passing the input parameter sQuoteRef. How would they usually do it? I'm not concerned about the client code here but how would the request from 3rd party look like and what changes I should make in my WSDL or Java classes to receive the input parameter and pass on to my service class?
If I understand you correctly your are asking how should I change WSDL or Java classes to accept client request correctly ? Usually the server side API has the upper hand in XML format need to be exchanged and in your case it should be mentioned in WSDL. So the client will create a valid request as per definition mentioned in server WSDL URL.
Further reading that my be useful on how to generate WSDL from Java classes:
Eclipse WSDL generator (from java class)?
SOAP fault handling in java

generate java classes from xsd with mutlitlevel imports

I am trying to generate java classes from xsd using JAXB plugin but not able to get the effect as I want.
My use case is :
a.xsd has some elements.
b.xsd has some elements.
composite.xsd needs to have some elements from "a.xsd" and "b.xsd" as well as it's own elements.
I have tried many options so far. I can import the xsds ( a and b ) into "composite" but that would only enable me to use the elements from "a" and "b" into "composite" xsd but when I generate the classes using jaxb, it won't automatically bring all contents from "a and b".
For example :
a.xsd -> has "name" element.
b.xsd -> has "phone" element.
composite.xsd -> imports a and b and has "nickname" element.
So if I don't explicitly use "name" and "phone" in composite.xsd, generated java class won't generate those. Also there could be multilevel imports ( kind of inheritance like composite.xsd includes "b.xsd" and "b.xsd" includes "a.xsd ).
So I want composite to have all elements from "a" and "b" in generated class without explicitly repeating a.xsd and b.xsd's elements in composite.xsd.
DESIRED OUTPUT:
composite.class
name, phone, nickname.
Please advise.
Here are some more details with xsd details:
( field names are different that what I put in the original question but will give a gist of it. ).
**a.xsd**
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="Customer">
<xsd:sequence>
<xsd:element name="name" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
**b.xsd**
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="Payments">
<xsd:sequence>
<xsd:element name="amount" type="xsd:float" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
**composite.xsd**
<xsd:include schemaLocation="x.xsd" />
<xsd:include schemaLocation="y.xsd" />
<xsd:complexType name="CustomerPayments">
<xsd:sequence>
<xsd:element name="customer" type="Customer" />
<xsd:element name="payments" type="Payments" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
WITH above xsds, what I want to achieve is to have a composite java class (generated by JAXB maven plugin ) to automatically have fields like "name" and "amount" from imported/included xsds.
The generated CustomerPayments class will not contain propertiesname or amount, this is not how XJC works.
But it will contain field customer and payments of types Customer and Payments which will contain properties name and amount respectively. So you can do customerPayments.getCustomer().getName() at the end.

SOAP via jax-ws: entity classes missing in schema

So, I have a soap server-side project. Annotations - #WebService over interface and implementation, #WebMethod over interface' methods, #XmlRootElement over entity-classes that are in return and arguments in web-methods, and #XmlElement over their fields(over getters actually). Tried also partially and fully swap #XmlRootElement with #XmlType, and #XmlElement with #XmlAttribute.
Project is launched via publisher class or via Tomcat(WSServletContextListener), everything's working after weeks of trial and error. In WSDL schema, for instance:
<xsd:element name="Sell_i">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="0" name="session" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="terminal" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="info" nillable="true" type="tns:TransactionSellInfo"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Represents the Sell_i method. TransactionSellInfo is an input argument here, and tns points to this namespace aka this wsdl. So, it should be described here. It of course has all the annonations. But, it's just missing, as well as every other class. What's the solution?
Worth noting: schema type is RPC(tho changing to Document doesn't cause classes to appear in wsdl). Also, on the same machine wsimport from wsdl creates classes for those missing entities, which is very wierd(didn't test wsimport on other machines tho). But soapUI won't work with that wsdl and rightfully says that it's malformed.
Maybe it's something quite basic that I'm missing, but google gives nothing useful on all my tries. Any help is appreciated!

Sax: XMLReader: Streaming and converting CSV to Xml and validating the result at the same time

I have to transform some CSV files (each > 600 MB) to XML while validating the end result with an XSD on the fly.
Because of the size of each file I'm using InputStreams to read the content and OutpuStreams to stream the result back to my clients as XML.
Let's start then with the easy part... (pseudocode)
void transform(final InputStream CSVCustomerStream, final OutputStream outputStream) {
outputStream.write("<customers>")
foreach csvCustomerRow in CSVCustomerStream {
String xmlCustomerRow = csvCustomerRow.toXML();
outputStream.write(xmlCustomerRow.getBytes();
}
outputStream.write("</customers>")
**MISSING_XMLVALIDATOR.parse(outputStream);**
}
So far, each row of my source CSV file is transformed to xml and then written to the outputstream.
Easy enough.
The part though, where the xml is actually validated is still missing.
For this I looked into XMLReader's parse() method. The only problem with that, is the fact that parse() only accepts InputSources, while at the same time I'm streaming the content I'd like to be validated to an OutputStream.
Of course, after reading the whole CSV content, I could turn the OutputStream into an InputStream via
new ByteArrayInputStream((outputstream).toByteArray())
but that would immediately bring 600 MB worth of XML back into memory, defying the whole purpose of streaming.
PS: I have no control over the exact implementation of the OutputStream since my code runs as a REST-webservice
return Response.ok(new StreamingOutput() {
#Override
public void write(OutputStream output) throws Exception {
.... loading and transforming csv ...
}
}).build();
Building on your comment, let me put forward the "worst" possible scenario, one where the XSD is authored as a Russian Doll (i.e. except for a document root, all other element and types are defined locally). Because of this style, there is no way to validate the xmlCustomerRow against the XSD, since there is no global element declaration which would match your tag (assume customer).
<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" xmlns="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="customers">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="customer" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Still, the solution is not that complicated. Take a look at this modified XSD:
<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" xmlns="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="customers">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="customer" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="customer">
<xsd:complexType>
</xsd:complexType>
</xsd:element>
</xsd:schema>
For this setup, you only need to open the original XSD as an XML, clone the customer element, remove its minOccurs/maxOccurs attribute, and then insert it as a child of the schema (it would be the document element in the XML). The idea here is that you could do a refactoring on the fly, or manually, etc.
There's always a possibility that you wouldn't have to do anything i.e. if the customer element is already global, something like this:
<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" xmlns="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="customers">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="customer" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="customer">
<xsd:complexType>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Other complications may arise, depending on how your XSD really looks like, but I can assure you that there could be nothing in there which would stop you from doing whatever refactoring you may need to achieve exactly what you want.
I am rather of the opinion that having the ability to validate each record independently beats anything else. More so, for a massive file running on a multi-core/CPU machine, you could parallelize your validation, which would make more efficient use of resources to achieve increased throughput.
It might be that tests will be sufficient to assure that your conversion produces XML that validates with the given XSD, or that (as Petru Gardea said in a comment) you can validate piecemeal using temporary strings.
But assuming that you actually have to validate on the fly, there are some tricks you can try, basically by manipulating streams.
You are producing an OutputStream that presumably you want to send to your client, and you have a process that you know how to do that needs an InputStream (actually the Reader interfaces might make some of this easier, but the fixes are parallel).
This means that you have to "tee" the OutputStream, i.e., duplicate it on-the-fly so you can send one stream to the client and use the copy for validation parsing. And you need to get an InputStream from your copied OutputStream.
For the "tee" process, you should consider Apache Commons TeeOutputStream, and for conversion from output to input, you should probably look at PipedInputStream and PipedOutputStream.

Categories