Como todo buen framework, para trabajar con Spring deberemos de descargarnos un archivo comprimido y luego extraer de él las librerias necesarias para utilizarlo.
En el primero de los vínculos que se muestran al final de esta entrada, podremos observar una interfaz, una implementación de esta interfaz, el archivo xml que especificará como inicializar o configurar nuestros objetos cuando queramos llamarlos y por último el programa cliente que utiliza estás clases.
Se muestran otras cosas entre ellas una conexión a base de datos y otro ejemplo de RMI.
Explica también que significa claramente la Inversion of Control (IoC), Spring está basado en una inyección de dependencia (Dependency Injection) del tipo IoC. No conectamos directamente nuestros componentes y servicios juntos en el código, describimos que servicios necesita cada componente en un archivo de configuración. Un contenedor es responsable de vincularlos.
Bean Factory, una implementación del patron de diseño y tiene como objeto crear y proveer beans. Tiene la posibilidad de crear asociaiones entre objetos que colaboran entre sí, al ser instanciados. Existen varias implementaciones del BeanFactory, una de ellas por ejemplos es aquella que lee un archivo de configuración xml y carga los beans. Luego se piden los Beans con un método getBean() del objeto BeanFactory.
MyBean bean= (MyBean)factory.getBean("MyBean");
Tres buenos tutoriales en estos vínculos:
http://www.roseindia.net/spring/index.shtml
http://www.visualbuilder.com/java/spring/tutorial/
http://www.programacion.net/tutorial/jap_jsfwork/
23 may 2008
21 may 2008
Spring
¿Que es?
Spring es un framwork para desarrollo de aplicaciones Empresariales, facilitandoel desarrollo de aplicaciones EJB creado por Rob Johnson.
¿Que puede hacer?
Configurar Servicios Declarativos,
Acceso remoto bajo RMI o servicios web,
Enviar de correos,
Persistir datos.
Todo esto de manera modular, solo integraremos lo que es necesario en nuestra aplicación.
¿Cuales son los conceptos básicos?
No requiere tanto código para generar aplicaciones empresariales, y permite al programador enfocarse en código de negocios.
Spring es un framwork para desarrollo de aplicaciones Empresariales, facilitandoel desarrollo de aplicaciones EJB creado por Rob Johnson.
¿Que puede hacer?
Configurar Servicios Declarativos,
Acceso remoto bajo RMI o servicios web,
Enviar de correos,
Persistir datos.
Todo esto de manera modular, solo integraremos lo que es necesario en nuestra aplicación.
¿Cuales son los conceptos básicos?
- Dependency Injection o Inversion of Control (IoC) .- Un "design pattern", permite modular nuestro sistema, realizando cambios en una área sin afectar a otra.
- Aspect Oriented Programming (AOP) .- Reducción de duplicados entre clases, los interceptores posibilitan la ejecución de código antes o después de ciertos fragmentos ejecutados, muy útil para debug, logging y seguridad, EHCache y rastreo del rendimiento de la aplicación.
- Manejador de Transacciones .- Spring provee de una capa generica de abstracción para los manejadores de transacciones. Facilitando el lidiar con aspectos de bajo nivel y no está atada a una cada JEE.
- Manejo de Excepciones JDBC.- Ofrece una jerarquia de excepciones, que simplifica la estrategia de manejo de errores.
- Integración con Hibernate, JDO e iBATIS.
- Framework AOP.
- Framework MVC.- Configurable, y se ajusta a muchas tecnologías de vista (JSP, Velocity, Tiles, iText y POI) y otros muchos pueden ser integrados en lugar del framework.
- Spring AOP.- Servicios declarativos.
- Spring ORM.- Capa de integración con acceso a BD y mapeadores objeto-relacional.
- Spring Web.- Incluye el framework Spring MVC.
- Spring DAO.- Estandariza el acceso a datos usando tecnologías como Hibernate, JDBC o JDO.
- Spring Context.- Soporte para fuentes de mensajes y el "Observer dessing pattern".
- Spring Web MVC.-Provee implementación para la aplicación web.
- Spring Core.- Nucleo, incluye el IoC y un Bean Factory con un patron que separa la creación, inicilaización y acceso a datos.
No requiere tanto código para generar aplicaciones empresariales, y permite al programador enfocarse en código de negocios.
20 may 2008
Hibernate
Hibernate es el ORM (Object-Relational Mapping / Mapeo Objeto-Relacional) más utilizado en el mundo Java, aunque .Net también tiene su versión de Hibernate. Este framework permite que nuestros objetos Javas sean persistentes de una manera sencilla, evitandonos usar los DAO (Data Access Object / Objetos de Acceso a Datos) que se encargan de guardarse en la base de datos por si mismo, separando sus atributos, formateandolos y para recuperarlos lo mismo, pero a la inversa, lo cual se ha llegado a cuantificar en un 30% de código solo para la persistencia de objetos.
Hibernate permite el ahorro de codificación, a cambio de un poco de retardo del sistema en tiempo de ejecución, no todo es miel sobre hojuelas, sin embargo, este tiempo es pequeñisimo de cualquier forma.
La manera en que Hibernate mapea los objetos para guardar sus datos en una base de datos no es tan complicado, en base a un archivo de mapeo (con terminación .hbm.xml) se indican se indica la relación entre un atributo y una columna en la tabla de la base de datos, opcionalmente se especifica el tipo de dato entre otras opciones. Lo que es necesario para la consistencia es la llave primaria, en un objeto sencillo no hay necesidad de esto, pero en el modelo relacional de base de datos sí. Lo que podemos indicar es un atributo del objeto como llave primaria y general el dato nosotros o permitir que Hibernate lo genere por nosotros, existen varias opciones aquí, como por ejemplo, generado por usuario, por fecha, secuencial, etc.
Aquí un ejemplo de una clase simple, esta clase debe tener métodos getters y setters, un Java Bean de lo más normal, además de un constructor sin argumentos:
Y su archivo de mapeo, mensaje.hbm.xml (el nombre es opcional, pero es una buena medida el indicar el mismo nombre que el de la clase que mapea):
Primero observamos la cabezera general de un archivo xml.
Luego aparace la etiqueta hibernate mapping, la raíz de nuestro archivo.
Luego varias tags:
class: Indica la clase que vamos a mapear con todo y su paquete y el nombre de la tabla de la base de datos.
id: Aquí damos la especificación de la llave de la tabla, en el ejemplo eleguimos el atributo id de nuestra clase e indicamos que será mapeado al campo id (del mismo nombre, no hay problema) y del tipo long.
generator: Dentro del indicador de llave primaria, indicamos como será formada la llave, en este caso increment genera un número secuencial en la tabla para cada registro insertado.
proprety: Para cada uno de los atributos extras. No solo se manejan tipos simples, también pueden ser indicados objetos, esto se verá en otra entrada del blog.
many-to-one: Es el tipo de relación que se guarda con otras tablas, o en este caso, con ella misma. Se indica el atributo y el campo de la tabla y en este caso el tipo de relación es de cascada, que significa el tipo de acción de relación en cascada.
Listo, esto se repetira para cada clase con persistencia en nuestro sistema.
Ahora el archivo que nombraré como maestro de configuración de Hibernate, el hibernate.cfg.xml.
Un archivo de configuración que especifica la configuración del driver, la conexión con la base de datos, los formatos de conexión, los dialectos con que se comunica el sistema con la base de datos, extras y los archivos de mapeo. Este archivo debe encontrarse en el classpath.
Si ya se han utilizado conexiones con base de datos, la mayoría de las líneas serán muy explicativas por si mismas, la primera indica el driver que utilizamos para la conexión, el segundo, el url, la url formada por jdbc : el manejador de base de datos que usamos : abreviación : especificaciones de conexión, investigar la url que debes escribir de acuerdo a tu manejador no debe ser difícil con Google. Seguidamente el usuario y el password para conectarnos. También podemos indicar que se muestre en consola el sql que genera hibernate para realizar sus operaciones. Los demás son especificaciones, si vemos hay un update, indicando una actualización automatica de los objetos que una vez guardados cambian sus valores en el sistema. Por último, todos y cada uno de los .hbm.xml que ya creamos para nuestras clases. Este archivo también puede venir en sabor .properties.
Por último, el código Java que hace uso del objeto Java y que lo persiste:
Hay un número importante de conceptos/objetos aquí:
Configuration: Encargado del arranque de Hibernate, se sirve del hibernate.cfg.xml para inicializar la conexión y levantar todo Hibernate.
SessionFactory: Nuestro generador de sesiones con la base de datos, estás son caras de establecer, pero son reutilizables, además de permitirnos conectarnos con otras base de datos al mismo tiempo.
Session: La sesión activa al momento, sobre la cual guardaremos, recuperaremos, consultaremos, etc.
Transaction: Operaciones atómicas, esto es opcional, pero yo he tenido problemas cuando no la utilizo, todo lo que se hace dentro de un beginTransaction y un commit, o se hace todo o no se hace nada.
Hibernate permite el ahorro de codificación, a cambio de un poco de retardo del sistema en tiempo de ejecución, no todo es miel sobre hojuelas, sin embargo, este tiempo es pequeñisimo de cualquier forma.
La manera en que Hibernate mapea los objetos para guardar sus datos en una base de datos no es tan complicado, en base a un archivo de mapeo (con terminación .hbm.xml) se indican se indica la relación entre un atributo y una columna en la tabla de la base de datos, opcionalmente se especifica el tipo de dato entre otras opciones. Lo que es necesario para la consistencia es la llave primaria, en un objeto sencillo no hay necesidad de esto, pero en el modelo relacional de base de datos sí. Lo que podemos indicar es un atributo del objeto como llave primaria y general el dato nosotros o permitir que Hibernate lo genere por nosotros, existen varias opciones aquí, como por ejemplo, generado por usuario, por fecha, secuencial, etc.
Aquí un ejemplo de una clase simple, esta clase debe tener métodos getters y setters, un Java Bean de lo más normal, además de un constructor sin argumentos:
public class Mensaje {
private Long id;
private String mensaje;
private Mensaje siguiente;
public Mensaje(){}
public Mensaje(String s){
mensaje=s;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getMensaje() {
return mensaje;
}
public void setMensaje(String mensaje) {
this.mensaje = mensaje;
}
public Mensaje getSiguiente() {
return siguiente;
}
public void setSiguiente(Mensaje siguiente) {
this.siguiente = siguiente;
}
}
Y su archivo de mapeo, mensaje.hbm.xml (el nombre es opcional, pero es una buena medida el indicar el mismo nombre que el de la clase que mapea):
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//hibernate/hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="Mensaje" table="MENSAJES">
<id name="id" column="id" type="long">
<generator class="increment"/>
</id>
<property name="mensaje" column="mensaje"/>
<many-to-one name="siguiente" cascade="all" column="siguiente"/>
</class>
</hibernate-mapping>
Primero observamos la cabezera general de un archivo xml.
Luego aparace la etiqueta hibernate mapping, la raíz de nuestro archivo.
Luego varias tags:
class: Indica la clase que vamos a mapear con todo y su paquete y el nombre de la tabla de la base de datos.
id: Aquí damos la especificación de la llave de la tabla, en el ejemplo eleguimos el atributo id de nuestra clase e indicamos que será mapeado al campo id (del mismo nombre, no hay problema) y del tipo long.
generator: Dentro del indicador de llave primaria, indicamos como será formada la llave, en este caso increment genera un número secuencial en la tabla para cada registro insertado.
proprety: Para cada uno de los atributos extras. No solo se manejan tipos simples, también pueden ser indicados objetos, esto se verá en otra entrada del blog.
many-to-one: Es el tipo de relación que se guarda con otras tablas, o en este caso, con ella misma. Se indica el atributo y el campo de la tabla y en este caso el tipo de relación es de cascada, que significa el tipo de acción de relación en cascada.
Listo, esto se repetira para cada clase con persistencia en nuestro sistema.
Ahora el archivo que nombraré como maestro de configuración de Hibernate, el hibernate.cfg.xml.
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//hibernate/hibernate Configuration DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="hibernate.connection.url">jdbc:hsqldb:hsql://localhost/testdb</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password"></property>
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>
<property name="show_sql">true</property>
<property name="transaction.factory_class">
org.hibernate.transaction.JDBCTransactionFactory
</property>
<property name="hibernate.cache.provider_class">
org.hibernate.cache.HashtableCacheProvider
</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping resource="Mensaje.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Un archivo de configuración que especifica la configuración del driver, la conexión con la base de datos, los formatos de conexión, los dialectos con que se comunica el sistema con la base de datos, extras y los archivos de mapeo. Este archivo debe encontrarse en el classpath.
Si ya se han utilizado conexiones con base de datos, la mayoría de las líneas serán muy explicativas por si mismas, la primera indica el driver que utilizamos para la conexión, el segundo, el url, la url formada por jdbc : el manejador de base de datos que usamos : abreviación : especificaciones de conexión, investigar la url que debes escribir de acuerdo a tu manejador no debe ser difícil con Google. Seguidamente el usuario y el password para conectarnos. También podemos indicar que se muestre en consola el sql que genera hibernate para realizar sus operaciones. Los demás son especificaciones, si vemos hay un update, indicando una actualización automatica de los objetos que una vez guardados cambian sus valores en el sistema. Por último, todos y cada uno de los .hbm.xml que ya creamos para nuestras clases. Este archivo también puede venir en sabor .properties.
Por último, el código Java que hace uso del objeto Java y que lo persiste:
import java.util.Iterator;
import java.util.List;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;
public class Raiz {
private static SessionFactory sessionFactory;
private static Session session;
private static Transaction tx;
public static void elDos(){
Mensaje message =
(Mensaje) session.load( Mensaje.class, new Long(1) );
message.setMensaje("Saludos terricolas");
Mensaje nextMessage = new Mensaje("Llevenme con su lider (por fis)");
message.setSiguiente( nextMessage );
}
public static void elUno(){
Mensaje message = new Mensaje("Hola Mundo");
session.save(message);
}
public static void revisar(){
List messages = session.createQuery("from Mensaje as m order by m.mensaje asc").list();
System.out.println( messages.size() + " message(s) found:" );
for ( Iterator iter = messages.iterator(); iter.hasNext(); ) {
Mensaje message = (Mensaje) iter.next();
System.out.println( message.getMensaje() );
}
}
public static void main(String[] args) {
Raiz instance = new Raiz();
try {
System.out.println("Iniciando Hibernate");
sessionFactory = new Configuration().configure().buildSessionFactory();
session = sessionFactory.openSession();
tx = session.beginTransaction();
elUno();
//elDos();
revisar();
tx.commit();
session.close();
System.out.println("Finalizando");
} catch (HibernateException e) {
e.printStackTrace();
}
}
}
Hay un número importante de conceptos/objetos aquí:
Configuration: Encargado del arranque de Hibernate, se sirve del hibernate.cfg.xml para inicializar la conexión y levantar todo Hibernate.
SessionFactory: Nuestro generador de sesiones con la base de datos, estás son caras de establecer, pero son reutilizables, además de permitirnos conectarnos con otras base de datos al mismo tiempo.
Session: La sesión activa al momento, sobre la cual guardaremos, recuperaremos, consultaremos, etc.
Transaction: Operaciones atómicas, esto es opcional, pero yo he tenido problemas cuando no la utilizo, todo lo que se hace dentro de un beginTransaction y un commit, o se hace todo o no se hace nada.
12 may 2008
Junit
Usando la versión 4.4 de JUnit, me he dedicado a investigar lo que este framework puede hacer.
Resumidamente JUnit es una herramienta para realizar pruebas de nuestras clases Java.
Las clases que se crean extendiendo a junit.framework.TestCase serán el lugar donde probaremos nuestras ya creadas clases. No se tiene que modificar la clase que se prueba, y se dice que es una excelente práctica el ubicar nuestras clases de prueba (casos de prueba) en el mismo paquete en el que se encuentran las clases a las que probaremos, aunque algunos la ubican en un diferente paquete, ganando organización, pero perdiendo la posibilidad de utilizar los métodos protegidos por el ámbito de paquete.
Entonces, un caso de prueba, es una clase que tiene como función encontrar errores de otra, regularmente los casos de prueba se nombran con el nombre de la clase a probar y el sufijo Test. Así, para probar la clase ProveedorCafe.java, llamaremos a la clase: ProveedorCafeTest, no es una regla ni es necesario para hacer funcionar la prueba, pero si es una convención.
Un caso de prueba realizará todo el montón de comprobaciones sobre los métodos de la clase que se está probando. Realmente todo lo que podemos hacer es que comprobar que los métodos regresen el valor esperado después de una serie de instrucciones controladas, esto es, después de indicarle a un método que regrese la suma de dos números (2+2), que su resultado sea 4. Lo hacemos por medio de comprobaciones assertXxx, a las que llamamos expresiones de prueba. Por ejemplo:
assertEquals(sumar2Numeros(2,2),4);
Más adelante mostraremos la ubicación de está expresión de prueba en la clase, lo importante es comprender que la clase TestCase, de la cual extendemos y creamos nuestros casos de prueba, contiene una buena cantidad de expresiones de prueba, para verificar que un método regresa Verdadero o Falso, que dos objetos son o no iguales (recordar reescribir el método equals), etc.
No solo funciona con métodos, con cualquier expresión valida de Java.
Las expresiones se encontrarán en métodos que inician con el prefijo test y el nombre de un testtestAgregarDatos.
Un ejemplo completo a continuación:
Un ejemplo donde solo hacemos uso de un tipo de expresión de prueba, pero observamos que tiene un mensaje. Este mensaje será el que se muestre si la expresión no es evaluada como se espera, en este caso, que ambos datos sean iguales. Se espera que clase receta sea creada con los valores que le damos y que no exista nada en esta secuencia de instrucciones que nos indique que no fue así.
Los métodos setUp() y tearDown() son como el constructor y destructores de la clase, serán siempre llamados para cada prueba de un método en un caso de prueba. Esto es, aquí podemos inicializar nuestros objetos y no repetir código (cada método testXXX reinicia las variables de instancia).
Eclipse trae ya integrada la compatibilidad con JUnit, bastará con correr el programa como UnitTest.
Si las pruebas son demasiadas y hay muchas clases para probar, pero en el futuro no las probaremos todas, existen las TestSuite que son las clases encargadas de correr un conjunto de Casos de prueba, esto es meramente organizacional, pero nos permite organizar un conjunto de pruebas en un solo archivo java y mandar llamar a todas las pruebas, evitando hacerlo unitariamente.
Tan simple como un contenedor de Casos de Prueba. Y este contenedor, tiene la capacidad de absorver a otros contenedores de casos de prueba y llamarlos a todos de una sola vuelta y estos serán los encargados de verificar la clase.
Resumidamente JUnit es una herramienta para realizar pruebas de nuestras clases Java.
Las clases que se crean extendiendo a junit.framework.TestCase serán el lugar donde probaremos nuestras ya creadas clases. No se tiene que modificar la clase que se prueba, y se dice que es una excelente práctica el ubicar nuestras clases de prueba (casos de prueba) en el mismo paquete en el que se encuentran las clases a las que probaremos, aunque algunos la ubican en un diferente paquete, ganando organización, pero perdiendo la posibilidad de utilizar los métodos protegidos por el ámbito de paquete.
Entonces, un caso de prueba, es una clase que tiene como función encontrar errores de otra, regularmente los casos de prueba se nombran con el nombre de la clase a probar y el sufijo Test. Así, para probar la clase ProveedorCafe.java, llamaremos a la clase: ProveedorCafeTest, no es una regla ni es necesario para hacer funcionar la prueba, pero si es una convención.
Un caso de prueba realizará todo el montón de comprobaciones sobre los métodos de la clase que se está probando. Realmente todo lo que podemos hacer es que comprobar que los métodos regresen el valor esperado después de una serie de instrucciones controladas, esto es, después de indicarle a un método que regrese la suma de dos números (2+2), que su resultado sea 4. Lo hacemos por medio de comprobaciones assertXxx, a las que llamamos expresiones de prueba. Por ejemplo:
assertEquals(sumar2Numeros(2,2),4);
Más adelante mostraremos la ubicación de está expresión de prueba en la clase, lo importante es comprender que la clase TestCase, de la cual extendemos y creamos nuestros casos de prueba, contiene una buena cantidad de expresiones de prueba, para verificar que un método regresa Verdadero o Falso, que dos objetos son o no iguales (recordar reescribir el método equals), etc.
No solo funciona con métodos, con cualquier expresión valida de Java.
Las expresiones se encontrarán en métodos que inician con el prefijo test y el nombre de un testtestAgregarDatos.
Un ejemplo completo a continuación:
import junit.framework.TestCase;
public class RecetaTest extends TestCase {
public Receta rec;
public void setUp() {
rec=new Receta();
}
public void testCreation(){
rec.setName("Chocolate");
rec.setPrice(50);
rec.setAmtCoffee(6);
rec.setAmtMilk(4);
rec.setAmtSugar(2);
rec.setAmtChocolate(4);
System.out.println("Verificando entrada de datos validos");
assertEquals("Datos no iguales", rec.getPrice(),50);
assertEquals("Datos no iguales", rec.getAmtCoffee(),6);
assertEquals("Datos no iguales", rec.getAmtMilk(),4);
assertEquals("Datos no iguales", rec.getAmtChocolate(),4);
assertEquals("Datos no iguales", rec.getAmtSugar(),2);
}
public void tearDown(){
rec=null;
}
}
Un ejemplo donde solo hacemos uso de un tipo de expresión de prueba, pero observamos que tiene un mensaje. Este mensaje será el que se muestre si la expresión no es evaluada como se espera, en este caso, que ambos datos sean iguales. Se espera que clase receta sea creada con los valores que le damos y que no exista nada en esta secuencia de instrucciones que nos indique que no fue así.
Los métodos setUp() y tearDown() son como el constructor y destructores de la clase, serán siempre llamados para cada prueba de un método en un caso de prueba. Esto es, aquí podemos inicializar nuestros objetos y no repetir código (cada método testXXX reinicia las variables de instancia).
Eclipse trae ya integrada la compatibilidad con JUnit, bastará con correr el programa como UnitTest.
Si las pruebas son demasiadas y hay muchas clases para probar, pero en el futuro no las probaremos todas, existen las TestSuite que son las clases encargadas de correr un conjunto de Casos de prueba, esto es meramente organizacional, pero nos permite organizar un conjunto de pruebas en un solo archivo java y mandar llamar a todas las pruebas, evitando hacerlo unitariamente.
import junit.framework.Test;
import junit.framework.TestSuite;
public class AllTests {
public static Test suite() {
TestSuite suite = new TestSuite("Mi Suite");
suite.addTestSuite(RecetaTest.class);
suite.addTestSuite(CafeTest.class);
suite.addTestSuite(InventarioTest.class);
return suite;
}
}
Tan simple como un contenedor de Casos de Prueba. Y este contenedor, tiene la capacidad de absorver a otros contenedores de casos de prueba y llamarlos a todos de una sola vuelta y estos serán los encargados de verificar la clase.
8 may 2008
Log4j
Log4j es un framework o conjunto de clases que nos permite no reinventar la rueda en cuestión de log para un sistema, es decir, no hay necesidad de crear un número de clases para implementar la facilidad de un logger.
Un logger es un conjunto de información o mensajes que un sistema de información genera por diversas causas, en este caso, se clasifican por niveles (FATAL, ERROR, WARNING, INFO, DEBUG y TRACE). Lanzaremos un mensaje de tipo FATAL cuando nuestro programa no pueda continuar, en el cual se indicará la causa, el tiempo y otros diversos parametros, por otro lado, uno del tipo DEBUG para verificar los resultados de nuestro sistema en tiempo de desarrollo. En el archivo de configuración especificaremos el nivel más bajo sobre el cual se mostraran mensajes, así podemos tener INFO y DEBUG en nuestro programa, pero si el nivel del log es WARNING, ERROR o FATAL, todos los INFO ,DEBUG y TRACE no se mostrarán, pero la instrucción sí será revisada, consumiendo recursos del sistema, más adelante se comprenderá esto
Log4j nos provee de un número importante de clases, de las cuales generalmente sólo importaremos un par a nuestros archivos .java. Se sirve además de un archivo de configuración, del tipo properties o xml generalmente, para indicar diversos modificadores para la acción del logger, por ejemplo:
Un Appender no es otra cosa que el destino de los mensajes, un appender puede ser la consola o un archivo, o ambos pueden ser configurados para ser usados en un mismo sistema. El Layout es solamente el formato de los mensajes en los appenders, es decir, el orden de los datos de un mensaje enviado al log.
Listo ahora veamos un formato del archivo properties (miarchivo.properties):
#Especificamos el level más bajo que se puede utilizar, y el nombre de la configuración que vamos a usar, en DEBUG, todos se muestran, excepto TRACE.
log4j.rootCategory=DEBUG,MiAppender, Otro
#Declaramos el appender, de que tipo es y sus caracteristicas (FileAppender es un archivo simple)
log4j.appender.MiAppender=org.apache.log4j.FileAppender
#El archivo donde se van a guardar los datos
log4j.appender.MiAppender.file=server.log
#El formato en que se van a mostrar los datos, en este caso como XML
log4j.appender.MiAppender.layout=org.apache.log4j.xml.XMLLayout
#En este tipo de Appender, append false significa que se reescriba el archivo cada vez que se reinicia la aplicación, true al contrario, agregaria los nuevos datos al final del archivo
log4j.appender.MiAppender.append=false
#Otro Appender, este va a consola, los dos funcionarán
log4j.appender.Otro=org.apache.log4j.ConsoleAppender
# Layout simple, el formato de mensaje más simple o por default
log4j.appender.BLAH.layout=org.apache.log4j.SimpleLayout
Podemos usar este archivo en la clase MiEjemplo.java:
El ejemplo es explicativo, para mandar diversos mensajes a diversos niveles, usaremos la instancia de la clase Logger sobre la clase que indicamos (para saber en que clase se manda el mensaje) y cargamos el archivo properties con el método configure de la clase PropertyConfigurator y listo a mandar mensajes y lo mejor, una vez compilado, solo hay que cambiar el archivo properties para redireccionar los loggers y cambiar los niveles, si el nivel fuera INFO, el mensaje del método hacer no aparecerá, pero debemos ser cuídadosos, pues de todos modos se mandará a llamar el método debug(), aunque no imprima nada. Podríamos saber si el nivel debug está activado con logger.isDebugEnabled, etc.
El otro formato de configuració es el xml (xmllog4jconfig.xml)
Un logger es un conjunto de información o mensajes que un sistema de información genera por diversas causas, en este caso, se clasifican por niveles (FATAL, ERROR, WARNING, INFO, DEBUG y TRACE). Lanzaremos un mensaje de tipo FATAL cuando nuestro programa no pueda continuar, en el cual se indicará la causa, el tiempo y otros diversos parametros, por otro lado, uno del tipo DEBUG para verificar los resultados de nuestro sistema en tiempo de desarrollo. En el archivo de configuración especificaremos el nivel más bajo sobre el cual se mostraran mensajes, así podemos tener INFO y DEBUG en nuestro programa, pero si el nivel del log es WARNING, ERROR o FATAL, todos los INFO ,DEBUG y TRACE no se mostrarán, pero la instrucción sí será revisada, consumiendo recursos del sistema, más adelante se comprenderá esto
Log4j nos provee de un número importante de clases, de las cuales generalmente sólo importaremos un par a nuestros archivos .java. Se sirve además de un archivo de configuración, del tipo properties o xml generalmente, para indicar diversos modificadores para la acción del logger, por ejemplo:
- El destino de los mensajes (consola, archivo, red, etc),
- El formato y orden de los mensajes (hora, mensaje, fecha, causa, nivel de evento),
- Diversas propiedades del destino de los mensajes (nombre del archivo, puerto, tipo de archivo, etc).
- JDK instalado en nuestro ordenador,
- Descargar el framework http://logging.apache.org/log4j/
- Agregar al classpath el log4j-*.*.*.jar
Un Appender no es otra cosa que el destino de los mensajes, un appender puede ser la consola o un archivo, o ambos pueden ser configurados para ser usados en un mismo sistema. El Layout es solamente el formato de los mensajes en los appenders, es decir, el orden de los datos de un mensaje enviado al log.
Listo ahora veamos un formato del archivo properties (miarchivo.properties):
#Especificamos el level más bajo que se puede utilizar, y el nombre de la configuración que vamos a usar, en DEBUG, todos se muestran, excepto TRACE.
log4j.rootCategory=DEBUG,MiAppender, Otro
#Declaramos el appender, de que tipo es y sus caracteristicas (FileAppender es un archivo simple)
log4j.appender.MiAppender=org.apache.log4j.FileAppender
#El archivo donde se van a guardar los datos
log4j.appender.MiAppender.file=server.log
#El formato en que se van a mostrar los datos, en este caso como XML
log4j.appender.MiAppender.layout=org.apache.log4j.xml.XMLLayout
#En este tipo de Appender, append false significa que se reescriba el archivo cada vez que se reinicia la aplicación, true al contrario, agregaria los nuevos datos al final del archivo
log4j.appender.MiAppender.append=false
#Otro Appender, este va a consola, los dos funcionarán
log4j.appender.Otro=org.apache.log4j.ConsoleAppender
# Layout simple, el formato de mensaje más simple o por default
log4j.appender.BLAH.layout=org.apache.log4j.SimpleLayout
Podemos usar este archivo en la clase MiEjemplo.java:
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class MiEjemplo{
static Logger logger=Logger.getLogger(MiEjemplo.class);
public static void main(String[] args){
PropertyConfigurator.configure("miarchivo.properties");
logger.info("Comienzo");
MiEjemplo mio=new MiEjemplo();
mio.hacer();
ogger.info("Fin");
}
void hacer(){
logger.debug("No debe verse despues si cambiamos el rootCategory a INFO o mayor");
}
}
El ejemplo es explicativo, para mandar diversos mensajes a diversos niveles, usaremos la instancia de la clase Logger sobre la clase que indicamos (para saber en que clase se manda el mensaje) y cargamos el archivo properties con el método configure de la clase PropertyConfigurator y listo a mandar mensajes y lo mejor, una vez compilado, solo hay que cambiar el archivo properties para redireccionar los loggers y cambiar los niveles, si el nivel fuera INFO, el mensaje del método hacer no aparecerá, pero debemos ser cuídadosos, pues de todos modos se mandará a llamar el método debug(), aunque no imprima nada. Podríamos saber si el nivel debug está activado con logger.isDebugEnabled, etc.
El otro formato de configuració es el xml (xmllog4jconfig.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="appender" class="org.apache.log4j.FileAppender">
<param name="File" value="Indentify-Log.txt"/>
<param name="Append" value="false"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
</layout>
</appender>
<root>
<priority value ="debug"/>
<appender-ref ref="appender"/>
</root>
</log4j:configuration>
Bien, en este ejemplo observamos el FileAppender, que también se encuentra en el archivo properties, lo diferente de este archivo con el otro es el formato xml para empezar, las 3 primeras líneas no deberían de cambiar a menudo. Luego viene la configuración de los Appender, y dentro de ellos, (en este ejemplo, pues se pueden especificar en otro lado) los Layout. Aquí sí vemos un ejemplo de formato, Apache tiene un lista muy completa de los formatos que se pueden agregar, los cuales van procedidos por un simbolo de porcentaje (%) para indicar un campo. Y al final, vemos el nivel de configuración del log, y los appender que se van a usar para el sistema. El archivo java cambia un poco, y se utiliza el configure de la clase DOMConfigurator:
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
public class XmlTest{
static Logger logger = Logger.getLogger(XmlTest.class);
public static void main(String args[]) {
DOMConfigurator.configure("xmllog4jconfig.xml");
logger.debug("Here is some DEBUG");
logger.info("Here is some INFO");
logger.warn("Here is some WARN");
logger.error("Here is some ERROR");
logger.fatal("Here is some FATAL");
}
}
3 may 2008
Problemas con Hibernate (nested exception is java.io.FileNotFoundException)
El otro día estaba siguiendo un tutorial, y me sucedió que desde Eclipse no pude sacar una prueba JUnit porque la referencia a los mapas Hibernate no estaban bien referenciados.
Un pedazo del trazado es el siguiente:
Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in file [C:\..\timex2-servlet.xml]: Invocation of init method failed; nested exception is java.io.FileNotFoundException: class path resource [Department.hbm.xml] cannot be opened because it does not exist
Lo arregle indicándole el directorio donde se encontraban los archivos .hbm en el servlet.xml.
Antes:
Después:
Un pedazo del trazado es el siguiente:
Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in file [C:\..\timex2-servlet.xml]: Invocation of init method failed; nested exception is java.io.FileNotFoundException: class path resource [Department.hbm.xml] cannot be opened because it does not exist
Lo arregle indicándole el directorio donde se encontraban los archivos .hbm en el servlet.xml.
Antes:
<property name="mappingResources">
<list>
<value>Department.hbm.xml</value>
<value>Employee.hbm.xml</value>
<value>Timesheet.hbm.xml</value>
</list>
</property>
Después:
<property name="mappingResources">
<list>
<value>com/vt/model/Department.hbm.xml</value>
<value>com/vt/model/Employee.hbm.xml</value>
<value>com/vt/model/Timesheet.hbm.xml</value>
</list>
</property>
2 may 2008
Terminos EJB
EIS
Integración de Sistemas Empresariales
JEE
Base para los usos de componentes basados en Servlets, JSP y EJB.
BEAN
Componente de software reutilizable.
EJB
Enterprise Java Bean.
Modelo de componente distribuido estándar para el lado del servidor. Abstracción de problemas generales (concurrencia, persistencia, transacciones, seguridad) y centrarse en negocios.
Un Bean no el lo mismo que un EJB. Los Beans no soportan la invocación remota (RMI).
La especificación de los EJB detallan como los servidores de aplicaciones proveen objetos desde el lado del servidor que son, precisamente los EJB.
Permiten:
Integración de Sistemas Empresariales
JEE
Base para los usos de componentes basados en Servlets, JSP y EJB.
- Acceso a BD,
- Utilizado por BEA, IBM, Oracle, Sun y Tomcat,
- Directorios distribuidos (JNDI),
- Métodos Remotos (RMI/CORBA),
- Correo (Java Mail),
- Aplicaciones Web (JSP y Servlets),
- Beans, etc.
BEAN
Componente de software reutilizable.
EJB
Enterprise Java Bean.
Modelo de componente distribuido estándar para el lado del servidor. Abstracción de problemas generales (concurrencia, persistencia, transacciones, seguridad) y centrarse en negocios.
Un Bean no el lo mismo que un EJB. Los Beans no soportan la invocación remota (RMI).
La especificación de los EJB detallan como los servidores de aplicaciones proveen objetos desde el lado del servidor que son, precisamente los EJB.
Permiten:
- Comunicación con CORBA,
- Transacciones,
- Concurrencia,
- JMS,
- Servicios de nombre y direcciones,
- Seguridad,
- Ubicación de componentes.
Estructura de Carpetas una Aplicación Web
Esta es una estructura general. Para una aplicación web que desarrolle con Flex como la vista y utilizando la tecnología BlazeDS para mapear objetos Java a objetos AS.
Login
-WEB-INF/
-META-INF/
-web/
Login
-WEB-INF/
- lib/
- flex/
- service-config.xml
- remoting-config.xml
- proxy-config.xml
- messaging-config.xml
- classes/
- com.company.pojos/
- Usuario.*
- com.company.rpcObjects/
- LoginServer
- hibernate.cfg.xml
- usuario.hbm.xml
- web.xml
-META-INF/
- MANIFEST.xml
- context.xml
-web/
- archivos flex
- archivos html
Ejemplo de MVC
En este ejemplo mostramos un flujo del paradigma modelo-vista-controlador. En el cual nos adentraremos más adelante. Resumiendo un poco, este paradigma se enfoca en 3 ámbitos, la vista, que será la interfaz mostrada al usuario, una pantalla, un display, etc; el modelo, que será la fuente de datos, como base de datos, archivos xml y el controlador, a cargo de manejar los datos entre ellos.

Etiquetas:
Controlador,
Modelo,
MVC,
Vista
Suscribirse a:
Comentarios (Atom)