WebServices
Los servicios Web XML permiten que las aplicaciones compartan información y que además invoquen funciones de otras aplicaciones independientemente de cómo se hayan creado las aplicaciones, cuál sea el sistema operativo o la plataforma en que se ejecutan y cuáles los dispositivos utilizados para obtener acceso a ellas. Aunque los servicios Web XML son independientes entre sí, pueden vincularse y formar un grupo de colaboración para realizar una tarea determinada
Definición de XML Web Services
Los servicios XML Web Services son los elementos fundamentales en la evolución hacia la computación distribuida a través de Internet. Se están convirtiendo en la plataforma de integración de aplicaciones gracias a los estándares abiertos y al énfasis en la comunicación y colaboración entre personas y aplicaciones. Las aplicaciones se crean utilizando los servicios XML Web Services múltiples de origen distinto que funcionan conjuntamente, sin importar su ubicación o la forma en que se implementaron.
Existen tantas definiciones de los servicios XML Web Services como empresas que los diseñan. Sin embargo la idea general es:
SOAP
SOAP es el protocolo de comunicaciones para los servicios XML Web Services. SOAP es un protocolo de mensajería XML extensible que forma la base de los Servicios Web. SOAP proporciona un mecanismo simple y consistente que permite a una aplicación enviar mensajes XML a otra aplicación. Un mensaje SOAP es una transmisión de una vía desde un emisor SOAP a un receptor SOAP, y cualquier aplicación puede participar en este intercambio como emisor o receptor. Los mensajes SOAP se pueden combinar para soportar muchos comportamientos de comunicación, incluyendo, solicitud/respuesta, respuesta solicitada, mensajería asíncrona de una-vía, o incluso notificación. SOAP es un protocolo de alto nivel que sólo define la estructura del mensaje y unas pocas reglas para su procesamiento. Es completamente independiente del protocolo de transporte subyacente, por eso los mensajes SOAP se pueden intercambiar sobre HTTP, JMS o protocolos de transporte de e-mail. Actualmente el protocolo HTTP es el más utilizado para los mensajes HTTP.
Si desean mayor documentación sobre SOAP, ver http://www.w3.org/TR/soap/ .
WSDL
WSDL es el acrónimo de Web Services Description Language (lenguaje de descripción de servicios Web). Para nuestros objetivos, se puede definir un archivo WSDL como un documento XML que describe un conjunto de mensajes SOAP y la forma en la que éstos se intercambian. La notación que utiliza un archivo WSDL para describir formatos de mensaje se basa en el estándar XML. Esto significa que es un idioma de programación neutral y basado en estándares, lo cual es perfecto para describir interfaces de servicios XML Web Services que pueden abrirse desde una gran variedad de plataformas y lenguajes de programación. Además de describir el contenido de un mensaje, WSDL define el lugar en el que está disponible el servicio y qué protocolo de comunicaciones se utiliza para hablar al servicio. Esto significa que el archivo WSDL define todos los elementos necesarios para escribir un programa que pueda funcionar con un servicio XML Web. Existen varias herramientas disponibles para leer un archivo WSDL y generar el código necesario para establecer comunicación con un servicio XML Web.
Si desean mayor documentación sobre WSDL, ver http://www.w3.org/TR/wsdl y http://www.w3.org/TR/REC-xml-names/ .
Para mayor información de los temas mencionados se pueden consultar los siguientes links:
http://www.microsoft.com/spanish/msdn/articulos/archivo/280202/voices/webservbasics.asp
http://www.microsoft.com/spanish/msdn/articulos/archivo/091101/voices/wsdlexplained.asp
http://e-docs.bea.com/wls/docs70/webserv/index.html
http://ws.apache.org/axis/java/user-guide.html
http://www.programacion.com/java/tutorial/servic_web/
http://www.osmosislatina.com/axis/webservices.htm
http://www.w3.org/2001/XMLSchema
Web Services para Teledespacho Web
Para el proyecto de Teledespacho Web, SUNAT ha implementado en la siguiente dirección
http://www.aduanet.gob.pe/ws-ad-pd/ws-ad-pd, los servicios Web habilitados que van a complementar la funcionalidad del Portafolio de Documentos, permitiendo el envío en serie de los archivos de numeración de documentos aduaneros.
A continuación se brinda una breve descripción de cada unos los Web Services, la manera de invocarlos y los valores que retornan, para poder realizar una adecuada implementación en los diferentes sistemas. Una vez implementado en los sistemas de los Operadores de Comercio Exterior, estos sistemas podrán realizar el envío automático de los archivos antes mencionados.
· WS enviaArchivoWebService, este Web Service , a manera del Portafolio de Documentos, permite el envío de archivos para la recepción y numeración de documentos aduaneros.
Parámetros de ingreso:
Nombre |
Tipo de Dato |
Descripción |
toperador |
String |
Tipo Operador |
operador |
String |
Código de operador, para el caso de un agente de aduana, seria su código de agente. |
clave |
String |
Clave de envío por Teledespacho |
aduana |
String |
Código de aduana |
archivoEnvioByte |
byte[] |
Archivo físico enviado como una cadena o arreglo de bytes. |
nombreArchivo |
String |
Nombre del archivo físico que se esta enviando. |
Los valores para el tipo de operador son los siguientes:
A: Agente de Aduana
D: Despachador Oficial
R: Beneficiario
C: Consignatario
F: Deposito Material Aeronáutico
G: Agente Marítimo
I: Agente de Carga Internacional L: Linea AereaM: Mensajeria Courier
T: Terminal de AlmacenamientoParámetros de retorno:
NroEnvioGenerado |
String |
Numero de la orden generada por el archivo enviado. |
La manera de cómo manejar el tipo de dato byte[] se detalla en el ejemplo mostrado en la sección Invocar WebServices desde cliente Java.
· WS obtieneArchivoRpta, permite obtener el archivo de respuesta generado por la orden enviada, una vez que ya fue procesada por el validador de Teledespacho.
Parámetros de ingreso:
Nombre |
Tipo de Dato |
Descripción |
toperador |
String |
Tipo Operador |
operador |
String |
Código de operador, para el caso de un agente de aduana, seria su código de agente. |
clave |
String |
Clave de envío por Teledespacho |
aduana |
String |
Código de aduana |
ano |
String |
Año de envío del archivo físico. |
NroEnvioGenerado |
String |
Numero de la orden generada por el archivo enviado. |
Parámetros de retorno:
nombreArchivo |
byte[] |
Archivo físico de respuesta del numero de la orden generada, como un arreglo de bytes. |
· WS verficaRUC, este Web Services, permite verificar si los datos del Operador de Comercio Exterior, están actualizados en la Web de ADUANAS.
Parámetros de ingreso:
Nombre |
Tipo de Dato |
Descripción |
ruc |
String |
RUC del Operador de Comercio Exterior |
Parámetros de retorno:
estado |
String |
Estado del RUC del Operador de Comercio Exterior:
|
· WS verificaDatadoManifiesto , este Web Service permite verificar si un manifiesto esta disponible para ser datado o no.
Parámetros de ingreso:
Nombre |
Tipo de Dato |
Descripción |
aduana |
String |
Aduana del manifiesto |
anomc |
String |
Año del Manifiesto (2 o 4 dígitos) |
numeromc |
String |
Numero del Manifiesto |
conoembar |
String |
Conocimiento de embarque. |
viatrans |
String |
Vía de transporte . |
tipomani |
String |
Tipo de Manifiesto M: Importación X: Exportación |
Parámetros de retorno:
datoManifiesto |
String |
Cadena de caracteres con el siguiente formato: Numero de detalle del manifiesto: 3 caracteres a partir de la primera posición. Puerto de Embarque:5 caracteres a partir de la posición 4. Código de Terminal: 4 caracteres a partir de la posición 9. Saldo de peso recibido: 16 caracteres (incluido el punto decimal) a partir de la posición 13. Saldo de bultos recibidos: 16 caracteres (incluido el punto decimal) a partir de la posición 30. |
WebServices desde cliente Java
La llamada a un Web Services hecho puede ser implementada desde un programa cliente ( en java, este programa cliente puede ser un JSP, Servlet, o un programa simple )hecho en cualquier lenguaje de programación que soporte tecnología.
Esta implementación consiste en agregar algunas líneas de código en cada sistema, de tal manera que puedan invocar a los métodos implementados
En la siguiente dirección mostramos un ejemplo de cómo invocar los WS implementados, desde una aplicación cliente en Java.
http://www.aduanet.gob.pe/js/app/WebServices/ClienteWebServicesPD.java
Para la implementación de los WS , se ha usado la librería axis.jar del Apache, el cual lo pueden bajar de la siguiente dirección http://ws.apache.org/axis/java/install.html .
Cabe señalar q los métodos obtieneArchivoRpta y enviaArchivoWebService, manejan parámetros que tienen un tipo de dato arreglo de bytes, el cual se usa para el envío y recepción de los archivo físicos de los envíos que realizan los Operadores de Comercio Exterior.
Adicionalmente, se muestra la rutina para la conversión de archivo al tipo de dato definido en java como arreglo de bytes, el cual también se encuentra incorporado en el archivo ClienteWebServicesPD.
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;…
String polizaZIP= (args[0]!=null)?args[0]:"C:/tci/mailbox/error7019.zip";
FileInputStream fis = new FileInputStream(polizaZIP);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int c = 0;
while((c = fis.read()) != -1){
baos.write(c);
}
fis.close();
byte[] byteReturn = baos.toByteArray();
baos.close();
Ejemplo practico:
Fuente: http://www.osmosislatina.com/axis/webservices.htm
Esta metodología para diseñar "Web-Services" en Axis es una de las maneras más sencillas para ejemplificar el uso de SOAP; para efectos didácticos la Clase empleada como "Web-Service" será sumamente sencilla para lograr enfatizar los conceptos de esta Tecnología.
Código Fuente Calculadora.jws
public class Calculadora { public int sumar(int x, int y) { return x + y; }
public int restar(int x, int y) { return x - y; } } |
La Clase Java anterior define dos métodos los cuales suman y restan respectivamente dos valores proporcionados como datos de entrada, nótese que esta Clase es definida con la terminación .jws(Java Web Service) y no con la clásica terminación .java.
Para ejecutar esta Clase dentro de Axis debe ser colocada bajo el WAR Axis ("Web-Archive") definido anteriormente, la clase debe ser colocada como Código Fuente y no debe ser compilada; recuerde que debido al contenido del archivo web.xml en este WAR ("Web-Archive"), todo archivo terminado en .jws será procesado por Axis.
Accesando "Web-Services"
Si en este momento revisa el URL :http://www.servidorprueba.com:8080/axis/Calculadora.jws debe observar una consola de Axis indicando los servicios que se encuentran registrados ("deployed"), en dicho registro aún no se encuentra el "Web-Service" de Calculadora.jws.
Sin embargo, a pesar que el "Web-Service" aún no se encuentra registrado ("deployed"), es posible accesarlo de un Cliente, esta es una de las ventajas de utilizar "Web-Services" de manera nativa (*.jws), el registro ("deployment") de "Web-Services" será descrito en la ultima sección de esta guia.
A continuación se describe el Cliente que puede accesar el "Web-Service" Calculadora.jws.
Código Fuente ClienteCalc.java
import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.encoding.XMLType; import javax.xml.rpc.ParameterMode; public class ClienteCalc { public static void main(String [] args) throws Exception { String endpoint = "http://servidorprueba.com:8080/axis/Calculadora.jws";
if (args == null || args.length != 3) { System.err.println("Uso: ClienteCalc <sumar|restar> arg1 arg2"); return; }
String method = args[0]; if (!(method.equals("sumar") || method.equals("restar"))) { System.err.println("Uso: ClienteCalc <sumar|restar> arg1 arg2"); return; }
Integer i1 = new Integer(args[1]); Integer i2 = new Integer(args[2]); Service service = new Service(); Call call = (Call) service.createCall(); call.setTargetEndpointAddress( new java.net.URL(endpoint) ); call.setOperationName( method ); call.addParameter( "op1", XMLType.XSD_INT, ParameterMode.IN ); call.addParameter( "op2", XMLType.XSD_INT, ParameterMode.IN ); call.setReturnType( XMLType.XSD_INT ); Integer ret = (Integer) call.invoke( new Object [] { i1, i2 });
System.out.println("Resultado : " + ret); } } |
Este Cliente que accesa el "Web-Service" es una simple Clase que puede ser ejecutada de una consola ("shell"), otra alternativa pudo haber sido diseñar otro Servlet o posiblemente un EJB que accesará la funcionalidad; para compilar este Cliente que accesa el "Web-Service" es necesario que las diversas librerías de Axis se encuentren en el CLASSPATH de compilación, esto se debe a que el Cliente utiliza diversas Clases Axis para llevar acabo la comunicación con el "Web-Service".
Una vez compilada esta Clase basta ejecutar una secuencia como la siguiente para llamar el "Web-Service":
# java ClienteCalc sumar 234 23 Resultado : 257 # java ClienteCalc restar 34 42 Resultado : -8 # java ClienteCalc sumar 23 1 Resultado : 24 |
El despliegue anterior demuestra tres invocaciones hacia el "Web-Service" Calculadora.jws.
Web Services desde Visual Fox Pro
También se adiciona un programa que invoca a los Web Services desde un cliente hecho en Visual Fox Pro.
Este ejemplo lo pueden encontrar también en la siguiente ruta http://www.aduanet.gob.pe/js/app/WebServices/clienteWSVisualFoxPro.zip junto con la librería FoxCrypto.fll. La libreria FoxCrypto.fll contiene la función que codifica y decodifica en base 64., el cual permite el trabajo tipo de datos bytes.
Prueba.prg
SET LIBRARY TO FoxCrypto.FLL
PROCEDURE psEnviArchivo
***********************
*envia archivo
PARAMETER pArc
tcInFile = IIF(EMPTY(pArc),"C:\desaprg\prueba\CDDEmbargoM4.htm", pArc)
lcInFile = FILETOSTR(tcInFile)
lcInFile64 = codifica(lcInFile)
***
doc = CreateObject("MSXML2.DOMDocument")
http = CreateObject("MSXML2.XMLHTTP")
http.Open("POST", "http://desweb1:8001/portafolio/portafolio", .F.)
http.SetRequestHeader("SOAPAction", "enviaArchivoWebService")
http.SetRequestHeader("Content-Type", "text/xml")
**carga el archivo
xml = fnArmaCadXml("A", "0091", "XXXX", "142", lcInFile64, "CDDEmbargoM5.htm")
doc.LoadXML(xml)
http.Send(doc.xml)
res = CreateObject("MSXML2.DOMDocument")
response = http.responseText
*?response
res.LoadXML(http.responseText)
txt = res.selectSingleNode("//NroEnvioGenerado") &&Return
IF nvl(txt.text,' ') = " " THEN
TXT="ERROR EN WS "
ENDIF
wait window txt.text NOWAIT
*? txt.text
release doc
release http
release res
release response
RETURN
FUNCTION decodifica
PARAMETER pCadena
LOCAL lcBinary, lnHandle, lnSize
lnHandle = Base64DecoderCreate()
IF lnHandle > 0
Base64DecoderPut(lnHandle, pCadena)
Base64DecoderClose(lnHandle)
lnSize = Base64DecoderMaxRetrievable(lnHandle)
lcBinary = Base64DecoderGet(lnHandle, lnSize)
Base64DecoderDestroy(lnHandle)
ELSE
WAIT WIND "ERROR al instanciar"
RETURN .F.
ENDIF
RETURN lcBinary
FUNCTION codifica
PARAMETER pCadena
LOCAL lcBase64, lcInFile, lnHandle, lnSize
lnHandle = Base64EncoderCreate( .T. )
IF lnHandle > 0
Base64EncoderPut(lnHandle, pCadena)
Base64EncoderClose(lnHandle)
lnSize = Base64EncoderMaxRetrievable(lnHandle)
lcBase64 = Base64EncoderGet(lnHandle, lnSize)
Base64EncoderDestroy(lnHandle)
ELSE
WAIT WIND "ERROR al instanciar"
RETURN .F.
ENDIF
RETURN lcBase64
FUNCTION fnArmaCadXml
*********************
PARAMETER pTOpe, pOpe, pClave, pAdu, pArch, pNomArch
strxml = [<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"] + CHR(13)
strxml = strxml + [ xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"] + CHR(13)
strxml = strxml + [ xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"] + CHR(13)
strxml = strxml + [ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">] + CHR(13)
strxml = strxml + [ <env:Header>] + CHR(13)
strxml = strxml + [ </env:Header>] + CHR(13)
strxml = strxml + [ <env:Body>] + CHR(13)
strxml = strxml + [ <m:enviaArchivoWebService xmlns:m="http://www.bea.com/education/webservices/examples/basic/javaclass"] + CHR(13)
strxml = strxml + [ env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">] + CHR(13)
strxml = strxml + [ <toperador xsi:type="xsd:string">] + pTOpe + [</toperador>] + CHR(13)
strxml = strxml + [ <operador xsi:type="xsd:string">] + pOpe + [</operador>] + CHR(13)
strxml = strxml + [ <clave xsi:type="xsd:string">] + pClave + [</clave>] + CHR(13)
strxml = strxml + [ <aduana xsi:type="xsd:string">] + pAdu + [</aduana>] + CHR(13)
strxml = strxml + [ <archivoEnvioByte xsi:type="xsd:base64Binary">] + pArch + [</archivoEnvioByte>] + CHR(13)
strxml = strxml + [ <nombreArchivo xsi:type="xsd:string">] + pNomArch+ [</nombreArchivo>] + CHR(13)
strxml = strxml + [ </m:enviaArchivoWebService>] + CHR(13)
strxml = strxml + [ </env:Body>] + CHR(13)
strxml = strxml + [</