martes, 24 de agosto de 2010

Revelando el misterio de los Web Services en Java - Parte I

Al parecer el hecho de saber de web Services en Java es todo un lujo.. Existe poca información clara al respecto y por lo general los programadores java no saben por donde empezar cuando se les habla de web services. Es por la necesidad de tener información realmente útil y fácil de entender que nace este post .. Realmente considero que este artículo les va ser de mucha ayuda cuando requieran empezar con el uso de los Servicios Web en Java.

Personalmente aún no he tenido la oportunidad de participar en proyectos donde requieran el uso de los web services, con lo cúal aprendería mucho más del uso de estos.

Empezaremos este artículo viendo de forma general la gran importancia que tienen los Servicios Web.

Servicio Web.-  en inglés Web Service, es un conjunto de protocolos y estándares que sirven para intercambiar datos entre diferentes aplicaciones, pudiendo estar desarrolladas en distintos lenguajes de programación y siendo ejecutadas en diferentes plataformas.  En relación a ello nace el concepto de SOA (Arquitectura Orientada a Servicios).


ws.png

Pues bien, una vez conocida la definición empezaremos a implementarlo en Java. Es en este punto en donde empiezan nuestras interrogantes.
  •  ¿Es mejor AXIS2 o JAXWS?
  • ¿Cómo genero el ws a partir del wdsl o de las clases Java?
  • ....
Pues bien empezaremos a resolver nuestras dudas.

Con respecto a a nuestra primera interrogante de ¿Qué elegir, Axis2 o JAXWS?

Empezaremos haciendo una comparativa entre los frameworks que podemos utilizar para el desarrollo de un ws, ya sea Axis2 o JAXWS. Existen otras opciones pero son poco conocidas aún.

Ventajas  y desventajas del uso de ambos:

  • Con Axis2 necesitamos tener instalado al menos la versión 1.4 del jdk, mientras que para JAXWS al menos necesitamos la versión 1.5 como mínimo. Este puede ser un factor determinante, en el caso de que nuestro servidor de aplicaciones utilice la versión 1.4 y no podamos migrar a una versión posterior.

  • Si generamos el WS a partir de las clases Java, no existen muchas diferencias entre una y otra solución.Aunque el archivo .wsdl que genera Axis2 es bastante engorroso y complicado de analizar (hay que tenerlo en cuenta a la hora de que alguien tenga que crear una aplicación cliente que se conecte a nuestro WS a partir del wsdl que nosotros le proporcionemos).

  • Si la estructura de los mensajes SOAP es más compleja, o deseas generar tu mismo el wsdl para tener más control sobre los mensajes SOAP (cosa que se recomienda), es preferible utilizar JAXWS. El código que genera Axis2 es realmente “infumable”. Genera clases hasta por las puras clases de estilo clase_1, clase_2, así como un montón de clases anidadas. No sé si todo esto habrá cambiado en las versiones posteriores, pero desde luego en la versión que conosco(1.3), la legibilidad y reutilización del código era penosa. El código generado esta lleno de warnings. En fin todo bastante engorroso. Sin embargo en JAXWS, al utilizar anotaciones, todo queda mucho más límpio y claro. Desde luego, este punto es el que me hizo preferir JAXWS antes que Axis2.

  • JAXWS al ser de Sun, podríamos decir que es más estandar que Axis2 que es de Apache
En conclusión, recomiendo usar JAX-WS a menos de que el servidor tenga la versión 1.4.x del jdk y no se pueda migrar, en dicho caso es recomendable usar Axis2. Sin embargo, si el servidor tiene 1.5.x o superior de jdk no existe mejor opción que usar JAX-WS.
Para descargar Axis2 visitar : apache.org/axis2
Para descargar JAX-WS visitar: jax-ws.dev.java.net

Este post continuará ....

lunes, 16 de agosto de 2010

Cambiando el Skin (Look & Feel) a nuestros aplicativos Java

Otra vez vuelvo al ruedo .. estos últimos meses me he encontrado saturado a causa de la Universidad. Pues bien, ahora cuento con algo de tiempo y me he decidido por publicar un nuevo artículo, esta vez trataré sobre el uso de skins en aplicativos Java.
Esto a partir del proyecto que presentamos con unos amigos en la U,que a manera de anécdota lo programamos 2 personas en 4 días .. dejando, como siempre, todo para el final xD.

Volviendo a nuestro tema principal, empezaremos definiendo skin, luego mostraremos una serie de Screenshots de como se vería nuestro aplicativo java aplicandoles otros skins y por último la implementación.

Skin.- También llamado theme, tema o tapiz, son una serie de elementos gráficos que, al aplicarse sobre un determinado software, modifican su apariencia visual externa.
Estos elementos son independientes de la propia aplicación, con lo que esta puede tener, entre sus opciones, varias de estas pieles o ninguna, mostrando una apariencia estándar o más vistosa.

Diseño Visual Común de Java Swing

uni1.png

El diseño visual por default de una aplicación Java es la siguiente.





















Pero esta no es la única forma de presentar tu aplicativo Java Swing. Existen también las siguientes formas y muchas otras más:


Implementación:
En esta ocasión haremos que nuestra aplicación tome la apariencia del uso de Mac. Para que quede de la siguiente manera:
uni2.png


Se ve mucho mejor no...
Pues ahora explicaremos los pasos para llevarlo a cabo.
Primero tenemos que descargar la librería (.jar) liquidlnf
Segundo añadir la librería liquidlnf.jar a nuestra aplicación.
Por último, modificar el Main de nuestra aplicación de la siguiente forma.


package pedro.rios.main;

import com.birosoft.liquid.LiquidLookAndFeel;
import javax.swing.UIManager;

/**
 *
 * @author Pedro.Rios
 * @date 16/08/10
 */
public class Main{

   public static void main(String[] args) {
       try {
            //líneas para el cambio visual
            UIManager.setLookAndFeel("com.birosoft.liquid.LiquidLookAndFeel");
            LiquidLookAndFeel.setLiquidDecorations(true, "panther");
            //LiquidLookAndFeel.setShowTableGrids(true);

            Principal tuFrame= new Principal();
            tuFrame.setVisible(true);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

/*
Para Otros temas:
swing.installedlafs = motif,windows,metal,mac,liquid
swing.installedlaf.motif.name = CDE/Motif
swing.installedlaf.motif.class = com.sun.java.swing.plaf.motif.MotifLookAndFeel
swing.installedlaf.windows.name = Windows
swing.installedlaf.windows.class = com.sun.java.swing.plaf.windows.WindowsLookAndFeel
swing.installedlaf.metal.name = Metal
swing.installedlaf.metal.class = javax.swing.plaf.metal.MetalLookAndFeel
swing.installedlaf.mac.name = Mac
swing.installedlaf.mac.class = com.sun.java.swing.plaf.mac.MacLookAndFeel
swing.installedlaf.liquid.name = Liquid
swing.installedlaf.liquid.class = com.birosoft.liquid.LiquidLookAndFeel
swing.defaultlaf=com.birosoft.liquid.LiquidLookAndFeel
*/


Ahora podemos apreciar lo fácil que es.. xD .. 2 líneas y listo. Espero les sirva para su desarrollo, se despide de ustedes y hasta la próxima publicación .... edisonjc7.

Demo Completa

miércoles, 30 de junio de 2010

Interceptores con Spring AOP

Hola a todos de nuevo.. estos días me he encontrado bastante ocupado por los parciales en la U y viendo trámites para sacar mi licencia de conducir (brevete) que ia sale :d. Ahora que todo está tranquilo en el trabajo me he animado por escribir un poco más acerca de Spring AOP, en este caso con sus Interceptores.  Estoy también analizando las propuestas que hacen en sus comentarios para futuros post.

Bueno había ya realizado un artículo en donde explicaba la forma de realizar métodos transaccionales con Spring AOP en transacciones-con-hibernate-y-Spring-AOP .
Ahora más bien veremos de lo que se tratan los interceptores y su utilidad en la bitácora de las aplicaciones en conjunto con log4j. Para empezar teóricamente definiremos el concepto de interceptor.


AOP son las siglas en ingles de Programación orientada al aspecto (Aspect Oriented Programming). Además, como sabemos la definición más simple de AOP es “una manera de eliminar codigo duplicado”. Un ejemplo práctico para la utilidad del AOP, es generar un interceptor, que inspeccionará el codigo que se va a ejecutar, permitiendo por lo tanto realizar ciertas acciones como : trazas cuando el método es llamado (bitácora), modificar los objetos devueltos o envio de notificaciones.


¿Qué es un interceptor?

Vimos hasta ahora que con Spring podemos delegar la creación de objetos, e inyectarles dependencias. Además, sabemos que usamos interfaces para castear los objetos que nos devuelve o inyecta Spring, de forma tal de poder lograr una real independencia de las implementaciones.
¿Qué pasaría entonces si, en tiempo de ejecución, se pudieran crear clases que intercepten los llamados y realicen acciones adicionales? Es decir, el poder agregar comportamiento en tiempo de ejecución, sin tocar el código.
Este es el concepto de los interceptores. Un interceptor es una clase que cumple con cierta interfaz, y su objetivo es "interponerse" en la ejecución de un método. Así, un interceptor es capaz de ejecutarse antes de un método dado, realizar acciones, y luego continuar con la ejecución normal (o abortarla).
Este tipo de concepto se conoce como Programación Orientado a Aspectos.

Un interceptor muy útil, por ejemplo, podría ser de log: algo que intercepte todas las llamadas a los objetos de Negocio y deje registrado la hora de la invocación, los parámetros, el valor de retorno, etc.


Configurando Nuestro Interceptor
Para configurar el Spring AOP con interceptor, nuestra aplicación deberá contar con las siguientes librerías:
  • spring.jar
  • log4j-1.2.14.jar
  • commons-logging-1.1.jar
  • cglib-2.1.jar
  • aopalliance.jar
  • aspectjrt.jar
  • aopalliance.jar
Todos estos y algunos más los puedes obtener en la siguiente dirección  download lib .

Configurando el applicationContext.xml

<beans xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
              ">
 
<!-- *********** INI :  DATASOURCE CONFIGURATION ************ -->    
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="/WEB-INF/jdbc.properties"/>
    </bean>
    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">        
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>       
    </bean>   

 <!-- *********** INI : IBATIS CONFIGURATION  ************* -->   
   
     <!-- SqlMap setup for iBATIS Database Layer -->
    <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="configLocation">
            <value>classpath:/gob/minedu/capacitacion/persistency/ibatis/sql-map-config-cxa.xml</value>
        </property>
        <property name="dataSource"><ref local="dataSource"/></property>     
    </bean> 

<!-- ************ INI: INTERCEPTOR DAO  ************** -->
<aop:config  proxy-target-class="true"> 
      <aop:pointcut id="businessOperation" expression="execution(* gob.minedu.capacitacion.*.dao.ibatisImpl.*.*(..))"/>
      <aop:advisor advice-ref="logInterceptor" pointcut-ref="businessOperation"/> 
</aop:config>

<bean id="logInterceptor" class="gob.minedu.shared.common.util.LogInterceptor"/>

<import resource="application-service.xml"/>

</beans>

Explicaremos lo relevante para este artículo.. las otras partes del applicationContext.xml han sido explicadas en anteriores artículos. Analizando la configuración del interceptor.

  • En vista de que no existe un TransactionManager es necesario poner proxy-target-class="true".

  • aop:pointcut : Punto de corte definido por patrones de nombres o expresiones regulares. La estructura de la expresión depende de la estructura de nuestra aplicación.

  • aop:advisor advice-ref="logInterceptor", referencia a la clase que implementa el aspecto. Se insertan en la aplicación en los Puntos de Corte.
Implementación de la clase interceptora LogInterceptor.java

package gob.minedu.shared.common.util;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;


/**
 * @author Pedro.Rios
 *
 */
public class LogInterceptor implements MethodInterceptor {
 private static final Logger log = Logger.getLogger(LogInterceptor.class);
 
 public Object invoke (MethodInvocation metodo) throws Throwable {
  
 log.debug("INI DAO: Clase Invocada "+metodo.getMethod().getDeclaringClass().getSimpleName() +" Metodo solicitado "+metodo.getMethod().getName());
 
 //Generamos la lista de argumentos que recibe el metodo separados por una coma   
    String arguments = new String();               
    for (int i = 0; i < metodo.getArguments().length; i++) {   
        arguments += metodo.getArguments()[i] + " ,";                
    }   
       
    // el metodo recibe al menos un argumento quitamos el espacio y la coma del final   
    if (arguments.length()> 0) {   
        arguments = arguments.substring(0, arguments.length() - 2);   
    }   
    log.debug("Argumentos: "+arguments);
 
 Object obj = metodo.proceed();
 log.debug ("FIN DAO: El método ha devuelto : "+obj);
 return obj;
 }
}
Definición del archivo log4j.properties
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.stdout.threshold=DEBUG

log4j.logger.org.ibatis=INFO
log4j.logger.org.apache=INFO
log4j.logger.org.springframework=INFO

#Sql: log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Connection=INFO
#Resultado sql: log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.ResultSet=INFO

Si no sabes como configurar el log4j y donde ubicar el archivo.properties puedes ver el web.xml del artículo  http://periospino.blogspot.com/2010/03/integrando-struts-spring-ibatis.html 
Con eso es suficiente para integrar Spring con Log4j.
De todas formas ya se viene un artículo explicando al detalle el uso de Log4j.

Para mayor informacíón:

Bueno amigos me despido y hasta la próxima publicación... Espero sus comentarios.