Getting rid of <arg0> - java

I have Java WebService code in my eclipse. I have used #WebService #Webmethod, #XmlElements, #XmlType, #XmlAccessorType
Now I am generating wsdl using java2ws command from cxf framework. Here is the command
F:\....\code\java2wsdl>java2ws -o CustomerVxRR.wsdl -d <myOutputDir> -wsdl -cp <myClassesFolder> <ServiceImpl class>
my wsdl file contqins agr0 as name which I do not want because when I am importing it to SoapUI. It is adding tag around the field.
Here is wsdl part with arg0
<xs:schema ..... >
<xs:complexType name="myServiceMethodName">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="tns:ServiceInputClassName"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ServiceInputClassName">
<xs:sequence>
<xs:element minOccurs="0" name="EmpID" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xz:schema>
Here is the request object which is generated in SOAPUI
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cus="http://customeroffer.manage.ws.hello.my.com/">
<soapenv:Header/>
<soapenv:Body>
<cus:myServiceMethodName>
<!--Optional:-->
<arg0>
<EmpID >123456</EmpID>
</arg0>
</cus:myServiceMethodName>
</soapenv:Body>
</soapenv:Envelope>
If I remove tag I get this response:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Unmarshalling Error: unexpected element (uri:"", local:"EmpID"). Expected elements are <{}empid></faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
I do not want to keep arg0 in the request XML

I just fixed it after some research of my own code. The only thing which is required to change <arg0> is that we need to used #WebParam annotation to declare custome name instead of "arg0".
For example:
my service name is getEmpDetail and EmpID is the input parameter to the service then here is the declaration required in the service impl class:
public Emp getEmpDetail(#WebParam(name="EmpDetail") String EmpId)
after generatingfrom WSDL the request XML will look like below
<ns:getEmpDetail>
<EmpDetail>
<EmdID>?</EmpID>
</EmpDetail>
<ns:getEmpDetail>

Related

Can XSD Assertions be Used in Specifying a WSDL File

I have a WSDL file which also contains all types used in it (via <wsdl:types>
tag). When defining the types, I have something like this:
<wsdl:definitions name="service"
targetNamespace="http://www.xxx.yyy/reg/definitions" xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tax="http://www.xxx.yyy/reg/definitions" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
.............
<xs:complexType name="CompanyName">
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="ShortName" type="xs:string" minOccurs="0" />
</xs:sequence>
<xs:attribute name="Language" type="tax:LanguageType" use="required"/>
<xs:assert test="ShortName or #Language != 'Language1'"/>
</xs:complexType>
.............
</wsdl:definitions>
Unfortunately, it doesn't work giving the following exception when I try to start the application on Tomcat:
javax.xml.ws.WebServiceException: org.xml.sax.SAXParseException; s4s-elt-invalid-content.1: The content of 'CompanyName' is invalid. Element 'assert' is invalid, misplaced, or occurs too often.
The WSDL version is 1.2 and I don't know which version of xsd it uses when types are described in it, so I don't know if it is a xsd version (1.0 vs. 1.1) issue or something else.
Can someone help me in finding the real issue?
EDIT: I have added the header of the wsdl.
I have added the version attribute (version="1.1") to <xs:schema>
definition but that didn't help either:
<xs:schema targetNamespace="http://www.xxx.yyy/reg/definitions" elementFormDefault="qualified" version="1.1">
Looks like assertions were introduced with XML Schema v1.1 when the XMLSchema definition moved over to w3.org.
Sample header:
<wsdl:description
targetNamespace="http://www.w3.org/2002/ws/sawsdl/spec/wsdl/order#"
xmlns="http://www.w3.org/2002/ws/sawsdl/spec/wsdl/order#"
xmlns:wsdl="http://www.w3.org/ns/wsdl"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sawsdl="http://www.w3.org/ns/sawsdl">

SOAP without namespace in response (Spring Boot)

I'm following this example to build a web service with Soap. Is there a way to remove the targetNamespace for the Soap response? With SoapUI I get this response:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns2:getAllResponse xmlns:ns2="http://spring.io/guides/gs-producing-web-service">
<ns2:timestamp>12/18/2015 10:51:02 AM</ns2:timestamp>
<ns2:MyItem>
<ns2:class>myClass</ns2:class>
<ns2:name>MyItemName</ns2:name>
</ns2:MyItem>
</ns2:getAllResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
And would like to get it without the target namespace, e.g. like:
...
<MyItem>
<MyItem>
<class>myClass</class>
<name>MyItemName</name>
</MyItem>
I'm sending an empty request to get a list of MyItems. My xsd looks like this:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
xmlns:tns="http://spring.io/guides/gs-producing-web-service"
targetNamespace="http://spring.io/guides/gs-producing-web-service">
<xs:element name="getAllRequest">
<xs:complexType>
<xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="getAllResponse">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="1" name="timestamp" type="xs:string"/>
<xs:element maxOccurs="unbounded" name="MyItem" type="tns:MyItem"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="MyItem">
<xs:sequence>
<xs:element name="class" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
The MyItem class will be generated automatically and gets annotated with this:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "MyItem", propOrder = {
"class",
"name",
})
public class MyItem { //....
Is there any way to get a response without the target namespace? I know its purpose and that it's actually quite useful. But it happened that it can't be processed any further by another tool with this target namespace and looks like this:
<MyItem xmlns="http://spring.io/guides/gs-producing-web-service"> ...
Thanks in advance!
Is there any way to get a response without the target namespace?
I hope not. A SOAP web service should have a well-defined, published interface and every response that it sends should conform to that interface. Usually, the interface is described by a WSDL document.
And would like to get it without the target namespace
<MyItem>
<class>myClass</class>
<name>MyItemName</name>
</MyItem>
Being pedantic, but the absence of a namespace prefix does not mean that there is no namespace. There might be a default namespace in force. So you could achieve XML that looks exactly like the above and the MyItem, class and name tags might still have a non-empty namespace.
I know its purpose and that it's actually quite useful.
The purpose of a namespace in an XML document ( whether a web service response, or any other XML ) is to avoid polluting the global namespace. Do you really want 'name' and 'class' to have exactly one meaning in your applications? Or would it be better if each schema could define its own version of those?
But it happened that it can't be processed any further by another tool with this target namespace and looks like this:
<MyItem xmlns="http://spring.io/guides/gs-producing-web-service"> ...
That looks like valid XML, so what's the problem? Is that output produced by the 'other tool'? Or is it something that the 'other tool' cannot handle?
Here is the simple and easiest solution for that problem. Create Package-Info.Java file in your model package and add the below script to that.
#javax.xml.bind.annotation.XmlSchema(namespace = "http://spring.io/guides/gs-producing-web-service", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, xmlns = { #javax.xml.bind.annotation.XmlNs(namespaceURI = "http://spring.io/guides/gs-producing-web-service", prefix = "") })
package my.com.scicom.stars.model;
And add elementFormDefault as "qualified" in your xsd or wsdl file.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://spring.io/guides/gs-producing-web-service"
targetNamespace="http://spring.io/guides/gs-producing-web-service"
elementFormDefault="qualified">

Difference in SOAP envelope from Java Client calling .NET SOAP Web-Service

I have a C# client which produces the .NET SOAP envelope below, which works against a C# ASMX SOAP web service. However we have a Java Client calling into our service which is producing the Java envelope specified below. The main difference between the envelopes is that some values are serialised as attributes in the java client envelope rather than as XML element nodes in the C# client envelope. The java client is using AXIS WSDL2Java to generate their client. Would anyone know what I would need to tell the Java developers so they may generate the correct soap envelope for the example shown.
Kind Regards
Working SOAP Envelope Captured from C# Client
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<getDocumentPageRequest xmlns="urn:mycorp-com:MyApp.Schema.DocumentEnquiry.Messages.v01">
<header xmlns="urn:mycorp-com:MyApp.Schema.Common.Types.v01">
<extensions />
<corelationIdentifier>41edebfb-fffd-44f8-94e9-be043e1dad48</corelationIdentifier>
</header>
<securityToken xmlns="urn:mycorp-com:MyApp.Schema.Common.Types.v01">
<Value>218FD85D</Value>
</securityToken>
<documentIdentifier>15236HDFG000005</documentIdentifier>
<pageNumber>1</pageNumber>
</getDocumentPageRequest>
</soap:Body>
</soap:Envelope>
Java SOAP Envelope - Not working with web-service
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<getDocumentPageRequest
documentIdentifier="15236HDFG000005"
pageNumber="1"
xmlns="urn:mycorp-com:MyApp.Schema.DocumentEnquiry.Messages.v01">
<ns1:header corelationIdentifier="" xmlns:ns1="urn:mycorp-com:MyApp.Schema.Common.Types.v01">
<ns1:extensions/>
</ns1:header>
<ns2:securityToken xmlns:ns2="urn:mycorp-com:MyApp.Schema.Common.Types.v01">218FD85D</ns2:securityToken>
</getDocumentPageRequest>
</soapenv:Body>
</soapenv:Envelope>
Edited:: Added in WSDL as requested.
Sample WSDL and XSD Extract
Below is a sample of the WSDL generated and an extract of the XSD that it imports for the message type. I can see in this that the XML has attributes, which is what the AXIS WSDL2Java is generating, but the C# proxy and web-service is expecting XML nodes. I think this means the way the C# services is implemented is different somehow or other than the schema it is defined against. This is confusing...
<!-- WSDL Extract -->
<message name="getDocumentPageIn">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" />
<part name="messagePart" element="import0:getDocumentPageRequest" />
</message>
<message name="getDocumentPageOut">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" />
<part name="messagePart" element="import0:getDocumentPageResponse" />
</message>
<!-- import0 XSD extract -->
<xs:element name="getDocumentPageRequest">
<xs:complexType>
<xs:complexContent>
<xs:extension base="MyApp:request">
<xs:attribute name="documentIdentifier" type="xs:string" use="required"/>
<xs:attribute name="pageNumber" type="xs:short" use="required"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
Thanks for taking the time to review this, but I found the actual problem.
It turns out the C# code that was being generated for the types for the web-service and proxy was missing an [XmlAttribute] attribute in the code for each attribute defined in the XML. This caused the XmlSerializer to flatten the properties on the class to elements rather than keeping them as attributes.

Spring-ws: How to create Wsdl from an xsd with no "Request" element

Trying to implement a SOAP Webservice for a client and I need a wsdl file to test the service by soapUI. But as you can see below, this xsd has no Request and Response methods, all requests and responses are defined as a a "type" in a base ServiceProvider element. So when I try to auto generate my wsdl file by spring-ws it does not generate a proper wsdl, because Spring-ws requires all requests and responses element names should end with "Request" "Response".
What can I do?
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified" targetNamespace="http://myurl" xmlns="http://myurl">
<xs:element name="ServiceProviderT" nillable="false">
<xs:annotation>
<xs:documentation>ServiceProviderT is the message spec for data sent between TechX and service providers or
vendors</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="Version" type="xs:string" nillable="false"/>
<xs:choice>
<xs:element name="Request" type="RequestType" nillable="false"/>
<xs:element name="Response" type="ResponseType" nillable="false"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
....
And this how I generate wsdl file
<sws:dynamic-wsdl id="myservice"
portTypeName="MyService"
locationUri="/myService"
targetNamespace="http://myurl">
<sws:xsd location="/schemas/my.xsd"/>
</sws:dynamic-wsdl>
There is no such requirement those are just the defaults. This is explained here in the Spring-WS reference guide. It also explains which properties to set to override those defaults.
The default request suffix is Request; the default response suffix is Response, though these can be changed by setting the requestSuffix and responseSuffix attributes on <dynamic-wsdl />, respectively.
<sws:dynamic-wsdl id="myservice"
portTypeName="MyService"
locationUri="/myService"
requestSuffix="YourRequestSuffixHere"
responseSuffix="YourResponseSuffixHere"
targetNamespace="http://myurl">
<sws:xsd location="/schemas/my.xsd"/>
</sws:dynamic-wsdl>

JAXB support for SOAP style arrayType

I'm trying to make a new version of a server that previously used Axis 1.4 to respond to SOAP RPC requests using Spring-WS. I have a few of the RPC calls working, but I'm stuck trying to satisfy a request that expects a SOAP body that looks like this:
<rpcCallResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<responseElement soapenc:arrayType="xsd:string[5]"
xsi:type="soapenc:Array"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<responseElement xsi:type="xsd:string">val1</responseElement>
<responseElement xsi:type="xsd:string">val2</responseElement>
<responseElement xsi:type="xsd:string">val3</responseElement>
<responseElement xsi:type="xsd:string" xsi:nil="true"/>
<responseElement xsi:type="xsd:string" xsi:nil="true"/>
</responseElement>
</rpcCallResponse>
I'm struggling to write the XML schema for this, and to get the JAXB marshaller to shove the xsi:type annotations into the response.
What's the correct XML schema to use/set of annotations to use to get this to marhsal (Java -> XML) correctly?
One solution I found that works for getting the arrayType added is to, instead of deriving from the http://schemas.xmlsoap.org/soap/encoding/ schema, use a custom schema of the form:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://schemas.xmlsoap.org/soap/encoding/"
elementFormDefault="qualified">
<xs:attribute name="arrayType" type="xs:QName" />
</xs:schema>
...which replaces the type of the arrayType attribute with an xs:QName (vs. the actual type, which is just an xs:string). The advantage of using a QName seems to be that JAXB will take the QName's namespace and shove it onto the element when serialization happens -- which was the main blocker on getting a working schema above.
The schema for above now looks something like:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:encoding="http://schemas.xmlsoap.org/soap/encoding/"
targetNamespace="http://foo.com/bar"
elementFormDefault="qualified">
<xs:import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="soapenc.xsd" />
<xs:element name="rpcCallResponse">
<xs:complexType>
<xs:element name="responseElement">
<xs:complexType>
<xs:sequence>
<xs:element name="responseElement" maxOccurs="5" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:attribute ref="soapenc:arrayType" />
</xs:complexType>
</xs:element>
</xs:schema>

Categories

Resources