I've wrote some simple service that consists of several files (wsdl, xsd).
In xsd file I've got following definition:
<xs:complexType name="ServerMessage">
<xs:sequence>
<xs:element name="type" type="xs:int"/>
<xs:element name="info" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="ServerMessage" type="tns:ServerMessage"/>
Then this element is referenced in wsdl file like this
<wsdl:message name="createItemFault">
<wsdl:part name="createItemFault" element="tns:ServerMessage"/>
</wsdl:message>
<wsdl:portType name="Service">
<wsdl:operation name="createItem">
<wsdl:input message="tns:createItemRequest"/>
<wsdl:output message="tns:createItemResponse"/>
<wsdl:fault name="Fault" message="tns:createItemFault"/>
</wsdl:operation>
And at last
<wsdl:binding name="ServiceBinding" type="intf:Service">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="createItem">
<soap:operation soapAction="http://test.com/createItem"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="Fault">
<soap:fault name="Fault" use="literal"/>
</wsdl:fault>
</wsdl:operation>
After launching WSDL2Java I receive the following code
public interface ServerMessage extends org.apache.xmlbeans.XmlObject
{
How come ServerMessage becomes defined like this? When I've used WSDL2Java provided by Axis1 final definition in java file was like this
public class ServerMessage extends org.apache.axis.AxisFault implements java.io.Serializable
And after Axis2 generation resulting "item" is drastically differs, it's not even throwable. What am I doing wrong?
From that WSDL you should get a CreateItemFault (due to the wsdl:message name) that looks something like:
public class CreateItemFault extends java.lang.Exception {
private org.example.www.service.ServerMessageDocument faultMessage;
...
}
That ServerMessageDocument probably looks like:
public interface ServerMessageDocument extends org.apache.xmlbeans.XmlObject {
...
org.example.www.service.ServerMessage getServerMessage();
void setServerMessage(org.example.www.service.ServerMessage serverMessage);
org.example.www.service.ServerMessage addNewServerMessage();
...
}
And here's where we get to your ServerMessage:
public interface ServerMessage extends org.apache.xmlbeans.XmlObject {
...
}
The method signature should throw a CreateItemFault, though.
Related
Faced a problem. How to put input data into a soap request, which is generated by means of SOARequestCreator (com.predic8.wsdl library).
My method:
#SneakyThrows
public String parseTEst(MultipartFile file) {
WSDLParser parser = new WSDLParser();
Definitions defs = parser.parse(file.getInputStream());
StringWriter writer = new StringWriter();
HashMap<String, String> formParams = new HashMap<String, String>();
formParams.put("xpath:/Add/intA", "1");
formParams.put("intB", "2");
SOARequestCreator creator = new SOARequestCreator(defs, new RequestTemplateCreator(), new MarkupBuilder(writer));
creator.setFormParams(formParams);
creator.createRequest("CalculatorSoap", "Add", "CalculatorSoap");
System.out.println(writer);
return writer.toString();
}
This method returtn:
<s11:Envelope xmlns:s11='http://schemas.xmlsoap.org/soap/envelope/'>
<s11:Body>
<ns1:Add xmlns:ns1='http://tempuri.org/'>
<ns1:intA>?999?</ns1:intA>
<ns1:intB>?999?</ns1:intB>
</ns1:Add>
</s11:Body>
</s11:Envelope>
How to replace "intA" and "intB"?
I think this should most likely be done here:
HashMap<String, String> formParams = new HashMap<String, String>();
formParams.put("xpath:/Add/intA", "1");
formParams.put("intB", "2");
SOARequestCreator creator = new SOARequestCreator(defs, new RequestTemplateCreator(), new MarkupBuilder(writer));
creator.setFormParams(formParams);
Because so in the documentation on tis site(http://www.membrane-soa.org/soa-model-doc/1.4/java-api/create-soap-request.htm):
HashMap<String, String> formParams = new HashMap<String, String>();
formParams.put("xpath:/create/article/name", "foo");
formParams.put("xpath:/create/article/description", "bar");
formParams.put("xpath:/create/article/price/amount", "00.00");
formParams.put("xpath:/create/article/price/currency", "USD");
formParams.put("xpath:/create/article/id", "1");
//SOARequestCreator constructor: SOARequestCreator(Definitions, Creator, MarkupBuilder)
SOARequestCreator creator = new SOARequestCreator(wsdl, new RequestCreator(), new MarkupBuilder(writer));
creator.setFormParams(formParams);
My wsdl file:
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://tempuri.org/"
xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://tempuri.org/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
<s:element name="Add">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="intA" type="s:int"/>
<s:element minOccurs="1" maxOccurs="1" name="intB" type="s:int"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="AddResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="AddResult" type="s:int"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="Subtract">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="intA" type="s:int"/>
<s:element minOccurs="1" maxOccurs="1" name="intB" type="s:int"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="SubtractResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="SubtractResult" type="s:int"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="Multiply">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="intA" type="s:int"/>
<s:element minOccurs="1" maxOccurs="1" name="intB" type="s:int"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="MultiplyResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="MultiplyResult" type="s:int"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="Divide">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="intA" type="s:int"/>
<s:element minOccurs="1" maxOccurs="1" name="intB" type="s:int"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="DivideResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="DivideResult" type="s:int"/>
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="AddSoapIn">
<wsdl:part name="parameters" element="tns:Add"/>
</wsdl:message>
<wsdl:message name="AddSoapOut">
<wsdl:part name="parameters" element="tns:AddResponse"/>
</wsdl:message>
<wsdl:message name="SubtractSoapIn">
<wsdl:part name="parameters" element="tns:Subtract"/>
</wsdl:message>
<wsdl:message name="SubtractSoapOut">
<wsdl:part name="parameters" element="tns:SubtractResponse"/>
</wsdl:message>
<wsdl:message name="MultiplySoapIn">
<wsdl:part name="parameters" element="tns:Multiply"/>
</wsdl:message>
<wsdl:message name="MultiplySoapOut">
<wsdl:part name="parameters" element="tns:MultiplyResponse"/>
</wsdl:message>
<wsdl:message name="DivideSoapIn">
<wsdl:part name="parameters" element="tns:Divide"/>
</wsdl:message>
<wsdl:message name="DivideSoapOut">
<wsdl:part name="parameters" element="tns:DivideResponse"/>
</wsdl:message>
<wsdl:portType name="CalculatorSoap">
<wsdl:operation name="Add">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Adds two integers. This is a test
WebService. ©DNE Online
</wsdl:documentation>
<wsdl:input message="tns:AddSoapIn"/>
<wsdl:output message="tns:AddSoapOut"/>
</wsdl:operation>
<wsdl:operation name="Subtract">
<wsdl:input message="tns:SubtractSoapIn"/>
<wsdl:output message="tns:SubtractSoapOut"/>
</wsdl:operation>
<wsdl:operation name="Multiply">
<wsdl:input message="tns:MultiplySoapIn"/>
<wsdl:output message="tns:MultiplySoapOut"/>
</wsdl:operation>
<wsdl:operation name="Divide">
<wsdl:input message="tns:DivideSoapIn"/>
<wsdl:output message="tns:DivideSoapOut"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="CalculatorSoap" type="tns:CalculatorSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="Add">
<soap:operation soapAction="http://tempuri.org/Add" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Subtract">
<soap:operation soapAction="http://tempuri.org/Subtract" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Multiply">
<soap:operation soapAction="http://tempuri.org/Multiply" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Divide">
<soap:operation soapAction="http://tempuri.org/Divide" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="CalculatorSoap12" type="tns:CalculatorSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="Add">
<soap12:operation soapAction="http://tempuri.org/Add" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Subtract">
<soap12:operation soapAction="http://tempuri.org/Subtract" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Multiply">
<soap12:operation soapAction="http://tempuri.org/Multiply" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Divide">
<soap12:operation soapAction="http://tempuri.org/Divide" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Calculator">
<wsdl:port name="CalculatorSoap" binding="tns:CalculatorSoap">
<soap:address location="http://www.dneonline.com/calculator.asmx"/>
</wsdl:port>
<wsdl:port name="CalculatorSoap12" binding="tns:CalculatorSoap12">
<soap12:address location="http://www.dneonline.com/calculator.asmx"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Help me pls!
Thanks!
Most likely because the xpath expression is different than the first? The second one doesnt have the xpath: prefix ? That still doesnt explain why the first one doesnt work.
formParams.put("xpath:/Add/intA", "1");
formParams.put("intB", "2");
I faced the same problem and took me quite a while to figure it out. The params values are correct, but the creator is not the one needed.
SOARequestCreator creator = new SOARequestCreator(defs, new RequestTemplateCreator(), new MarkupBuilder(writer));
Will generate the payload without any values from the params because RequestTemplateCreator is used. If instead RequestCreator is used, values will be filled.
I am using spring soap ws.
I have following JAXB domain classes correspond to complex types
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"reference",
"reason"
})
#XmlRootElement(name = "request-message")
public class RequestMessageType {
#XmlElement(name = "reference", required = true)
protected String reference;
#XmlElement(name = "reason")
protected String reason;
// I have getters and setters but removed here.
}
I have following class with #XmlRegistry annotations
#XmlRegistry
public class ObjectFactory {
private final static QName _RequestMessage_QNAME = new QName("http://namespace/url", "request-message");
public ObjectFactory() {
}
#XmlElementDecl(namespace = "http://namespace/url", name = "request-message")
public JAXBElement<RequestMessageType> createDisconnectRequestMessage(RequestMessageType value) {
return new JAXBElement<RequestMessageType>(_RequestMessage_QNAME, RequestMessageType.class, null, value);
}
}
Following are endpoints
#Endpoint
public class FirstEndPoint {
private static final String NAMESPACE_URI = "http://first/url/version";
private static final Logger LOG = Logger.getLogger(FirstEndPoint.class);
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "request-message")
#ResponsePayload
public JAXBElement<ResponseMessageType> requestMessage(#RequestPayload JAXBElement<RequestMessageType> requestMessage) {
LOG.info("request-message : first version ID : " + requestMessage.getValue().getReference());
//Preparing response and return response
}
}
#Endpoint
public class SecondEndPoint {
private static final String NAMESPACE_URI = "http://second/url/version";
private static final Logger LOG = Logger.getLogger(SecondEndPoint.class);
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "request-message")
#ResponsePayload
public JAXBElement<ResponseMessageType> requestMessage(#RequestPayload JAXBElement<RequestMessageType> requestMessage) {
LOG.info("request-message : second version ID : " + requestMessage.getValue().getReference());
//Preparing response and return response
}
}
When I make Soap request, I am using NAMESPACE_URI given in endpoints in soap request.
Here, in this case, I am getting following response
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring xml:lang="en">unexpected element (uri:"http://first/url/version", local:"request-message"). Expected elements are <{http://namespace/url}request-message></faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
If I use "http://namespace/url" as NAMESPACE_URI in endpoint and in soap request I am getting the proper response but I try to make it different for two endpoints with two different namespaces then it is not working and gives above response.
How can I use two different namespaces for two different endpoints with same JAXB class? I am completely new to spring and web service.
Additional info : RequestMessageType class and ObjectFactory class are in one package and in package-info.java namespace is
#javax.xml.bind.annotation.XmlSchema(namespace="http://namespace/url",elementFormDefault=javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.example
Do I need to change anything in package-info.java file ?
I created a sample project. I hope it can be useful to you. You can give a look at it here: https://github.com/angeloimm/spring-ws-sample
Basically this is my WSDL file (in SOAP Web Service all is ruled by WSDL):
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:ss="http://www.example.org/SpringSample/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="SpringSample"
targetNamespace="http://www.example.org/SpringSample/">
<wsdl:types>
<xsd:schema targetNamespace="http://www.example.org/SpringSample/">
<xsd:complexType name="abstractRequest">
<xsd:sequence minOccurs="1" maxOccurs="1">
<xsd:element name="reqName" type="xsd:string" nillable="false"
maxOccurs="1" minOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="abstractResponse">
<xsd:sequence minOccurs="1" maxOccurs="1">
<xsd:element name="responseName" type="xsd:string"
nillable="false" maxOccurs="1" minOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:element name="requestImplementation" type="ss:abstractRequest" />
<xsd:element name="responseImplementation" type="ss:abstractResponse" />
<xsd:element name="requestImplementation2" type="ss:abstractRequest" />
<xsd:element name="responseImplementation2" type="ss:abstractResponse" />
</xsd:schema>
</wsdl:types>
<wsdl:message name="OperationRequest">
<wsdl:part element="ss:requestImplementation" name="request" />
</wsdl:message>
<wsdl:message name="OperationResponse">
<wsdl:part element="ss:responseImplementation" name="response" />
</wsdl:message>
<wsdl:message name="OperationRequest2">
<wsdl:part element="ss:requestImplementation2" name="request2" />
</wsdl:message>
<wsdl:message name="OperationResponse2">
<wsdl:part element="ss:responseImplementation2" name="response2" />
</wsdl:message>
<wsdl:portType name="SpringSample">
<wsdl:operation name="Operation1">
<wsdl:input message="ss:OperationRequest" />
<wsdl:output message="ss:OperationResponse" />
</wsdl:operation>
<wsdl:operation name="Operation2">
<wsdl:input message="ss:OperationRequest2" />
<wsdl:output message="ss:OperationResponse2" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="SpringSampleSOAP" type="ss:SpringSample">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Operation1">
<soap:operation style="document" soapAction="http://www.example.org/SpringSample/Operation1" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Operation2">
<soap:operation style="document" soapAction="http://www.example.org/SpringSample/Operation2" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="SpringSample">
<wsdl:port binding="ss:SpringSampleSOAP" name="SpringSampleSOAP">
<soap:address location="http://www.example.org/" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
As you can see I defined 2 complex type: abstractRequest and abstractResponse. Then I implemented them by using the elements requestImplementation,requestImplementation2,responseImplementation,responseImplementation2 According to WS-I specification you need to use separate operations and elements
Then I wrote this endpoint:
#Endpoint
public class SampleEndpoint
{
private static final Logger logger = LoggerFactory.getLogger(SampleEndpoint.class.getName());
private static final String NAME_SPACE_URI = "http://www.example.org/SpringSample/";
#PayloadRoot(namespace = NAME_SPACE_URI, localPart="requestImplementation")
#ResponsePayload
public JAXBElement<AbstractResponse> operationOneResp(#RequestPayload JAXBElement<AbstractRequest> ar)
{
if( logger.isDebugEnabled() )
{
logger.debug("Operation 1 request "+ar.getValue().getReqName());
}
ObjectFactory of = new ObjectFactory();
AbstractResponse aResp = of.createAbstractResponse();
aResp.setResponseName("operation 1 response");
JAXBElement<AbstractResponse> result = of.createResponseImplementation(aResp);
return result;
}
#PayloadRoot(namespace = NAME_SPACE_URI, localPart="requestImplementation2")
#ResponsePayload
public JAXBElement<AbstractResponse> operationTwoResp(#RequestPayload JAXBElement<AbstractRequest> ar)
{
if( logger.isDebugEnabled() )
{
logger.debug("Operation 2 request "+ar.getValue().getReqName());
}
ObjectFactory of = new ObjectFactory();
AbstractResponse aResp = of.createAbstractResponse();
aResp.setResponseName("operation 2 response");
JAXBElement<AbstractResponse> result = of.createResponseImplementation(aResp);
return result;
}
}
As you can see now I always use AbstractRequest and AbstractResponse JAXBElement in both methods. The 2 methods can also be in 2 different endpoints
I hope it's what you needed and it's useful
Angelo
I need to define custom exception in different namespace than a web service. But when I generate a wsdl, some wrapper appears in the namespace of webservice. Is it possible to use exception from another namespace without this wrapper?
Exception:
#WebFault(targetNamespace = "http://somenamespace/server/faults",
faultBean = "my.package.SoapBadRequestException.FaultBean")
public class SoapBadRequestException extends Exception {
private FaultBean faultBean;
#XmlType(name = "FaultBean", namespace = "http://somenamespace/server/faults")
public static class FaultBean {}
public SoapBadRequestException() { super(); }
public SoapBadRequestException(String message, FaultBean faultBean, Throwable cause) {
super(message, cause);
this.faultBean = faultBean;
}
public SoapBadRequestException(String message, FaultBean faultBean) {
super(message);
this.faultBean = faultBean;
}
public FaultBean getFaultInfo() { return faultBean; }
}
Web service:
#WebService(targetNamespace = "http://somenamespace/server/ws")
public interface MyWebService {
void someOperation(
#WebParam(name = "param1") String param1,
#WebParam(name = "param2") String param2) throws SoapBadRequestException;
}
Resulting wsdl (FaultBean is undefined, also don't know why):
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://somenamespace/server/ws"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:ns1="http://somenamespace/server/faults"
name="MyWebServiceImpl"
targetNamespace="http://somenamespace/server/ws">
<wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://somenamespace/server/faults"
attributeFormDefault="unqualified"
elementFormDefault="unqualified"
targetNamespace="http://somenamespace/server/faults">
<xsd:element name="SoapBadRequestFault" nillable="true" type="tns:FaultBean"/>
</xsd:schema>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://somenamespace/server/ws"
attributeFormDefault="unqualified"
elementFormDefault="unqualified"
targetNamespace="http://somenamespace/server/ws">
<xsd:element name="someOperation" type="tns:someOperation"/>
<xsd:complexType name="someOperation">
<xsd:sequence>
<xsd:element name="param1" type="xsd:string"/>
<xsd:element name="param2" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="someOperationResponse" type="tns:someOperationResponse"/>
<xsd:complexType name="someOperationResponse">
<xsd:sequence/>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="someOperationResponse">
<wsdl:part element="tns:someOperationResponse" name="parameters"></wsdl:part>
</wsdl:message>
<!-- This is the redundant wrapper in the web service namespece -->
<wsdl:message name="SoapBadRequestException">
<wsdl:part element="ns1:SoapBadRequestFault" name="SoapBadRequestException"></wsdl:part>
</wsdl:message>
<wsdl:message name="someOperation">
<wsdl:part element="tns:someOperation" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:portType name="MyWebService">
<wsdl:operation name="someOperation">
<wsdl:input message="tns:someOperation" name="someOperation"></wsdl:input>
<wsdl:output message="tns:someOperationResponse" name="someOperationResponse"></wsdl:output>
<wsdl:fault message="tns:SoapBadRequestException" name="SoapBadRequestException"></wsdl:fault>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="MyWebServiceImplSoapBinding" type="tns:MyWebService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="someOperation">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="someOperation">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="someOperationResponse">
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="SoapBadRequestException">
<soap:fault name="SoapBadRequestException" use="literal"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="MyWebServiceImpl">...</wsdl:service>
I saw this and this but nothing helped.
I followed this guide "http://wso2.com/library/1719/", I didn't modified nothig except in the part of java to wsdl where i setted the taget namespace as
http ://ws
and in schema target namespace
http ://ws
I used for this tutorial a service and a client. I generate correctly (the tomcat server doesn't give error in axis page) the.aar file and the wsdl from it.
Service:
`
import java.time.*;
import java.time.format.DateTimeFormatter;
public class ATMachine {
//program begin
public double deposita(double amount) {
Deposit.deposit = amount; //= read.nextDouble();
BalanceInquiry.balance = Deposit.deposit + BalanceInquiry.getBalance();
LocalDateTime date1= LocalDateTime.now();
String md= "deposit";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
String date2= date1.format(formatter);
BalanceInquiry.updateBalance(Deposit.deposit,BalanceInquiry.movement,md,date2);
return Deposit.deposit;
}
public double preleva(double amount) {
Withdraw.withdraw = amount;
LocalDateTime date = LocalDateTime.now();
String mw= "withdraw";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
String date3= date.format(formatter);
BalanceInquiry.updateBalance(Withdraw.withdraw,BalanceInquiry.movement,mw,date3);
int erwithdraw=BalanceInquiry.withdrawMoney(); // risposta di withdraw
return erwithdraw;
}
public String[] bilancio(){
double checkb=BalanceInquiry.getBalance();
String[] rbilancio= new String[12];
rbilancio[0]= Double.toHexString(checkb);
for(int i1=1;i1<=rbilancio.length;i1++){
for(int i=0;i<= BalanceInquiry.movement.length-1; i++){
if(BalanceInquiry.movement[i]==null){
rbilancio[i1]="";
}
else{rbilancio[i1]=BalanceInquiry.movement[i];
}
}
}
return rbilancio;
}
}
`
ATMClient
`
package ws;
import java.util.Scanner;
import java.io.*;
import java.util.Properties;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.description.PolicyInclude;
import org.apache.neethi.Policy;
import org.apache.rampart.policy.model.CryptoConfig;
import org.apache.rampart.policy.model.RampartConfig;
import org.apache.axiom.om.OMElement;
public class ATMClient {
public static void main(String[] args)
{
Scanner read = new Scanner(System.in);
double amount=0;
int select = 0;
int choice = 0;
//To be able to load the client configuration from axis2.xml
//ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem("axis-repo",null);
ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem("axis-repo", "axis-repo\\conf\\axis2.xml");
ATMachineStub stub = new ATMachineStub(ctx,"http://localhost:8888/axis2/services/ATMachine");
ServiceClient sc = stub._getServiceClient();
sc.engageModule("rampart");
System.out.println("====================================================");
System.out.println("\tWelcome to this simple ATM machine");
System.out.println("====================================================");
System.out.println();
do
{try
{
do {
System.out.println("\tPlease select ATM Transactions");
System.out.println("\tPress [1] Deposit");
System.out.println("\tPress [2] Withdraw");
System.out.println("\tPress [3] Balance Inquiry");
System.out.println("\tPress [4] Exit");
System.out.print("\n\tWhat would you like to do? ");
select = read.nextInt();
if(select>4)
{
System.out.println("\n\tPlease select correct transaction.");
}
else
{
switch (select)
{
case 1:
amount=0;
System.out.print("\n\tEnter the amount of money to deposit: ");
amount= read.nextDouble();
double result= stub.deposita(amount);
System.out.println("\tYou deposited the amount of " + amount);
break;
case 2:
amount=0;
System.out.print("\n\tTo withdraw, make sure that you have sufficient balance in your account.");
System.out.println();
System.out.print("\tEnter amount of money to withdraw: ");
amount= read.nextDouble();
double erpreleva=stub.preleva(amount);
if(erpreleva==1)
{
System.out.println("\tYour current balance is zero.");
System.out.println("\tYou cannot withdraw!");
System.out.println("\tYou need to deposit money first.");
}
else if(erpreleva==2)
{
System.out.println("\tThe amount you withdraw is greater than to your balance");
System.out.println("\tPlease check the amount you entered.");
}
else
{
System.out.println("\n\tYou withdraw the amount of Php " + amount);
}
break;
case 3:
String[] bilanciores= new String[12];
bilanciores=stub.bilancio();
System.out.println("\tYour current balance is:" + bilanciores[0]);
System.out.println();
System.out.println("\tThe last 10 operation are:\n ");
for(int i=1;i<bilanciores.length;i++){
System.out.println("\t"+ bilanciores[i] +"\n");
}
break;
default:
System.out.print("\n\tTransaction exited.");
break;
}
}
}while(select>4);
do {
try
{
System.out.println("\n\tWould you like to try another transaction?");
System.out.println("\n\tPress [1] Yes \n\tPress [2] No");
System.out.print("\tEnter choice: ");
choice = read.nextInt();
if(choice>2)
{
System.out.print("\n\tPlease select correct choice.");
}
}
catch(Exception e)
{
System.out.println("\tError Input! Please enter a number only.");
read = new Scanner(System.in);
System.out.println("\tEnter yout choice:");
choice = read.nextInt();
}
} while(choice>2);
}
catch(Exception e)
{
System.out.println("\tError Input! Please enter a number only.");
read = new Scanner(System.in);
System.out.println("\tEnter yout choice:");
select = read.nextInt();
}
}while(choice<=1);
System.out.println("\n\tThank you for using this simple ATM Machine.");
}
}
`
The classes BalanceInquiry, Deposit, Withdraw have get and response methods and works.
All the declared libraries are added to the project.
But in ATMClient Eclipse says
ATMachineStub cannot be resolved to a type
I also tried to create an interface with the wizard using instead that ws and ws, ws and ws/xsd but cause error on the methods bilancio(), deposita(), and preleva() requiring to modify the parameters in the ATMchineStub file froma deposita(Deposita) to deposita(double), (the same for the other methods).
I post also the xml file of the wsdl :
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns="http://ws.apache.org/axis2" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://ws.apache.org/axis2">
<wsdl:documentation>ATMachine</wsdl:documentation>
<wsdl:types>
<xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://ws.apache.org/axis2">
<xs:element name="deposita">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="amount" type="xs:double"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="depositaResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:double"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="preleva">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="amount" type="xs:double"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="prelevaResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:double"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="bilancioResponse">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="return" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="bilancioRequest"/>
<wsdl:message name="bilancioResponse">
<wsdl:part name="parameters" element="ns:bilancioResponse"/>
</wsdl:message>
<wsdl:message name="prelevaRequest">
<wsdl:part name="parameters" element="ns:preleva"/>
</wsdl:message>
<wsdl:message name="prelevaResponse">
<wsdl:part name="parameters" element="ns:prelevaResponse"/>
</wsdl:message>
<wsdl:message name="depositaRequest">
<wsdl:part name="parameters" element="ns:deposita"/>
</wsdl:message>
<wsdl:message name="depositaResponse">
<wsdl:part name="parameters" element="ns:depositaResponse"/>
</wsdl:message>
<wsdl:portType name="ATMachinePortType">
<wsdl:operation name="bilancio">
<wsdl:input message="ns:bilancioRequest" wsaw:Action="urn:bilancio"/>
<wsdl:output message="ns:bilancioResponse" wsaw:Action="urn:bilancioResponse"/>
</wsdl:operation>
<wsdl:operation name="preleva">
<wsdl:input message="ns:prelevaRequest" wsaw:Action="urn:preleva"/>
<wsdl:output message="ns:prelevaResponse" wsaw:Action="urn:prelevaResponse"/>
</wsdl:operation>
<wsdl:operation name="deposita">
<wsdl:input message="ns:depositaRequest" wsaw:Action="urn:deposita"/>
<wsdl:output message="ns:depositaResponse" wsaw:Action="urn:depositaResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ATMachineSoap11Binding" type="ns:ATMachinePortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="bilancio">
<soap:operation soapAction="urn:bilancio" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="preleva">
<soap:operation soapAction="urn:preleva" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="deposita">
<soap:operation soapAction="urn:deposita" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="ATMachineSoap12Binding" type="ns:ATMachinePortType">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="bilancio">
<soap12:operation soapAction="urn:bilancio" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="preleva">
<soap12:operation soapAction="urn:preleva" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="deposita">
<soap12:operation soapAction="urn:deposita" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="ATMachineHttpBinding" type="ns:ATMachinePortType">
<http:binding verb="POST"/>
<wsdl:operation name="bilancio">
<http:operation location="ATMachine/bilancio"/>
<wsdl:input>
<mime:content type="text/xml" part="bilancio"/>
</wsdl:input>
<wsdl:output>
<mime:content type="text/xml" part="bilancio"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="preleva">
<http:operation location="ATMachine/preleva"/>
<wsdl:input>
<mime:content type="text/xml" part="preleva"/>
</wsdl:input>
<wsdl:output>
<mime:content type="text/xml" part="preleva"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="deposita">
<http:operation location="ATMachine/deposita"/>
<wsdl:input>
<mime:content type="text/xml" part="deposita"/>
</wsdl:input>
<wsdl:output>
<mime:content type="text/xml" part="deposita"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ATMachine">
<wsdl:port name="ATMachineHttpSoap11Endpoint" binding="ns:ATMachineSoap11Binding">
<soap:address location="http://localhost:8080/axis2/services/ATMachine.ATMachineHttpSoap11Endpoint/"/>
</wsdl:port>
<wsdl:port name="ATMachineHttpSoap12Endpoint" binding="ns:ATMachineSoap12Binding">
<soap12:address location="http://localhost:8080/axis2/services/ATMachine.ATMachineHttpSoap12Endpoint/"/>
</wsdl:port>
<wsdl:port name="ATMachineHttpEndpoint" binding="ns:ATMachineHttpBinding">
<http:address location="http://localhost:8080/axis2/services/ATMachine.ATMachineHttpEndpoint/"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Can somebody suggest me how to solve it ?
I solved it using WSS4J by terminal. Instead of the eclipse service it has solved.
I am trying to create a simple webservice which takes a String as input and returns string as output.
I am using Ecelipse Helios and Axis 2.15.
I am writing simple WSDL for the same.
I am generating the stubs using code generator.
New ->code generator -> java class from wsdl-> give WSDL and generates the java skeletons.
And in the skelton I am just print the value what is coming as parameter. and returning the same value.
I have written client code to invoke the method of the webservice. which takes a String.
but when I am trying to invoke the method I am getting following exception and it's not hitting the webservice.
Infact I am using XStream along with Client/WebService.
Code goes like this for the webservice skeleton:
public com.url.pkg.ShowInputResponse showInput(
com.url.pkg.ShowInput showInput) {
// TODO : fill this with the necessary business logic
String inputString = showInput.getInputString();
System.out.println("INput String is :\n" + inputString);
XStream xStream = new XStream();
System.out.println("After XStream Declaration...");
SOVO vo = null;
try {
vo = (SOVO) xStream.fromXML(inputString);
} catch (Throwable e) {
System.out.println(e);
e.printStackTrace();
}
System.out.println("After SOVO casting from XML");
System.out.println(vo.getName());
System.out.println(vo.getParams());
// TODO: business logic
ShowInputResponse response = new ShowInputResponse();
response.set_return(inputString);
return response;
}
My client code goes like this :
public static void main(String[] args) throws Exception {
BasicServiceStub stub = new BasicServiceStub();
ShowInput request = new ShowInput();
SOVO sovo = new SOVO();
sovo.setName("I am the post for SO");
Map params = new HashMap();
params.put("key1", "val1");
params.put("key2", "val2");
sovo.setParams(params);
XStream xStream = new XStream();
String soVoString = xStream.toXML(sovo);
// System.out.println(soVoString);
request.setInputString(soVoString);
ShowInputResponse response = stub.showInput(request);
System.out.println("....................................");
System.out.println("response = " + response.get_return());
}
SOVO is a simple POJO which is present at both client and webservice side.
public class SOVO {
private String name;
private Map params;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map getParams() {
return params;
}
public void setParams(Map params) {
this.params = params;
}
}
And last but most important WSDL is here:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:ns="http://pkg.url.com" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" targetNamespace="http://pkg.url.com">
<wsdl:types>
<xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://pkg.url.com">
<xs:element name="showInput">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="inputString" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="showInputResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="return" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="showInputRequest">
<wsdl:part name="parameters" element="ns:showInput"/>
</wsdl:message>
<wsdl:message name="showInputResponse">
<wsdl:part name="parameters" element="ns:showInputResponse"/>
</wsdl:message>
<wsdl:portType name="BasicServicePortType">
<wsdl:operation name="showInput">
<wsdl:input message="ns:showInputRequest" wsaw:Action="urn:showInput"/>
<wsdl:output message="ns:showInputResponse" wsaw:Action="urn:showInputResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BasicServiceSoap11Binding" type="ns:BasicServicePortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="showInput">
<soap:operation soapAction="urn:showInput" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="BasicServiceSoap12Binding" type="ns:BasicServicePortType">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="showInput">
<soap12:operation soapAction="urn:showInput" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="BasicServiceHttpBinding" type="ns:BasicServicePortType">
<http:binding verb="POST"/>
<wsdl:operation name="showInput">
<http:operation location="BasicService/showInput"/>
<wsdl:input>
<mime:content type="text/xml" part="showInput"/>
</wsdl:input>
<wsdl:output>
<mime:content type="text/xml" part="showInput"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="BasicService">
<wsdl:port name="BasicServiceHttpSoap11Endpoint" binding="ns:BasicServiceSoap11Binding">
<soap:address location="http://localhost:8080/axis2/services/BasicService"/>
</wsdl:port>
<wsdl:port name="BasicServiceHttpSoap12Endpoint" binding="ns:BasicServiceSoap12Binding">
<soap12:address location="http://localhost:8080/axis2/services/BasicService"/>
</wsdl:port>
<wsdl:port name="BasicServiceHttpEndpoint" binding="ns:BasicServiceHttpBinding">
<http:address location="http://localhost:8080/axis2/services/BasicService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
And the Stack trace for the exception I must modify :
I am not very sure if its hitting the webservice layer.
Caused by: org.apache.axis2.AxisFault: string
at org.apache.axis2.util.Utils.getInboundFaultFromMessageContext(Utils.java:446)
at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:371)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:417)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
at com.url.pkg.BasicServiceStub.showInput(BasicServiceStub.java:184)
at com.url.pkg.Client.main(Client.java:30)
It looks like more its some problem with XStream desirialization. Even though SOVO is in the classpath why its happening? Am I missing something?
When I try sending XXXXX as string it tells:
only whitespace content allowed before start tag and not X (position: START_DOCUMENT seen X... #1:1)
When i try sending "some value" it says:
only whitespace content allowed before start tag and not s (position: START_DOCUMENT seen s... #1:1)
I am not sure what's wrong.
I would suggest the following:
Test the service with another client
Use soapUI to generate a valid test request for your showInput method. If you don't get any errors using this tool, you know your service is working fine. If you do get an error, then you know to start digging around in your service code.
Enable client side logging for SOAP messages
Add these JVM options when running your client:
-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
-Dorg.apache.commons.logging.simplelog.showdatetime=true
-Dorg.apache.commons.logging.simplelog.log.httpclient.wire=debug
-Dorg.apache.commons.logging.simplelog.log.org.apache.commons.httpclient=debug
This will let you to see the SOAP messages that get transmitted. Pay close attention to content appearing before your start tags like the error message says.