ORVE WS (Dynamic) (1). Analising the WSDL and creating classes
1. Introduction
Our target is building a WS Client for ORVE
There is an introductory manual for this.
Let's create the client in a dynamic way, as the previous post
Java 10 will be used. Take care from java versions newer than 1.8 as they do not include XML libraries in the jvm.
To use these WS from ORVE, we need a user and a password. For security reasons, my user and password is not public so a generic user and password will be displayed in this post
2. The WSDL
The WDSL URL is:
https://ssweb.seap.minhap.es/demoorve/WSExportacion.wsdl
The WDSL response is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="https://ssweb.seap.minhap.es/demoorve/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" name="WSExportacion" targetNamespace="https://ssweb.seap.minhap.es/demoorve/"> <wsdl:types xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="https://ssweb.seap.minhap.es/demoorve/"> <xsd:complexType name="Security"> <xsd:sequence> <xsd:element name="username" type="xsd:string"/> <xsd:element name="password" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="SecurityElement" type="tns:Security"/> <xsd:complexType name="FiltrosIdentificadores"> <xsd:sequence> <xsd:element name="estado" type="xsd:string"/> <xsd:element name="oficina" type="xsd:string"/> <xsd:element name="unidad" type="xsd:string"/> <xsd:element name="numeroRegistro" type="xsd:string"/> <xsd:element name="fechaInicio" type="xsd:string"/> <xsd:element name="fechaFin" type="xsd:string"/> <xsd:element name="historico" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="FiltrosIdentificadoresElement" type="tns:FiltrosIdentificadores"/> <xsd:complexType name="obtenerIdentificaoresRespuestaWS"> <xsd:sequence> <xsd:element name="codigo" type="xsd:string"/> <xsd:element name="descripcion" type="xsd:string"/> <xsd:element name="identificadores" type="tns:AnyTypeArray"/> </xsd:sequence> </xsd:complexType> <xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="obtenerIdentificaoresRespuestaWSElement" type="tns:obtenerIdentificaoresRespuestaWS"/> <xsd:complexType name="AnyTypeArray"> <xsd:sequence> <xsd:element name="item" type="xsd:anyType" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> <xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="AnyTypeArrayElement" type="tns:AnyTypeArray"/> <xsd:complexType name="obtenerRegistroRespuestaWS"> <xsd:sequence> <xsd:element name="codigo" type="xsd:string"/> <xsd:element name="descripcion" type="xsd:string"/> <xsd:element name="registro" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="obtenerRegistroRespuestaWSElement" type="tns:obtenerRegistroRespuestaWS"/> </xsd:schema> </wsdl:types> <wsdl:portType name="WSExportacionPortType"> <wsdl:operation name="obtenerIdentificadores" parameterOrder="Security filtros"> <wsdl:input message="tns:obtenerIdentificadoresRequest"/> <wsdl:output message="tns:obtenerIdentificadoresResponse"/> </wsdl:operation> <wsdl:operation name="obtenerRegistro" parameterOrder="Security identificador"> <wsdl:input message="tns:obtenerRegistroRequest"/> <wsdl:output message="tns:obtenerRegistroResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="WSExportacionBinding" type="tns:WSExportacionPortType"> <soap:binding xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="obtenerIdentificadores"> <soap:operation xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" soapAction="https://ssweb.seap.minhap.es/demoorve/obtenerIdentificadores" style="rpc"/> <wsdl:input xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <soap:body xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" parts="filtros" use="literal" namespace="https://ssweb.seap.minhap.es/demoorve/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> <soap:header xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" message="tns:obtenerIdentificadoresRequest" part="Security" use="literal" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </wsdl:input> <wsdl:output xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <soap:body xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" parts="resultado" use="literal" namespace="https://ssweb.seap.minhap.es/demoorve/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> <soap:header xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" message="tns:obtenerIdentificadoresResponse" part="Security" use="literal" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </wsdl:output> </wsdl:operation> <wsdl:operation xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="obtenerRegistro"> <soap:operation xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" soapAction="https://ssweb.seap.minhap.es/demoorve/obtenerRegistro" style="rpc"/> <wsdl:input xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <soap:body xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" parts="identificador" use="literal" namespace="https://ssweb.seap.minhap.es/demoorve/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> <soap:header xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" message="tns:obtenerRegistroRequest" part="Security" use="literal" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </wsdl:input> <wsdl:output xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <soap:body xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" parts="resultado" use="literal" namespace="https://ssweb.seap.minhap.es/demoorve/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> <soap:header xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" message="tns:obtenerRegistroResponse" part="Security" use="literal" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:message name="obtenerIdentificadoresRequest"> <wsdl:part name="Security" element="tns:SecurityElement"/> <wsdl:part name="filtros" type="tns:FiltrosIdentificadores"/> </wsdl:message> <wsdl:message name="obtenerIdentificadoresResponse"> <wsdl:part name="Security" element="tns:SecurityElement"/> <wsdl:part name="resultado" type="tns:obtenerIdentificaoresRespuestaWS"/> </wsdl:message> <wsdl:message name="obtenerRegistroRequest"> <wsdl:part name="Security" element="tns:SecurityElement"/> <wsdl:part name="identificador" type="xsd:int"/> </wsdl:message> <wsdl:message name="obtenerRegistroResponse"> <wsdl:part name="Security" element="tns:SecurityElement"/> <wsdl:part name="resultado" type="tns:obtenerRegistroRespuestaWS"/> </wsdl:message> <wsdl:service xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="WSExportacionService"> <wsdl:port xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="WSExportacionPort" binding="tns:WSExportacionBinding"> <soap:address xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" location="https://ssweb.seap.minhap.es/demoorve/WSExportacion.php"/> </wsdl:port> </wsdl:service> </wsdl:definitions> |
3.The name of the package
The package of the class is located in line 3 with the tag
<xsd:schema ... targetNamespace="https://ssweb.seap.minhap.es/demoorve/">
And changing:
"://" with "."
"," with "_"
"/" with "."
The package is :
https.ssweb_seap_minhap_es.demoorve
"://" with "."
"," with "_"
"/" with "."
The package is :
https.ssweb_seap_minhap_es.demoorve
4. Classes to use
There are 4 main classes
4.1 Class "Security"
WDSL Line 4
Purpose: Defines the login properties used in the HEAD of the WS
Attributes:
- username (String)
- password (String)
4.2 Class "FiltrosIdentificadores"
WDSL Line 11
Purpose: To narrow down the query results
Attributes:
- estado (String) The phase of the record to retrieve
- oficina (String) The DIR3 office
- unidad (String) The DIR3 unit
- numeroRegistro (String) Record number
- fechaInicio (String) Begining data
- fechaFin (String) End date
- historico (String) History
4.3 Class "ObtenerIdentificaoresRespuestaWS"
WDSL Line 23
Purpose: Returns the ids of the records. It is the response of a request
Attributes:
- codigo (String) If "00" then no error reported, else an error is reported
- descripcion (String) Describes a resume of the response.
- identificadores (AnyTypeArray) An array or list of the ids
4.4 Class "ObtenerRegistroRespuestaWS"
WDSL Line 37
Purpose: Returns the record that matches a provided id. It is the response of a request
Attributes:
- codigo (String) If "00" then no error reported, else an error is reported
- descripcion (String) Describes a resume of the response.
- registro (String) A complex element that defines the record
5. Services to use (Requests)
2 services will be used:
5.1 Service "obtenerIdentificadores"
WDSL Line 48
Purpose: Gets the ids of the records to retrieve
Input parameter: obteneridentificadoresRequest (line 49) that consists of
- Security line 83
- Filtrosidentificadores line 84
Output parameter: obtenerIdentificadoresResponse (line 50) that consists of
- Security line 87
- ObtenerIdentificaoresRespuestaWS line 88
5.2 Service "obtenerRegistro"
WDSL Line 52
Purpose: Gets the record of a supplied ids
Input parameter: obtenerRegistroRequest (line 53) that consists of
- Security line 91
- Identificator (int) line 92
Output parameter: obtenerRegistroResponse (line 54) that consists of
- Security line 95
- ObtenerRegistroRespuestaWS line 96
6. Creating classes with wsdl2java
Although the dynamic way is preferred, many problems have arisen in this project, so it is not a bad idea to create the classes with the wsdl2tava command and inspect the generated code.
6.1 Select java 1.8 version (Now There is compatibility with Java 13)
First, the Java 1.8 version (or older) is needed for compatibility use of wsdl2java command.
In Ubuntu, it is required to change java and javac. For java:
sudo update-alternatives --config java
and select the java version
Selection Path Priority State ------------------------------------------------------------ 0 /usr/lib/jvm/java-10-oracle/bin/java 1091 mode automàtic 1 /home/eduard/ProgramesMeus/jdk-10.0.1/bin/java 1 mode manual * 2 /home/eduard/ProgramesMeus/jdk1.8.0_181/bin/java 1 mode manual 3 /usr/lib/jvm/java-10-openjdk-amd64/bin/java 1 mode manual 4 /usr/lib/jvm/java-10-oracle/bin/java 1091 mode manual 5 /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java 1081 mode manual 6 /usr/lib/jvm/java-9-openjdk-amd64/bin/java 1091 mode manual 7 /usr/lib/jvm/java-9-oracle/bin/java 1091 mode manual Press return for default option[*], or input a selection number:
For javac (compiler), it is similar
sudo update-alternatives --config javac
and select the javac version as the previous step.
It is important to test our java version trying these commands
java -version javac -version
6.2 Generate the classes
Download Apache CXF if you have not yet downloaded it and extract it into a folder.Open a terminal, go into the generated "bin" folder and execute
UPDATE: As you can use with java 13, you need now this environment variables to be set
$JAVA_HOME
$CXF_HOME
In my case :
export JAVA_HOME=/usr/java/jdk-13.0.2
export CXF_HOME=/home/eduard/MyPrograms/apache-cxf-3.3.5
wsdl2java -ant -client -d ClientDir https://ssweb.seap.minhap.es/demoorve/WSExportacion.wsdl
where ClientDir is the name of the folder where Java code will be generated and the blue code identifies the WSDL URL.
A package named https.ssweb_seap_minhap_es.demoorve has been created
6.3 Important class
The most important class is the one that ends with "_Client.java", that is a skeleton of how to use all the operations provided in the web service. This class is
WSExportacionPortType_WSExportacionPort_Client.java
6.4 Problematic class
Maybe due to changes in Java versions and XML libraries, the class "AnyTypeArray.java" is very problematic as internally it uses the ElementNSImpl class that is referenced in 2 different packages. To solve this problem, simply change "<Object>" by "<Integer>", as in this particular case only integers will be used. Here is the code. the changes are reflected in lines 36,36,60 and 61.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | package https.ssweb_seap_minhap_es.demoorve; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlType; /** * <p>Java class for AnyTypeArray complex type. * * <p>The following schema fragment specifies the expected content contained within this class. * * <pre> * <complexType name="AnyTypeArray"> * <complexContent> * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * <sequence> * <element name="item" type="{http://www.w3.org/2001/XMLSchema}anyType" maxOccurs="unbounded" minOccurs="0"/> * </sequence> * </restriction> * </complexContent> * </complexType> * </pre> * * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "AnyTypeArray", propOrder = { "item" }) public class AnyTypeArray { //protected List<Object> item; protected List<Integer> item; /** * Gets the value of the item property. * * <p> * This accessor method returns a reference to the live list, * not a snapshot. Therefore any modification you make to the * returned list will be present inside the JAXB object. * This is why there is not a <CODE>set</CODE> method for the item property. * * <p> * For example, to add a new item, do as follows: * <pre> * getItem().add(newItem); * </pre> * * * <p> * Objects of the following type(s) are allowed in the list * {@link Object } * * */ //public List<Object> getItem() { public List<Integer> getItem() { if (item == null) { //item = new ArrayList<Object>(); item = new ArrayList<Integer>(); } return this.item; } } |
Comments
Post a Comment