Java, RPC/encoded Axis 1.4 client cannot send null argument - java

I'm dealing with a problem of connecting to web-service with RPC/encoded WSDL file to my Java/Spring service. I cannot change this WSDL.
I figured out that I have to use Apache Axis 1.4 to create client (according to this problem: https://dzone.com/articles/wsdltojava-error-rpcencoded ).
Then I had problem with login/password/api_key parameters with such message:
<message name="login_message">
<part name="login" type="xsd:string"/>
<part name="password" type="xsd:string"/>
<part name="api_key" type="xsd:int"/>
</message>
Error Element 'api_key': '' is not a valid value of the atomic type 'xs:int'
I solved this problem by adding:
webapi_locator.getEngine().setOption("sendMultiRefs", Boolean.FALSE);
Now I can login and fetch some data from this service but I cannot pushed messages with null arguments like:
<message name="add_offer_input">
<part name="session" type="xsd:string"/>
<part name="category_id" type="xsd:int"/>
<part name="offer" type="tns:offer"/>
</message>
where offer is defined as:
<xsd:complexType name="offer">
<xsd:all>
<xsd:element name="price" type="xsd:float" minOccurs="0" maxOccurs="1"/>
<xsd:element name="price_m2" type="xsd:int" minOccurs="0" maxOccurs="1"/>
[...]
</xsd:all>
</xsd:complexType>
Now I am getting exception like this one:
org.apache.axis.AxisFault: Wrong parameters input xml
Element 'price': '' is not a valid value of the atomic type 'xs:int'. line: 1 column: 0'
at org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:222) ~[axis-1.4.jar:na]
I have already tried setting
elemField.setNillable(false);
to
elemField.setNillable(true);
in Offer.java.
I am creating Offer message in following way:
Offer offer = new Offer(null,null);
I will be very gratefull for found solution for this error. I don't need to stick with axis 1.4 - any other solution which letting me to connect to this service via SOAP with be usefull for me. Thank you very much for help!

You are probably missing the nillable="true" attribute in your WSDL.
The WSDL should look something similar to below:
..
<xsd:element name="price" type="xsd:float" nillable="true" minOccurs="0" maxOccurs="1"/>
..
nillable="true" allows null arguments to be passed. Java2WSDL using Axis 1.4 doesn't do it, as the axis code method writeWrappedParameter() in org/apache/axis/wsdl/fromJava/Types.java doesn't have it.
More info on bug: https://issues.apache.org/jira/browse/AXIS-243

Related

Using SAML Assertion in XSD

I have a webservice operation where i'll be getting SAML Assertion as part of the request Body.
I have following XSD:
<xsd:element name="CreateRequest">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="info" type="SomeRequestObj"/>
<xsd:element ref="saml:Assertion" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
The saml:Assertion refers to:
<xsd:import namespace="urn:oasis:names:tc:SAML:2.0:assertion"schemaLocation="../samlv2_0/saml-schema-assertion-2.0.xsd"/>
This saml schema is copied from SAML 2.0.
This generates classes with name *Type.java.
And i am having a hard time creating a unit test for this (which is a separate application with UI).
My Request requires a SAML AssertionType element in the request Body.
So, i cannot use OpneSaml for generating that as it gives me a SAML Assertion object and not AssertionType.
I tried generating the AssertionType object manually but i am having a hard time doing so.
Is there a way to use OpenSaml for generating this?
As i see the xml is going to be the same that i would get in case i just use OpenSaml to generate Assertion object.
Is there a way to simplify this?
EDIT: Added XSD snippet of Assertion
<element name="Assertion" type="saml:AssertionType"/>
<complexType name="AssertionType">
<sequence>
<element ref="saml:Issuer"/>
<element ref="ds:Signature" minOccurs="0"/>
<element ref="saml:Subject" minOccurs="0"/>
<element ref="saml:Conditions" minOccurs="0"/>
<element ref="saml:Advice" minOccurs="0"/>
<choice minOccurs="0" maxOccurs="unbounded">
<element ref="saml:Statement"/>
<element ref="saml:AuthnStatement"/>
<element ref="saml:AuthzDecisionStatement"/>
<element ref="saml:AttributeStatement"/>
</choice>
</sequence>
<attribute name="Version" type="string" use="required"/>
<attribute name="ID" type="ID" use="required"/>
<attribute name="IssueInstant" type="dateTime" use="required"/>
</complexType>
This generates AssertionType Object.
SAML Assertions are of complex type "AssertionType", but the element name is "Assertion". The <Assertion> element generated by OpenSaml should be just fine.
The element is defined in section 2.3.3 in the SAML core spec.
Try to use an external binding file when generating the classes from the XSD with JAXB. See this topic (I guess the second answer of it is what you're looking for): JAXB: How to change XJC-generated classes names when attr type is specified in XSD?

MULE ESB Simple SOAP service create mandatory fields

I want to expose a Simple SOAP web service in Mule 3.4 Community.
Some fields of the service need to be mandatory/required. How can that be done?
Here is the web service method:
public String methodname(String field1, String field2, String field3);
Here is the resulting wsdl:
<xsd:element minOccurs="0" name="field1" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="field2" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="field3" nillable="true" type="xsd:string"/>
How can I make these fields minOccurs="1" and nillable="false"
Please note #XmlElement(required=true) doesn't work with my Java version 1.6
minOccurs="1" makes the element mandatory and minOccurs="0" makes it optional
So make the following change to make it mandatory:-
<xsd:element minOccurs="1" name="field1" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="1" name="field2" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="1" name="field3" nillable="true" type="xsd:string"/>
For your reference :- https://social.msdn.microsoft.com/Forums/en-US/f59a3ee2-5997-4ee7-8c09-8d371c923267/creating-required-elements-in-xsd?forum=xmlandnetfx
and
How to tell if XML element is marked as required in the XSD file
and nillable is specifies whether an explicit null value can be assigned to the element
reference:-http://www.w3schools.com/schema/el_element.asp
So you need to make change in your WSDL so that the Java class generated from to implements those properties of attributes
I'm afraid you can't do this with a simple service (as it's simple by definition, it would probably work latter versions of java as you point).
You should switch to a fullfeatured jaxws service without autogenerated wdsl.

Character limit in webservice at wsdl level

I hace deployed a java WebService in an application using WebSphere AST. I need to limit the length of some fields (Strings) and I wondered if I can do that at the wsdl instead of coding some validations at java level.
I mean, if rigth now I have the elements defined like this:
<element name="code" nillable="true" type="xsd:string"/>
Can I set some property that restrict the max length of "code"?
Thank you.
<element name="code" nillable="true" type="xsd:string"/>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:minLength value="2"/>
<xsd:maxLength value="10"/>
</xsd:restriction>
</xsd:simpleType>

when to use SOAPBinding.ParameterStyle.BARE and SOAPBinding.ParameterStyle.WRAPPED

I am in confusion as when to use SOAPBinding.ParameterStyle.BARE and SOAPBinding.ParameterStyle.WRAPPED .and which binding style is more preferred.what are the differences between them.
ParameterStyle.Bare and ParameterStyle.Wrapped affects your wsdl definitions of request and response messages only.
Lets take an example, we have a webservice with a method "test" which has 2 input "string1" and "string2" and it is returning a string as "rstring".
ParameterStyle.BARE
Your parameter's name will be visible as part name in your wsdl.
Request message:
<message name="test">
<part name="string1" element="tns:string1"/>
<part name="string2" element="tns:string2"/>
</message>
Response message:
<message name="testResponse">
<part name="rstring" element="tns:rstring"/>
</message>
In your xsd test and testResponse will be defined like below, and your wsdl element directly referring elements under test and test response from xsd.
<xs:complexType name="test">
<xs:sequence>
<xs:element name="string1" type="xs:string" minOccurs="0"/>
<xs:element name="string2" type="xs:string" minOccurs="0"/>
</xs:sequence>
<xs:complexType name="testResponse">
<xs:sequence>
<xs:element name="rstring" type="xs:string" minOccurs="0"/>
</xs:sequence>
ParameterStyle.WRAPPED
In this style your request and response message will be wrapped in single input as "parameter" and output as "result". and they will refer that particular element in xsd for all elements within.
Request message:
<message name="test">
<part name="parameters" element="tns:test"/>
</message>
Response message:
<message name="testResponse">
<part name="result" element="tns:testResponse"/>
</message>
In your xsd test and testResponse will be defined as same as above,
<xs:complexType name="test">
<xs:sequence>
<xs:element name="string1" type="xs:string" minOccurs="0"/>
<xs:element name="string2" type="xs:string" minOccurs="0"/>
</xs:sequence>
<xs:complexType name="testResponse">
<xs:sequence>
<xs:element name="rstring" type="xs:string" minOccurs="0"/>
</xs:sequence>
In above example , you can spot the difference. This is the only difference they implicate in wsdl.
Note: Above example is explained for Document type soap binding, in RPC, no xsd is involved so RPC.Bare is applicable only.
The document/literal wrapped style is the best approach and is also
the default. Wrapped document style with literal encoding has the
following advantages:
There is no type encoding info.
Everything that appears in the soap:body is defined by the Schema, so you can easily validate the message.
You have the method name in the soap message.
Document/literal is WS-I compliant, but without the WS-I restriction that the SOAP.body should have only one Child. The wrapped
pattern meets the WS-I restriction that the SOAP messages SOAP.body
has only one Child.
But in few cases you might have to use another style. If you have
overloaded operations, you cannot use the document/literal wrapped
style. WSDL allows overloaded operations, but when you add the wrapped
pattern to WSDL, you require an element to have the same name as the
operation, and you cannot have two elements with the same name in XML.
So you must use the document/literal, non-wrapped style or one of the
RPC styles.
Source: Which style of WSDL should I use?

wsimport bind xsd:int to Integer instead of int

Ok. The title really says it all.
I have a extremely large SOAP server I'm calling in a java application. To make my life easier I've been using wsimport to generate the source and jar for the service. I just ran into a problem. All the xsd:int types in the wsdl are being parsed as int types in the java code when I need them as Integer types. Reason for this is some of the int's i need to set as null, but since int types can't be null I can't do that.
I am currently going through and hand changing the fields, but I want to know if there is a easier way to do it through a agrument to the wsimport command
Here is my current wsimport command. Thanks
wsimport.exe -d E:\ServiceWSBuild -p com.example.wsdl -s E:\Service\src -verbose http://wsdl.example.com/?wsdl
Here is also a example of one of the custom types that does this:
<xsd:complexType name="SubPackageSell">
<xsd:complexContent>
<xsd:extension base="tns:APIObject">
<xsd:sequence>
<xsd:element name="sp" type="tns:SubPackage"/>
<xsd:element name="value" type="xsd:int"/>
<xsd:element name="days" type="xsd:int"/>
<xsd:element name="date" type="xsd:string"/>
<xsd:element name="combine" type="xsd:boolean"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
For elements, specify minOccurs="0" and wsimport should generate a java.lang.Integer instead of a primitive int. The default values for minOccurs and maxOccurs is 1, which is why you are getting primitive ints. For example:
<xsd:element name="value" type="xsd:int" minOccurs="0"/>

Categories