domingo, 2 de mayo de 2010

MANEJO DE JAKARTA HTTP CLIENT

Bueno en esta oportunidad postearé sobre un Framework muy útil, para los casos en los que, muchos desarrolladores, en algún momento hemos estado en el escenario en el que teníamos que enviar parámetros a un Servlet pero sin esta necesariamente en un JSP, ni apoyándose en una funciona JavaScript, sino que desde una clase JAVA. Para esto un Framework aparece en nuestro rescate, este se llama: 'Jakarta Commons HttpClient'. Este Framework permite realizar una conexión directa a un JSP o un Servlet enviando fácilmente los parámetros respectivos y identificar rápidamente datos como del Response como: TIPO (GET/POST), URL, SERVLET, PARAMETROS DEL SERVLET, ESTATUS, HTML, etc.

El demo preparado muestra el manejo de 'HttpClient' y se conecta con un 'Servlet' de un demo anteriomente mostrado para manejos de Servlet´s. El ejemplo de Servket lo descargas de aquí:
DEMO MANEJO SERVLET.

Para mayor detalle descargar el ejemplo completo de 'HttpClient': AQUÌ.

sábado, 1 de mayo de 2010

MANEJO DE SERVLETs

Que tal esta oportunidad postearé sobre un tema ya un poco antiguo, pero que nunca pasará 100% de moda, ya que por mas frameworks que utilicemos para nuestros desarrollos en algún momento tendremos la necesidad de recurrir al uso de un Servlet.

Un servlet es un objeto que se ejecuta en un servidor o contenedor JEE, especialmente diseñado para ofrecer contenido dinámico desde un servidor web, generalmente HTML.

Un servlet implementa la interfaz javax.servlet.Servlet o hereda alguna de las clases más convenientes para un protocolo específico (Ejm: javax.servlet.HttpServlet). Al implementar esta interfaz el servlet es capaz de interpretar los objetos de tipo 'HttpServletRequest' y 'HttpServletResponse' quienes contienen la información de la página que invocó al servlet.

Ciclo de vida de un Servlet.

El ciclo de vida de un Servlet se divide en los siguientes puntos:

1. El cliente solicita una petición a un servidor vía URL.
2. El servidor recibe la petición.
2.1. Si es la primera, se utiliza el motor de Servlets para cargarlo y se llama al método init().
2.2. Si ya está iniciado, cualquier petición se convierte en un nuevo hilo. Un Servlet puede manejar múltiples peticiones de clientes.
3. Se llama al método service() para procesar la petición devolviendo el resultado al cliente.
4. Cuando se apaga el motor de un Servlet se llama al método destroy(), que lo destruye y libera los recursos abiertos.

Asi mismo un Servlet permite el acceso por medio de unos objetos, para el acceso al contexto de la aplicación.

-------------
ServletConfig
-------------

- Para el acceso al contexto actual de una aplicación Web corriendo en una JVM.
- Un ServletConfig por 'Servlet'.
- Es usado para el acceso al 'ServletContext'.
- Se accede al objeto mediante: getServletConfig().getInitParameter( "nombreParametro" );

--------------
ServletContext
--------------

- Para el acceso al contexto actual de una aplicación Web corriendo en una JVM.
- Usado para el acceso a la configuración de elemento deployado.
- Se acceder al objeto mediante: getServletContext().getInitParameter( "nombreParametro" );

El ejemplo preparador muestra una aplicación dividida en 2 partes:

La primera muestra un Login que valida un usuario y password, aqui se muestra el manejo de metodos como: doGet(), doPost(), service(), destroy(), etc.Mientras que el segundo ejemplo muestra el manejo de un muy útil ImageServlet.







Para mayor detalle descargar el ejemplo completo: AQUÌ.

viernes, 6 de noviembre de 2009

MANEJO DE 'WEB SERVICE' CON 'AXIS2'.

Hace un tiempo posteè sobre el manejo de Web Service con AXIS1, esta vez mostraré el manejo de Web Service (Su consumo) pero con AXIS2. Este Framework AXIS2 a diferencia de su versión anterior AXIS1 permite un mejor manejo de los Web Service Orientados a Objetos, ya que en la versión anterior de AXIS los Objetos del Service enviados como parámetros por el Web Service, se podían regenerar desde un cliente WS pero para poder parsearlos se necesita de forma obligada el número de serialVersionUID (Para poder comprobar que es el mismo objeto) , aquí AXIS1 era débil. AXIS2 supero eso ya que no tiene este traspié. AXIS2 solamente posee un problema al momento de la generación del cliente WS que mas adelante mostraremos y solucionaremos.

Al igual que el ejemplo posteado con AXIS1 mostraré la generación del Cliente WS y consumo de dichos procesos:

/********** PROCESOS 'WS' **********/
//Probando 'SUMA'.
clienteWS.getResultadoSuma( numero_01, numero_02, accesoWS );

//Probando 'RESTA'.
//clienteWS.getResultadoResta( numero_01, numero_02, accesoWS );

//Probando 'MULTIPLICACION'.
//clienteWS.getResultadoMultiplicacion( numero_01, numero_02, accesoWS );

//Probando 'DIVISION'.
//clienteWS.getResultadoDivision( numero_01, numero_02, accesoWS );

//Probando 'obtenerUsuario'.
//clienteWS.getObjetoUsuario( accesoWS );

//Probando 'obtenerListaUsuarios'.
//clienteWS.getListaUsuarios( accesoWS );;
/***********************************/

Los pasos son los siguientes:

1.- Tenemos el WSDL ya generado del servidor “UsuarioServiceImpl.wsdl” , este WSDL esta en la ruta: WebContent/wsdl/UsuarioServiceImpl.wsdl. En base a esta ruta generaremos por medio de consola el Cliente AXIS2, pero tendremos que configurar las variables de entorno antes.

2.- Bajarte la ultima versión de AXIS2: http://ws.apache.org/axis2/1_5_1/installationguide.html

3.- Ubicarla en una ruta en tu PC: “D:\JAVA\Axis\axis2-1.5.1”

4.- Registrar las variables de entorno (Tanto en Usuario como en Sistema):



5.- Generar el cliente AXIS2 desde consola aplicando el siguiente còdigo desde la ruta raiz del proyecto trabajado:

%AXIS2_HOME%/bin/WSDL2Java -p org.java.service -uri WebContent/wsdl/UsuarioServiceImpl.wsdl -s



6.- En este momento AXIS2 genera un error:

Es posible que cuando se desee generar un cliente JAVA con AXIS2 en base a un WSDL, uno encuentre con un error así:

Unexpected subelement 'XXXX'

Esto se debe a que AXIS2 genera el Cliente WS de una forma no totalmente correcta. Ya que confunde los NameSpaceURI. Supongamos como en este caso que el Servidor WS posee dos paquetes:

- PAQUETE DEL OBJETO: org.java.bean
- PAQUETE DEL WS: org.java.servidor.ws

Al momento de la generación del Cliente WS con AXIS2, los NameSpaceURI se invierten y quedan de la siguiente manera:

- NAMESPACE APUNTANDO AL OBJETO: “http://bean.java.org"
- NAMESPACE APUNTANDO AL WS: "http://ws.servidor.java.org"

Aquí esta el problema y la solución seria buscar la clase 'Stub' generada, en este caso 'ConsultaWSServiceStub' y en ella buscar por cada Objeto que se trabaje su:

static MY_OBJETO parse:

/**
* Factory class that keeps the parse method
*/
public static class Factory{

/**
* static method to create the object Precondition: If this object is an element, the
* current or next start element starts this object and any intervening reader events
* are ignorable If this object is not an element, it is a complex type and the reader
* is at the event just after the outer start element Postcondition: If this object is
* an element, the reader is positioned at its end element If this object is a complex
* type, the reader is positioned at the end element of its outer element
*/
public static Usuario parse( javax.xml.stream.XMLStreamReader reader ) throws java.lang.Exception{

Y cambiar el NameSpace para cada campo de > cada Objeto trabajado, de la siguiente forma:

AQUI SE DA EL 'ERROR':

while( !reader.isStartElement() && !reader.isEndElement() )
reader.next();
if( reader.isStartElement() &&
new javax.xml.namespace.QName( "http://bean.java.org", "nombre" ).equals( reader.getName() ) ){
nillableValue = reader.getAttributeValue( "http://www.w3.org/2001/XMLSchema-instance", "nil" );
if( !"true".equals( nillableValue ) && !"1".equals( nillableValue ) ){
java.lang.String content = reader.getElementText();
object.setNombre( org.apache.axis2.databinding.utils.ConverterUtil.convertToString( content ) );
}
else{
reader.getElementText(); // throw away text nodes if any.
}
reader.next();
} // End of if for expected property start element
else{
// A start element we are not expecting indicates an invalid parameter was
// passed throw new org.apache.axis2.databinding.ADBException( "Unexpected subelement " + reader.getLocalName() );
}

AQUI SE DA EL 'SOLUCION':

while( !reader.isStartElement() && !reader.isEndElement() )
reader.next();
if( reader.isStartElement() &&
new javax.xml.namespace.QName( "http://ws.servidor.java.org", "nombre" ).equals(
reader.getName() ) ){
nillableValue = reader.getAttributeValue( "http://www.w3.org/2001/XMLSchema-instance", "nil" );
if( !"true".equals( nillableValue ) && !"1".equals( nillableValue ) ){
java.lang.String content = reader.getElementText();
object.setNombre(
org.apache.axis2.databinding.utils.ConverterUtil.convertToString( content ) );
}
else{
reader.getElementText(); // throw away text nodes if any.
}
reader.next();
} // End of if for expected property start element
else{
// A start element we are not expecting indicates an invalid parameter was
// passed throw new org.apache.axis2.databinding.ADBException( "Unexpected subelement " + reader.getLocalName() );
}

7.- Creamos la clase: org/java/client/ClienteWS_Generado.java y vamos descomentando y ejecutando los procesos anteriormente nombrados uno por uno para probar su manejo. Recordar que primero se tiene que desplegar el demo del 'Proyecto Servidor' que es parte del demo posteado llamado: Ejemplo Web Service con JAX-WS , para poder probar sin problemas el Cliente WS con AXIS2.

Para mayor detalle descargar el ejemplo completo: AQUÌ.

jueves, 15 de octubre de 2009

MANEJO DE FECHAS CON JODA API

El manejo de Fechas en JAVA siempre a sido un poco molestoso ya que uno por muchos motivos tiende al manejo de dichas fechas de diferentes formas:

En String, Date, Calendar, GregorianCalendar, etc.

Y porque no hay un estándar en dicho manejo de fechas, las tendencias son siempre convertir formatear, reconvertir y volver a formatear para manipular los datos de un lado a otro. Bueno en esta oportunidad presento esta API Java que puede ayudar en algo dichos problemas ya que proporción objetos (No Deprecated) que son fáciles de manipular, que permiten muchas conversiones: StringToDate, DateToString, etc. y que con una sola línea te devuelve lo deseado, el API se llama JODA y aquí les comparto una clase JAVA donde muestro su manejo. El manejo es tan fácil como decir:

int anos = Years.yearsBetween( fechaInicio, fechaFin ).getYears();

Aquí maestro el resumen informativo de un demo en donde trabajo el cálculo de 2 fechas:


FECHA INICIO [DateTime]: 1983-01-04T00:00:00.000-05:00
FECHA FIN [DateTime]: 2009-10-15T14:23:30.093-05:00

FECHA INICIO [Date]: Tue Jan 04 00:00:00 COT 1983
FECHA FIN [Date]: Thu Oct 15 14:23:30 COT 2009

FECHA INICIO [Date MGT]: 4 Jan 1983 05:00:00 GMT
FECHA FIN [Date MGT]: 15 Oct 2009 19:23:30 GMT

FECHA INICIO [Date LOCALE]: 04-ene-1983 0:00:00
FECHA FIN [Date LOCALE]: 15-oct-2009 14:23:30

FECHA INICIO [Calendar]: java.util.GregorianCalendar[time=410504400000,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/Bogota",offset=-18000000,dstSavings=0,useDaylight=false,transitions=5,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=1983,MONTH=0,WEEK_OF_YEAR=1,WEEK_OF_MONTH=1,DAY_OF_MONTH=4,DAY_OF_YEAR=4,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=0,ZONE_OFFSET=-18000000,DST_OFFSET=0]

FECHA FIN [Calendar]: java.util.GregorianCalendar[time=1255634610093,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/Bogota",offset=-18000000,dstSavings=0,useDaylight=false,transitions=5,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2009,MONTH=9,WEEK_OF_YEAR=42,WEEK_OF_MONTH=3,DAY_OF_MONTH=15,DAY_OF_YEAR=288,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=2,HOUR_OF_DAY=14,MINUTE=23,SECOND=30,MILLISECOND=93,ZONE_OFFSET=-18000000,DST_OFFSET=0]

//VALIDANDO
[F.INICIO] ES ANTES [F.FIN]
[F.FIN] ES DESPUES [F.INICIO]


DATOS [FECHA INICIO]
--------------------
AÑO: 1983
AÑO DE LA CENTURIA: 83
AÑO DE LA ERA: 1983
MES DEL AÑO: 1
DIA DEL MES: 4
DIA DE LA SEMANA: 2
DIA DEL AÑO: 4
MINUTO DEL DIA: 0
MINUTO DE LA HORA: 0
SEGUNDO DEL DIA: 0
SEGUNDO DEL MINUTO: 0


DATOS [FECHA FIN]
-----------------
AÑO: 2009
AÑO DE LA CENTURIA: 9
AÑO DE LA ERA: 2009
MES DEL AÑO: 10
DIA DEL MES: 15
DIA DE LA SEMANA: 4
DIA DEL AÑO: 288
MINUTO DEL DIA: 863
MINUTO DE LA HORA: 23
SEGUNDO DEL DIA: 51810
SEGUNDO DEL MINUTO: 30

//OTROS DATOS
DIAS ENTRE [F.INICIO] & [F.FIN]: 9781
MESES ENTRE [F.INICIO] & [F.FIN]: 321
AÑOS ENTRE [F.INICIO] & [F.FIN]: 26
MINUTOS ENTRE [F.INICIO] & [F.FIN]: 14085503
SEGUNDOS ENTRE [F.INICIO] & [F.FIN]: 845130210


Para descargar El demo pulsar:
AQUÌ.

jueves, 8 de octubre de 2009

OBTENCIÒN DE DATOS DE XML CON XPATH Y JAVA

El otro dìa me encontre con un post que hablaba muy bien de un lenguaje de programaciòn para el ràpido acceso a datos embebidos en un fichero XML, este lenguaje se llama XPATH
y es una versiòn superior a otro conocido pero màs antiguo lenguaje llamado XQL, el cual su logica era en base a consultas tipo SQL acceder a los datos pero no de una BD sino de XML propiamente. XPATH heredò toda la sintaxis de este lenguaje como predecesor que es y le ha puesto varias mejoras. XPATH como lenguaje esta orientado a buscar información dentro de
documentos con esctructura en XML. Uno de sus ùnicos defectos que le he podido encontrar es que no se pueden realizar JOINs, pero se puede jugar con los datos obtenidos y cargar listas de datos por ejemplo de còdigos que pueden servir en entrada para la obtenciòn de datos de otra tabla (si lo orientamos a SQL por decir) y que finalmente da un resultado similar al de un JOIN. Este lenguaje es verdaderamente ràpido y lo mejor es que podemos trabajarlo simultaneamente con JAVA, ya que JAVA posee librerìas que soportan las consultas generadas con los XPATH Querys y por ser un lenguaje superior JAVA te permite lo anteiormente hablado de simular un JOIN cargando
listas y recorriendolas.

Al comienzo XPATH puede causar un poco de molestia, ya que su sintaxis no es SQL, pero poco a poco uno le agarra el truco, yo en medio dìa lo aprendì y para probarme que tan bien lo aprendì, busquè y encontre una muy buena WEB donde explican todo en Español sobre XPATH y posse un SIMULADOR donde te toman un TEST de sintaxis
que en base a preguntas y con un gran XML a tu costado, tienes que demostrar que sabes y codificar tu Query y comparar el resultado que tienes con el resultado correcto, que tambien se muestra al lado.

Los links son los siguientes:

- TUTORIAL: http://geneura.ugr.es/~victor/cursillos/xml/XPath
- FICHERO XML: http://geneura.ugr.es/~victor/cursillos/xml/XPath/ejercicios_xpath_xml.html
- SIMULADOR: http://geneura.ugr.es/~victor/cursillos/xml/XPath/ejercicios_xpath.html

Pero como este es un BLOG de JAVA, tenemos que hablar de JAVA, asi voy a mostrar la soluciòn de este simulador pero dentro de una aplicaciòn JAVA que yo mismo cree y que de paso muestra el facil manejo de lentura de XML que este XPATH con JAVA de manera conjunta hacen.

Para descargar la aplicaciòn demo pulsar:
AQUI.

SIMPLE XML FRAMEWORK 1.2

En esta oportunidad voy a hablar sobre un muy buen y potente Framework para manipulaciòn de ficheros XML. Este Framework se llama SIMPLE FRAMEWORK v1.2. Este framework a diferencia de todos los anteriores Frameworks de parseo de datos para ficheros XML que he utilizado previamente, los cuales trabajan para la obtencion de los datos recorriendo y recorreindo todos los XML muchas veces y que la verdad no es òptimo. Por ejemplo en mi trabajo los XML que manejamos son verdaderamente GIGANTES tanto asì que para su recorrido y obtenciòn de los datos podìan demorar unas 2 horas en algunos casos, algo realmente catastròfico. Bueno este framework viene para la salvaciòn de estos problemas, ya que su logica de trabajo esta orientada a la creaciòn y manipulaciòn de los XML pero con una Lògica Orientada a Objetos, ustedes diran como??, bueno para su trabajo se debe ter una seria de objetos (Beans) relacionados de la misma forma que uno quiere que su XML este formado (herendando, instanciando, etc) a tal punto de que cuando uno mande a generar el XML el framework lo genere de una forma excelente y en un màximo 10 lineas de còdigo y luego cuando se requiere acceder a los datos del XML, el mètodo respectivo que instancia el fichero XML automaticamente carga en memoria todo el XML y uno simplemente recorrerìa los objeto dentro de tu aplicacion via GET y obtendrìas los datos, todo un registro o una lista de registros de forma completa. Eso si este Framework trabaja con JAVA mìnimo 1.5, ya que manipula los beans con Anotaciones.

Aquì les comparto un completo ejemplo para mostrales la potencia de este Framework:
Descargar.

miércoles, 22 de julio de 2009

Integración JSF - IBATIS

Hola compañeros en esta oportunidad estoy posteando sobre este muy bonito Framework
llamado IBATIS, la verdad no muchos motivos no lo había utilizado antes, pero por necesidad de que el manejo de dicho framework es Standard en mi centro de trabajo, me dedique un par de días a investigar todo acerca de este framework y de di con la sorpresa de que es muy útil, rápido de configurar e integrar con otros frameworks a comparación de otros como Hibernate ( Aunque la verdad aun prefiero trabajar con Hibernate ). Este framework lo muy bueno que tiene es que las consultas SQL las realiza en un fichero .XML que esta necesariamente amarrado a un objeto del negocio y donde se mapearan todas las consultas relacionadas a las transacciones en donde este objeto este relacionado, las consultas están embebidas dentro de tags especiales del IBATIS que permiten recibir variables primitivas, variables de tipo clase y hasta objetos completos. Permite el uso de comodines para las consultas y parámetros dinámicos diferenciados por símbolos como el #, permite la reutilización de las consultas realizadas ( Llamado de un QUERRY a otro QUERRY ), para minimizar código, Manejo de Store Procedure, etc. Todo esto dentro de los mapeos y desde la implementación de cualquier DAO asignado simplemente se le llamaría por medio del nombre del ID el cual esta asignado al IBATIS tag que envuelve la consulta SQL respectiva, algo como lo que muestro pero empleado para distintos procesos CRUD:

• Integer estadoGuardar = (Integer)this.update( "nombreIdSQL", nombreMiObjeto );

• Usuario objUsuario = (Usuario)this.insert( "nombreIdSQL", nombreMiObjeto );

• Usuario usuario = (Usuario)queryForObject( "nombreIdSQL", codigo );

• List listaUsuario = (List)queryForList( "getListaUsuario", codigo );


Pensando en esto he visto la necesidad de hacer un aplicativo J2EE de ejemplo donde integro los Frameworks JSF y IBATIS. Es un ejemplo muy completo que se inicia con un login:

Usuario: rguerra
Password: 123

Y internamente es un mantenimiento completo de USUARIOS: Listado, Registro, Modificacion, Eliminacion (CRUD) y ademas le he agredado Filtros con comboBoxs y funcionalidad keyPress.

El aplicativo WEB esta realizado con Eclipse v3.3, bajo una plataforma JAVA v1.6 (Pero funciona tambien con la v1.5), IBATIS v2.1.6 y una motor datos MySql. El Script SQL se encuentra dentro del proyecto y viene con un Store Procedure incluido utilizado para el proceso de logín.

Aplicativo Ejemplo:

Login de la aplicacion..

Listado de Usuarios

Registro de Usuarios Nuevos de tipo 'Administrador'

Usuaio Nuevo Listado

Modificacion de Usuario Nuevo

Listado de Usuario Modificado

Eliminacion de Usuario Modificado

Listado de Usuarios Actuales


Para mayor detalle descargar el ejemplo completo: AQUI.