Webservices, webservices, porque me dificultas tanto la vida? Esta bien, son un reto, son algo nuevo para mi y mantienen las cosas interesantes. Aunque me estoy quejando de webservices y realmente son los clients los que han sido dolores de cabeza. En el pasado escribi un post de como generar clientes en ADB y en xmlBeans con el Axis2 Code Generator Eclipse plugin. Al tener otro problema con estos clientes, tuve que irme por la solucion de clientes generados por linea de comando.
En general es muy sencillo. Estoy segura que hay mas informacion al respecto pero he aqui lo esencial.
Descargar las librerias de Axis2. Trata siempre de estar actualizando ya que Axis pasa corrigiendo bugs conocidos que probablemente sean los que te estan dando problemas.
Abres una consola DOS y navegas hasta llegar al directory donde tienes tus librerias Axis2. Navega hasta la carpeta bin. escribe el siguiente comando:
WSLD2JAVA -uri http://EndpointDelWebService?wsdl
Hay mas comandos que puedes agregar a esta sentencia para especificar databinding (ADB es el default en esta generacion tambien), ruta en donde poner las clases generadas, etc. Para mas informacion puedes buscar aqui: http://axis.apache.org/axis2/java/core/docs/reference.html
Navega en la carpeta bin y copia las tareas generadas (clases JAVA). Copia las clases en algun proyecto donde desees el webclient (En este caso no tenemos problemas poniendolo en un Java Project que te permite usar este .jar para cualquier proyecto que requiera usar ese cliente).
Siempre requeriras crear clases para consumir las clases generadas. En mi caso siempre necesito un ConectionStud manager y un PasswordCallbackHandler. Las clases son un poco bruscas a mi parecer ya que generan casi todo el codigo en una sola clase, pero si necesitas entrar al codigo para hacer cambios, el codigo generado es un poco mas facil de seguir y cambiar que las clases generadas por los Eclipse code generator plugins.
En una nota aparte, tambien tuvimos problemas con el policy del webservice. Por lo general, el policy va dentro del request cuando envias el user y password. En este caso tuvimos problemas porque el webservice nos retornaba que no encontraba el policy. Se tuvo que crear .xml que llevara el policy con el username de nuestro cliente para poder solucionar este problema. Ejemplo de Policy:
<?xml version="1.0" encoding="UTF-8"?>
<wsp:Policy wsu:Id="wss_username_token_service_policy"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsp:ExactlyOne>
<wsp:All>
<sp:SupportingTokens
xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:UsernameToken
sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken>TuUserName</sp:WssUsernameToken>
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:user>TuUserName</ramp:user>
<ramp:passwordCallbackClass>package.claseDeTuCallBackHandler</ramp:passwordCallbackClass>
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
Como puedes ver en el ejemplo, se utiliza ramparta para el manejo de autenticacion por lo que necesitaras el modulo rampart (yo utilizo el 1.4 aunque no es el ultimo) y agregar las librerias de rampart.
Para el uso de este, debes configurar apache.axis2.client.options en el ConectionStud Manager.
Aqui un pequeño ejemplo:
ClientGeneradoStub result = new ClientGeneradoStub ();
ServiceClient sc = result.getServiceClient();
Options options = new Options();
options.setUserName("TuUserName");
options.setTo(new EndpointReference(endPoint));
options.setProperty(RampartMessageData.KEY_RAMPART_POLICY, loadPolicy(repositoryPath + "policy/policy.xml"));
sc.setOptions(options);
sc.engageModule("rampart");
private static Policy loadPolicy(String xmlPath) throws Exception {
StAXOMBuilder builder = new StAXOMBuilder(xmlPath);
return PolicyEngine.getPolicy(builder.getDocumentElement());
}
Ahora, en el llamado al loadPolicy mandas el directorio en donde se encuentras tu archivo policy.xml (o como tu lo nombraste). Yo agregaba esto al directorio: "policy\\policy.xml" y funcionaba perfectamente. Sin embargo, una vez en produccion, el cliente se volvio a quejar que no encontraba el policy. Crei que el problema era de permisos de carpeta y no lei el policy porque no podia. El problema era de sintaxis. Un amable compañero descubrio que la sintaxis correcta era: "policy/policy.xml". Mi sintaxis corria perfectamente en windows, pero la sintaxis del compañero corria en windows y linux y voila!
Bueno, ahi sigo con los exploits en el mundo de webservices. Espero esto te ayude!
En general es muy sencillo. Estoy segura que hay mas informacion al respecto pero he aqui lo esencial.
Descargar las librerias de Axis2. Trata siempre de estar actualizando ya que Axis pasa corrigiendo bugs conocidos que probablemente sean los que te estan dando problemas.
Abres una consola DOS y navegas hasta llegar al directory donde tienes tus librerias Axis2. Navega hasta la carpeta bin. escribe el siguiente comando:
WSLD2JAVA -uri http://EndpointDelWebService?wsdl
Hay mas comandos que puedes agregar a esta sentencia para especificar databinding (ADB es el default en esta generacion tambien), ruta en donde poner las clases generadas, etc. Para mas informacion puedes buscar aqui: http://axis.apache.org/axis2/java/core/docs/reference.html
Navega en la carpeta bin y copia las tareas generadas (clases JAVA). Copia las clases en algun proyecto donde desees el webclient (En este caso no tenemos problemas poniendolo en un Java Project que te permite usar este .jar para cualquier proyecto que requiera usar ese cliente).
Siempre requeriras crear clases para consumir las clases generadas. En mi caso siempre necesito un ConectionStud manager y un PasswordCallbackHandler. Las clases son un poco bruscas a mi parecer ya que generan casi todo el codigo en una sola clase, pero si necesitas entrar al codigo para hacer cambios, el codigo generado es un poco mas facil de seguir y cambiar que las clases generadas por los Eclipse code generator plugins.
En una nota aparte, tambien tuvimos problemas con el policy del webservice. Por lo general, el policy va dentro del request cuando envias el user y password. En este caso tuvimos problemas porque el webservice nos retornaba que no encontraba el policy. Se tuvo que crear .xml que llevara el policy con el username de nuestro cliente para poder solucionar este problema. Ejemplo de Policy:
<?xml version="1.0" encoding="UTF-8"?>
<wsp:Policy wsu:Id="wss_username_token_service_policy"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsp:ExactlyOne>
<wsp:All>
<sp:SupportingTokens
xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:UsernameToken
sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken>TuUserName</sp:WssUsernameToken>
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:user>TuUserName</ramp:user>
<ramp:passwordCallbackClass>package.claseDeTuCallBackHandler</ramp:passwordCallbackClass>
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
Como puedes ver en el ejemplo, se utiliza ramparta para el manejo de autenticacion por lo que necesitaras el modulo rampart (yo utilizo el 1.4 aunque no es el ultimo) y agregar las librerias de rampart.
Para el uso de este, debes configurar apache.axis2.client.options en el ConectionStud Manager.
Aqui un pequeño ejemplo:
ClientGeneradoStub result = new ClientGeneradoStub ();
ServiceClient sc = result.getServiceClient();
Options options = new Options();
options.setUserName("TuUserName");
options.setTo(new EndpointReference(endPoint));
options.setProperty(RampartMessageData.KEY_RAMPART_POLICY, loadPolicy(repositoryPath + "policy/policy.xml"));
sc.setOptions(options);
sc.engageModule("rampart");
private static Policy loadPolicy(String xmlPath) throws Exception {
StAXOMBuilder builder = new StAXOMBuilder(xmlPath);
return PolicyEngine.getPolicy(builder.getDocumentElement());
}
Ahora, en el llamado al loadPolicy mandas el directorio en donde se encuentras tu archivo policy.xml (o como tu lo nombraste). Yo agregaba esto al directorio: "policy\\policy.xml" y funcionaba perfectamente. Sin embargo, una vez en produccion, el cliente se volvio a quejar que no encontraba el policy. Crei que el problema era de permisos de carpeta y no lei el policy porque no podia. El problema era de sintaxis. Un amable compañero descubrio que la sintaxis correcta era: "policy/policy.xml". Mi sintaxis corria perfectamente en windows, pero la sintaxis del compañero corria en windows y linux y voila!
Bueno, ahi sigo con los exploits en el mundo de webservices. Espero esto te ayude!
Hola, no sabes lo útil que me está siendo tu blog. Pero tengo una duda, igual me la sabes responder...
ReplyDeleteResulta que quiero acceder a un web service a través de wdsl. Lo estoy programando en java embebido en Matlab. El caso es que conecta bien y manda el mensaje de petición, pero a la hora de recibir el mensaje, salta el siguiente error: "SOAP Fault: org.apache.axis2.databinding.ADBException: Unexpected subelement
HistoricRequest"
¿Sabes si puede ser que tengo mal instaladas las librerías de axis2? ¿Qué otra cosa puede ser?
Mil gracias de antemano.
Saludos!
María
Hola Maria, no me he encontrado con ese error, lo siento.
ReplyDelete