WebFault and Web Service in different namespaces - java

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.

Related

How to set value SoapRequestCreator

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.

How can I have two different endpoint with different namespace and same JAXB class?

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

How to pass parameters in soap webservice using java?

i have created soap webservice,in this web service i have add(int a, int b) which takes parameter integer type.
Now my question is how to consume this method by passing these parameter using java? how to make soap client using java ?
WSDL
<wsdl:definitions xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://service.ss.com" xmlns:intf="http://service.ss.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://service.ss.com">
<!--
WSDL created by Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)
-->
<wsdl:types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://service.ss.com">
<element name="add">
<complexType>
<sequence>
<element name="a" type="xsd:int"/>
<element name="b" type="xsd:int"/>
</sequence>
</complexType>
</element>
<element name="addResponse">
<complexType>
<sequence>
<element name="addReturn" type="xsd:int"/>
</sequence>
</complexType>
</element>
<element name="insert">
<complexType/>
</element>
<element name="insertResponse">
<complexType>
<sequence>
<element name="insertReturn" type="xsd:string"/>
</sequence>
</complexType>
</element>
<element name="getDate">
<complexType/>
</element>
<element name="getDateResponse">
<complexType>
<sequence>
<element name="getDateReturn" type="xsd:dateTime"/>
</sequence>
</complexType>
</element>
<element name="findAll">
<complexType/>
</element>
<element name="findAllResponse">
<complexType>
<sequence>
<element name="findAllReturn" type="xsd:string"/>
</sequence>
</complexType>
</element>
</schema>
</wsdl:types>
<wsdl:message name="insertRequest">
<wsdl:part element="impl:insert" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="addResponse">
<wsdl:part element="impl:addResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="findAllRequest">
<wsdl:part element="impl:findAll" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="addRequest">
<wsdl:part element="impl:add" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="getDateResponse">
<wsdl:part element="impl:getDateResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="insertResponse">
<wsdl:part element="impl:insertResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="getDateRequest">
<wsdl:part element="impl:getDate" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="findAllResponse">
<wsdl:part element="impl:findAllResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:portType name="TestService">
<wsdl:operation name="add">
<wsdl:input message="impl:addRequest" name="addRequest"></wsdl:input>
<wsdl:output message="impl:addResponse" name="addResponse"></wsdl:output>
</wsdl:operation>
<wsdl:operation name="insert">
<wsdl:input message="impl:insertRequest" name="insertRequest"></wsdl:input>
<wsdl:output message="impl:insertResponse" name="insertResponse"></wsdl:output>
</wsdl:operation>
<wsdl:operation name="getDate">
<wsdl:input message="impl:getDateRequest" name="getDateRequest"></wsdl:input>
<wsdl:output message="impl:getDateResponse" name="getDateResponse"></wsdl:output>
</wsdl:operation>
<wsdl:operation name="findAll">
<wsdl:input message="impl:findAllRequest" name="findAllRequest"></wsdl:input>
<wsdl:output message="impl:findAllResponse" name="findAllResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TestServiceSoapBinding" type="impl:TestService">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="add">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="addRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="addResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="insert">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="insertRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="insertResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getDate">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getDateRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getDateResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="findAll">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="findAllRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="findAllResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="TestServiceService">
<wsdl:port binding="impl:TestServiceSoapBinding" name="TestService">
<wsdlsoap:address location="http://localhost:8080/SoapService/services/TestService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Code
This code is working good, but i don't know how to pass the parameters.
String requestContent= "";
WsdlProject project = new WsdlProject();
WsdlInterface[] wsdls = WsdlImporter.importWsdl(project, "http://host.ubnsoft.com:8080/SoapService/services/TestService?wsdl");
WsdlInterface wsdl = wsdls[0];
List<Operation> operations = wsdl.getOperationList();
for (Operation operation : operations) {
WsdlOperation wsdlOperation = (WsdlOperation) operation;
// create a new empty request for that operation
WsdlRequest request = wsdlOperation.addNewRequest("My request");
request.setTimeout("2000");
requestContent = wsdlOperation.createRequest(true);
request.setRequestContent(requestContent);
System.out.println("REQUEST: " + requestContent);
// submit the request
try {
WsdlSubmit submit = (WsdlSubmit) request.submit(new WsdlSubmitContext(request), false);
Status status = submit.getStatus(); //FINISHED OR ERROR
System.out.println("STATUS: " + status);
Response response = submit.getResponse();
System.out.println("RESPONSE: " + response.getContentAsString());
} catch (SubmitException e) {
e.printStackTrace();
}
}
How to send request with parameter and getting the response in soap using java?

Axis WSDL2Java generation issue

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.

Problem with deserialization of String sent over wire with XStream

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.

Categories