My provider must have an array of object as input parameter, according to the WSDL:
<element name="classifica" type="Q4:Titolario" maxOccurs="unbounded" minOccurs="0"/>
This is the generated method:
public void protoModificaProtocollo(...,...,...,Titolario[] classifica,....) {
How to get the input values of this array (always returns null).
EDIT
This is the xsd schema of the method to provide:
<import schemaLocation="TipoVerso.xsd" namespace="http://regione.toscana.it/rfc205/interpro.TipoVerso"/>
<import schemaLocation="Anagrafica.xsd" namespace="http://regione.toscana.it/rfc205/interpro.Anagrafica"/>
<import schemaLocation="Titolario.xsd" namespace="http://regione.toscana.it/rfc205/interpro.Titolario"/>
<element name="protoModificaProtocolloElement" type="tns:protoModificaProtocollo"/>
<complexType name="protoModificaProtocollo">
<sequence>
<element name="numero" type="int" maxOccurs="1" minOccurs="1"/>
<element name="anno" type="int" maxOccurs="1" minOccurs="1"/>
<element name="verso" type="Q1:TipoVerso" maxOccurs="1" minOccurs="1"/>
<element name="oggetto" type="string" maxOccurs="1" minOccurs="0"/>
<element name="classifica" type="Q4:Titolario" maxOccurs="unbounded" minOccurs="0"/>
<element name="ufficio" type="Q2:Anagrafica" maxOccurs="unbounded" minOccurs="0"/>
</sequence>
</complexType>
and this is the xsd schema of Titolario
<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="http://regione.toscana.it/rfc205/interpro.Titolario"
elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://regione.toscana.it/rfc205/interpro.Titolario">
<complexType name="Titolario">
<sequence>
<element name="codice" type="string" maxOccurs="1" minOccurs="1"></element>
<element name="descrizione" type="string" maxOccurs="1" minOccurs="0">
</element>
</sequence>
</complexType>
</schema>
Here the SOAP message sent:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:int="http://regione.toscana.it/rfc205/interpro"
xmlns:int1="http://regione.toscana.it/rfc205/interpro.protoModificaProtocollo"
xmlns:int2="http://regione.toscana.it/rfc205/interpro.Titolario"
xmlns:int3="http://regione.toscana.it/rfc205/interpro.Anagrafica">
<soapenv:Header/>
<soapenv:Body>
<int:protoModificaProtocollo>
<int1:numero>140</int1:numero>
<int1:anno>2014</int1:anno>
<int1:verso>P</int1:verso>
<!--Optional:-->
<int1:oggetto>test</int1:oggetto>
<!--Zero or more repetitions:-->
<int1:classifica>
<int2:codice>34</int2:codice>
<!--Optional:-->
<int2:descrizione>test description</int2:descrizione>
</int1:classifica>
</int:protoModificaProtocollo>
</soapenv:Body>
</soapenv:Envelope>
In the provider, this is the method:
public void protoModificaProtocollo(int numero, int anno, TipoVerso verso,
String oggetto, Titolario[] classificazione, Anagrafica[] ufficio,
ResponseProtocolloHolder protocollo_resp, ResponseErrorHolder response_msg_err) {
... some stuff here ...
System.out.println("getCodice():" + classificazione[0].getCodice()); <-- THIS LINE ALWAYS RETURNS NULL
Notice that, in input parameters, if I change
Titolario[] classificazione
with
Titolario classificazione
my debug line prints:
34
UPDATE 2
TIA Simon, here pastebin you can find the full WSDL. And here Titolario.java the class for Titolario. I've noticed that when consumer call provider, Titolario constructor i call N times, depending of number of Titolario occurrences in SOAP request. As you can see, the constructor is an empty constructor.
In this moment, my protocol is RPC/encoded, just becouse i've must understand the problem reported here Literal vs Encoded (if you please can take a look also at this...:-))
I've found some references about the problem, for example this article, maybe related to mine.
Anyway, i would like to know if there is a Java workaround to manage this. Thanks again!
Found the problem!
The fact was that i've used the same given WSDL both to generate the provider and to create the SoapUI project.
Basically the trick was:
generate the provider in Domino using the given WSDL
set RPC/Literal, according to the <soap:body use="literal"/> directive
export the Domino WSDL of the provider
create the SoapUI project with it
use it to call services provided
That's it! ... a very stupid mistake! :-(
Without a full WSDL I can't say with 100% this is the issue.
Based on what you have so far.
1. There are known issues where the "xsd:string" is wrapped with custom string handler. I have see references before where "string" would just sit on top of "xsd:string". So I would start with changing that back to "xsd:string" and see if it helps.
2. As your web service provider has the following:
Titolario[] classifica
Normally your WSDL should create an xxxArray Object which your consumer sends, and not the array object itself. (Tested on Doc/Literal + RPC/Literal, as "minoccurs" only shows up on Literal).
For example:
public String TestProtoModificaProtocollo (Titolario x[]) { ...
Converts to:
<complexType name="Titolario">
<sequence>
<element name="codice" nillable="true" type="xsd:string"/>
<element maxOccurs="unbounded" minOccurs="0" name="descrizione" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
<complexType name="TitolarioArray">
<sequence>
<element maxOccurs="unbounded" minOccurs="0" name="item" type="impl:Titolario"/>
</sequence>
</complexType>
<element name="x" type="impl:TitolarioArray"/>
<element name="TestProtoModificaProtocolloReturn" type="xsd:string"/>
So your consumer would translate to:
public java.lang.String testProtoModificaProtocollo(TitolarioArray x) throws java.rmi.RemoteException;
Related
We have a very old axis web service that we need to use with a client made with jaxws. One of the methods of this web services returns a type apachesoap:Document, where apachesoap schema is http://xml.apache.org/xml-soap.
The response XML looks like this:
<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>
<ns1:consultaXMLResponse xmlns:ns1="http://webservices.imagapp.app" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<consultaXMLReturn href="#id0"/>
</ns1:consultaXMLResponse>
<multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns2="http://xml.apache.org/xml-soap" id="id0" soapenc:root="0"
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xsi:type="ns2:Document">
<DatosConsultaWS>
<Registro>2974161</Registro>
</DatosConsultaWS>
</multiRef>
</soapenv:Body>
</soapenv:Envelope>
My adapted wsdl schema looks like this (I show only the response element, the rest I don't think is relevant because works fine).
<element name="consultaXMLResponse">
<complexType>
<sequence>
<element name="consultaXMLReturn">
<complexType>
<sequence>
<element name="DatosConsultaWS">
<complexType>
<sequence>
<element name="Registro" type="xsd:string"/>
</sequence>
</complexType>
</element>
</sequence>
<attribute name="href" type="xsd:anyURI"/>
<attribute name="id" type="xsd:ID"/>
<anyAttribute namespace="##other" processContents="strict"/>
</complexType>
</element>
</sequence>
</complexType>
</element>
However with this element, when I call that method, my client returns null (not even a ConsultaXMLReturn with null value inside).
I don't really know if what I'm trying to do is even posible.
Ideas? thanks.
What is the best way to convert this XML into Java objects?
<entity>
<customers id=2 other="data">
<customer name="john">testData1</customer>
<customer name="jenny">testData2</customer>
<customer name="joe">testData3</customer>
<customer name="joanna">testData4</customer>
</customers>
</entity>
Is it best to use a custom XMLAdapter with a HashMap to convert multiple xml rows of <customer>? I'm not sure if the XMLAdapter is the proper use case for this scenario. Any ideas would be appreciated.
Since the nesting isn't very deep, you could just have Entity, Customer classes and then use these annotations for the mapping in the entity class:
#XmlElementWrapper(name="customers")
#XmlElement(name="customer")
public void setCustomers(List<Customer> customers) {
this.customers= customers;
}
References:
XmlElementWrapper
Best approach, in my opinion, would be to write an xsd file to validate against your xml. You can use that to generate your java classes using xjc which comes bundled with Java. This should get you there.
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:NameOfNamespace="http://enter.your.namespace.here"
targetNamespace="http://enter.your.namespace.here"
attributeFormDefault="unqualified"
elementFormDefault="qualified">
<complexType name="customer">
<simpleContent>
<extension base="string">
<attribute name="name"/>
</extension>
</simpleContent>
</complexType>
<complexType name="customers">
<sequence>
<element name="customer" type="NameOfNamespace:customer"/>
</sequence>
<attribute name="id" type="positiveInteger"/>
<attribute name="other"/>
</complexType>
<complexType name="entity" >
<sequence>
<element name="customers" type="NameOfNamespace:customers" minOccurs="1" maxOccurs="1"/>
</sequence>
</complexType>
<element name="entity" type="NameOfNamespace:entity"/>
</schema>
Open a command prompt to the folder where you put your xsd file, and then generate java code you'll just need to type:
$ xjc nameOfSchemaFile.xsd
assuming your java 'bin' folder is in your path. The classes generated will be created in folder with the same name as your targetNamespace.
Using these you can follow the instructions in Naimish's example JAXB Hello World Example
I auto-generated a solution from a WSDL file for a project I'm working on, but for some reason the solution does not seem to correctly handle the input specified by the WSDL. Does anyone know what I can do to fix it?
Given the following operation:
<wsdl:operation name="createBin">
<wsdl:input message="impl:createBinRequest" name="createBinRequest"/>
<wsdl:output message="impl:createBinResponse" name="createBinResponse"/>
</wsdl:operation>
<wsdl:message name="createBinRequest">
<wsdl:part element="impl:createBin" name="parameters"/>
</wsdl:message>
<element name="createBin">
<complexType>
<sequence>
<element name="request" type="impl:Bin"/>
</sequence>
</complexType>
</element>
<complexType name="Bin">
<sequence>
<element name="FulfillerID" type="xsd:positiveInteger"/>
<element name="BinID" nillable="true" type="xsd:positiveInteger"/>
<element name="ExternalLocationID" type="xsd:string"/>
<element name="BinType" type="xsd:string"/>
<element name="BinStatus" type="xsd:string"/>
<element name="Name" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
Implemented with this code (auto-generated by eclipse):
public PositiveInteger createBin(Bin request) throws RemoteException {
throw new UnsupportedOperationException();
}
When sending this message:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://my.api.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<q0:createBin>
<q0:request>
<q0:FulfillerID>1234</q0:FulfillerID>
<q0:BinID>1234</q0:BinID>
<q0:ExternalLocationID>1234</q0:ExternalLocationID>
<q0:BinType>Good</q0:BinType>
<q0:BinStatus>Bad</q0:BinStatus>
<q0:Name>Ugly</q0:Name>
</q0:request>
</q0:createBin>
</soapenv:Body>
</soapenv:Envelope>
I get the following error:
<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>
<soapenv:Fault>
<faultcode>soapenv:Server.userException</faultcode>
<faultstring>org.xml.sax.SAXException: Invalid element in com.api.my.Bin - request</faultstring>
<detail>
<ns1:hostname xmlns:ns1="http://xml.apache.org/axis/">localhost</ns1:hostname>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
I'm 100% sure that the SOAP message is the correct format, so my server must be choking on something. When I remove the parameter, everything works swimmingly for some reason.
I can however, get the expected behavior by removing the element like so:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://my.api.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<q0:createBin>
<q0:FulfillerID>1234</q0:FulfillerID>
<q0:BinID>1234</q0:BinID>
<q0:ExternalLocationID>1234</q0:ExternalLocationID>
<q0:BinType>Good</q0:BinType>
<q0:BinStatus>Bad</q0:BinStatus>
<q0:Name>Ugly</q0:Name>
</q0:createBin>
</soapenv:Body>
</soapenv:Envelope>
I'm searching my brain to remember where I saw this before, but I'm certain I've seen some seemingly 'invalid SOAP requests' which turned out to be invalid because the response was invalid.
In this light: could you change the generated createBin(Bin request) code to return a PositiveInteger rather than -3? Maybe if we can make te response valid, your server will stop complaining.
Good Luck!
It turns out the SAX parser is not interpreting the request that it looks like it should. Even though the parameter to the method is request, it ignores that and expects to parse an element that has a request field of type com.api.my.Bin. The problem was fixed by changing .
public PositiveInteger createBin(Bin request) throws RemoteException {
throw new UnsupportedOperationException();
}
With
public PositiveInteger createBin(CreateBin request) throws RemoteException {
throw new UnsupportedOperationException();
}
Where
public class CreateBin {
public Bin request;
/* ... */
}
Though, to be transparent, I did have to do a lot of tweaking to the CoreServiceSoapBindingStub and CoreServiceSoapBindingSkeleton that eclipse generated in order to get the whole thing not to blow up because of invalid something-or-other.
<complexType name="spThread">
<sequence>
<element name="SPThreadID" type="int" />
<element name="durtime" minOccurs="0" default="0">
<simpleType>
<restriction base="int">
<minInclusive value="0" />
</restriction>
</simpleType>
</element>
<element name="minexecutions" minOccurs="0" default="0">
<simpleType>
<restriction base="int">
<minInclusive value="0" />
</restriction>
</simpleType>
</element>
<element name="numThreads" type="int" />
<element name="procedures" type="spm:procedure" minOccurs="1"
maxOccurs="unbounded" />
</sequence>
</complexType>
i want to generate this type of .xsd file using java code..? How can i do that.?
Specially how to generate Simple type elements and put restrictions on it ?
Instead of creating your own simple type to represent integers starting with 0, you could leverage the existing xs:nonNegativeInteger type. I'll demonstrate with an example.
SpThread
You can use the #XmlSchemaType annotation to specify what type should be generated in the XML schema for a field/property.
package forum11667335;
import javax.xml.bind.annotation.XmlSchemaType;
public class SpThread {
private int durTime;
#XmlSchemaType(name="nonNegativeInteger")
public int getDurTime() {
return durTime;
}
public void setDurTime(int durTime) {
this.durTime = durTime;
}
}
Demo
You can use the generateSchema method on JAXBContext to generate an XML schema:
package forum11667335;
import java.io.IOException;
import javax.xml.bind.*;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(SpThread.class);
jc.generateSchema(new SchemaOutputResolver() {
#Override
public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException {
StreamResult result = new StreamResult(System.out);
result.setSystemId(suggestedFileName);
return result;
}
});
}
}
Output
Below is the XML schema that was generated.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="spThread">
<xs:sequence>
<xs:element name="durTime" type="xs:nonNegativeInteger"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
You can use any XML-handling API to achieve this. JDOM is one of them. If you'd like an API specific to building XML Schemas which you then serialize into XML, you might want to check out Eclipse MDT API.
You can use Java2Schema tool for generating schema from java classes, and also you can try JaxB 2.0
I recommend you JAXB to any XML jobs you do. But normally XSD files are generated manually and then XML files are generated programatically using the XSD files. What are you trying to develop?
I am trying to consume a Java Webservice using Visual Basic.net. I am getting an error on deserialization "Cannot assign object of type System.Xml.XmlNode[] to an object of type System.String".
What I have been reading is that the wsdl specification may not conform to the WS-I BP 1.1 specification. Link Here
The other solution talked about here is to change the response xml to conform to a .net datatype. I have tried to do this for other reasons a couple of years back and it proved to be unstable.
A snippet of the wsdl is this:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://ws.interfaces.sessions.APILink.amdocs"
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="http://ws.interfaces.sessions.APILink.amdocs"
xmlns:intf="http://ws.interfaces.sessions.APILink.amdocs"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns2="http://io.datainfo.APILink.amdocs"
xmlns:tns3="http://datainfo.APILink.amdocs"
xmlns:tns4="http://awsi.amdocs.com"
xmlns:tns5="http://exceptions.APILink.amdocs"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<complexType name="InPersonInfo">
<complexContent>
<extension base="tns2:BaseInputOutputInfo">
<sequence>
<element maxOccurs="1" minOccurs="0" name="mItem1" type="xsd:int"/>
<element maxOccurs="1" minOccurs="0" name="mID" nillable="true" type="xsd:string"/>
<element maxOccurs="1" minOccurs="0" name="mPersonType" type="tns4:char"/>
</sequence>
</extension>
</complexContent>
</complexType>
The other pieces from the WSDL I am seeing is just the message and operation sections.
EDIT 2011-04-21: This question mentions what I am going through.
I am not familiar with java what I know is that it is being created/consumed with AXIS or SOAPUI and somehow it is not creating the WSDL according to standard and there is my problem. If I find an answer to solve it I will post it here.