jueves, 24 de julio de 2008

Ruby (entre php y java)

Ruby es un lenguaje de programación interpretado, reflexivo y orientado a objetos, creado por el programador japonés Yukihiro "Matz" Matsumoto, quien comenzó a trabajar en Ruby en 1993, y lo presentó públicamente en 1995. Combina una sintaxis inspirada en Python, Perl con características de programación orientada a objetos similares a Smalltalk. Comparte también funcionalidad con otros lenguajes de programación como Lisp, Lua, Dylan y CLU. Ruby es un lenguaje de programación interpretado en una sola pasada y su implementación oficial es distribuida bajo una licencia de software libre.

Ruby es orientado a objetos: todos los tipos de datos son un objeto, incluidas las clases y tipos que otros lenguajes definen como primitivas, (como enteros, booleanos, y "nil"). Toda funcion es un método. Las variables siempre son referencias a objetos, no los objetos mismos. Ruby soporta herencia con enlace dinámico, mixins y patrones singleton (pertenecientes y definidos por un sola instancia más que definidos por la clase). A pesar de que Ruby no soporta herencia múltiple, la clases pueden importar módulos como mixins. La sintaxis procedural está soportada, pero todos los métodos definidos fuera del ámbito de un objeto son realmente métodos de la clase Object. Como esta clase es padre de todas las demás, los cambios son visibles para todas las clases y objetos.

via: wikipedia

enlaces:
oficial: rubi-lang.org
pruebalo: http://tryruby.hobix.com/
descárgalo: aquí
desarrollo web: rubyonrails.org

seam-gen

Es un framework que facilita el desarrollo con el JB3.Y estandariza la vista JSF y en el modelo los EJB.
Con esta herramienta tenemos varias opciones:
  • setup: Sirve para configurar el proyecto. Te pregunta entre otras cosas el directorio de instalación de JBoss, si quieres desplegar un archivo war (sin EJBs) o un ear (con EJBs), el nombre del paquete donde irán las clases, y parámetros de la conexión con la base de datos.
  • new-project: Crea un proyecto para eclipse con todas las dependencias y la configuración básica a partir de los datos proporcionados a través del setup.
  • update-project: Actualiza el proyecto con las últimas dependencias.
  • delete-project: borra el proyecto
  • deploy: Despliega el proyecto y el datasource en JBoss
  • undeploy: Replega el proyecto y el datasource.
  • explode: Desplega el proyecto y el datasource en JBoss como una estructura de ficheros, sin empaquetar.
  • restart: Resetea el proyectodesplegado con ”explode”
  • unexplode: Replega el proyecto y el datasource desplegado con ”explode”
  • new-action: Crea un nuevo Stateless Session Bean con su correspondiente interface y sus anotaciones.
  • new-form: Crea un nuevo Stateful Session Bean con su correspondiente interface y sus anotaciones.
  • new-conversation: Crea un nuevo Stateful Session Bean con su correspondiente interface y sus anotaciones. Añade anotaciones y esqueletos de métodos para trabajar con Tasks. También crea una clase de Test que puede usarse para simular el ciclo de petición/respuesta de JSF.
  • new-entity: Crea un nuevo Entity Bean con sus anotaciones.
  • generate-entities: Genera Entity Beans a partir de un modelo existente en la base de datos
Vía: El misterioso mundo de Java

miércoles, 23 de julio de 2008

Aplicación con jboss-seam y seam-gen: Delicious

Hoy vamos a crear una nueva aplicación ("delicious") utilizando el framwork 'JBoss-Seam' y una de sus herramientas para la generación de proyectos, el 'seam-gen'.
Se da por hecho que se ha insertado en el "C:\WorkspaceSeam" el '
jboss-seam-2.0.3.CR1', y que en la ventanita de eclipse-ANT se ha arrastrado el 'build.xml' del 'seam-gen':

Lo primero que hacemos es ejecutar la tarea "seam-gen>reset" desde ANT (asi se limpia la información que pueda haber en "seam-gen/build.properties") y "seam-gen
>setup" (para empezar a configurar la información del archivo "seam-gen/build.properties"). La configuración abarca lo siguiente:
  • directorio de workspace: C:/WorkspaceSeam
  • directorio de jboss: C:/jboss-4.2.2.GA
  • nombre del proyecto: delicious
  • queremos richfaces: n
  • richfaces skin:blueSky
  • ear o war project: ear
  • el package de nuestra aplicación: es.cea.delicious
  • el package de nuestros EJBs: es.cea.delicious
  • el package de nuestros tests: es.cea.delicious
  • base de datos: mysql
  • hibernate dialect: org.hibernate.dialect.MySQLDialect
  • path a la libreria de mysql (buscar la ruta donde esté el .jar 'mysql-connector-java-5.0.3-bin.jar'): C:/Workspace/librerias/mysql-connector-java-5.0.3-bin.jar
  • jdbc driver: com.mysql.jdbc.Driver
  • jdbc url: jdbc:mysql://localhost/delicious?createDatabaseIfNotExist=true
  • user database: root
  • clave database:eticom
  • database catalog name: delicious
  • are you working with tables that already exist ...:n
  • do you want to drop and recreate the database ...: y
Para ver cómo ha quedado abrir el "seam-gen/build.properties":

Ahora, desde la ventanita ANT ejecutamos la tarea "seam-gen
>new-project", con lo que se genera un nuevo proyecto (toda su estructura) en el workspace indicado en el "seam-gen/build.properties". Para abrirlo con eclipse ejecutamos la ruta: 'file>new project>java project'; como nombre de proyecto "delicious" y activamos el radiobutton 'create project from existing source' y buscamos la ruta 'C:\WorkspaceSeam\delicious' (que se había generado anteriormente). Finalizamos.

Arrastramos el archivo "build.xml", del nuevo proyecto 'delicious', a la ventana ANT. Se lanza la tarea explode (para desplegar el proyecto y el datasource en JBoss, como una estructura de ficheros -sin empaquetar-). Ejecutar primero restart por si hay algún proyecto desplegado mediante 'explode'.
Se lanza el JBoss (desde eclipse -
> web browser) y poniendo la dirección "http://localhost:8080/delicious" en la barra de direcciones, aparecerá el inicio de nuestro proyecto.

Tenemos que generar tres clases/entidades, que serán persistentes y cuyas propiedades serán:
  • Usuario: 1) List links; 2) List tags;
  • Link: List tags;
  • Tag: List links;
Vamos a crear las entidades. Empezamos por 'Link'. Ejecutamos la tarea "seam-gen>new-entity", que nos pide:

1) el nombre de la entidad: Link
2) el nombre de la página principal: linkList
3) el nombre de la página detalle: link

Actualizamos el proyecto (F5) y se ve que el source folder "src/model" contiene un nuevo EJB
(Enterprise JavaBean) de Entidad "es.cea.delicious/Link.java" que encapsula los objetos del servidor que almacena los datos. Si la abrimos vemos como se encuentran incluidos los import de las etiquetas del api de persistencia, así como un validador de hibernate (Length) y varias anotaciones más: @Entity para definir la clase, @Id para definir el campo que hará de identificativo, etc.
Nota: todos los campos/propiedades incluidos en un EJB de entidad se consideran persistentes (que tienen la capacidad de guardarse y recuperarse desde un medio de almacenamiento), aunque no se incluya la etiqueta '@Column'. Si no se quiere persistir una propiedad, basta con anotarla con la etiqueta @Transient.

Observar también que en
el source folder "src/action" se han creado nuevas clases: 1) LinkHome.java, que extiende de org.jboss.seam.framwork.EntityHome, y 2) LinkList.java, que extiende de org.jboss.seam.framwork.EntityQuery.

Ejecutamos "Ant
>delicious>explode" para actualizar la aplicación en el servidor, iniciamos el JBoss y vemos los cambios en el navegador: aparece un nuevo enlace en el menú superior de la web que incluye 'linkList', que si entramos también nos permite listar, editar, crear y borrar links.

Ahora creamos, del mismo modo que con Link, las clases 'Tag' y 'Usuario': seam-gen>new-entity... Cuando acabemos el árbol de clases debe quedar tal que así:

A continuación se modifica el archivo "resources/import-dev.sql" para que cuando arranquemos la base de datos, ésta se encuentre cargada de datos:
Ahora hay que modificar las clases para implementar las relaciones, esto es, implementar las listas en las clases Usuario, Link y Tag. Las relaciones serán de tipo OneToMany o ManyToMany.
En el caso de la clase Usuario, tenemos dos listas, una de links y otra de tags, ambas de tipo OneToMany:

...para las clases 'Link' y 'Tag', la relación a implementar es una ManyToOne, lo que es lo mismo, declarar la propiedad usuario y su correspondiente etiqueta @ManyToOne en el método getter:

...como hemos insertado nuevas propiedades en las clases, hay que modificar el "resources/import-dev.sql":

Modificamos ahora las páginas 'linkList.xhtml' y 'tagList.xhtml' (situadas en la carpeta 'view') para reflejar los cambios del modelo persistente de nuestra aplicación, esto es, vamos a mostrar en el listado de links y tags el usuario al que cada link pertenece, para lo cual añadimos una nueva columna a la tabla /dataTable ya existente. Este es el código a incluir en el dataTable para la nueva columna:
<h:column>
<f:facet name="header">Usuario</f:facet>
<h:outputText value="#{link.usuario.name}" />
</h:column>
Para el 'usuarioList.xhtml' imprimimos los links y los tags de cada usuario, para lo que necesitamos crear 2 métodos getter nuevos en la clase 'Usuario.java' que devuelvan una cadena con los elementos de cada colección (hay que colocar encima de cada método la anotación '@Transient' para indicar la no persistencia de esos atributos):
...seguidamente hay que añadir dos columnas más a la lista de usuario (usuarioList.xhtml) para sacar por pantalla las cadenas anteriormente creadas. Se hace del mismo modo que anteriormente creamos las columnas para 'tagList' y 'linkList':

Ahora vamos a crear una clase de consulta sobre una de las clases persistentes. Esto se realiza con el comando "Ant
>seam-gen>new-query", que al ejecutarla te pide una serie de parámetros:
  • enter the entity class to search, donde se introduce el nombre de la clase persistente (EJB de entidad) de la que queremos realizar la consulta. Empezamos con 'Link'.
  • seam query component name: se introduce el nombre del componente que realizará la consulta, esto es, el '@Name("___")', por ejemplo "consultaLink".
  • query class name: es el nombre de la clase java que será el componente que realizará la query; pondremos "linkQuery".
  • ejbql: hay que poner la consulta. Podemos poner la que queramos o dejarla como está: "select o from Link o".
  • query results page: es el nombre de la página (sin la extensión) que generará los resultados para el usuario; ponemos "consultaLinks".
...actualizamos (F5) el proyecto y vemos que en "src/action>es.cea.delicious" ha creado la clase "linkQuery.java", y en la carpeta "view" el JSP "consultaLinks.xhtml".

Lo siguiente es crear la Acción, que se realiza mediante "seam-gen
>new-action". Al ejecutar la tarea nos pide los siguientes parámetros:
  • seam component name: esto es el nombre del componente que contendrá la acción, esto es, el '@Name("___")'; ponemos "registroAction".
  • interface local: es el nombre de la interface que implementará la bean class o componente que nos pide seguidamente; escribimos "RegistroAction".
  • bean class: esta es la clase java que implementará la interface anterior y que será nuestro componente/bean: "RegistroActionBean".
  • method name: es el nombre de la acción: "Registrar".
  • page name: es el nombre de la página que contendrá el formulario y el botón correspondiente: "registroUsuario".
...actualizamos (F5) el proyecto y vemos que en "src/action>es.cea.delicious" ha creado la interface "RegistroAction.java" y la clase "RegistroActionBean.java" con su método "registrar()", y en la carpeta "view" el JSP "registroUsuario.xhtml".

Lo siguiente es crear una nueva conversación (seam-gen
>new-conversation), que sirve para la generación de tareas por parte del usuario. Se inicia con la anotación "@Begin" encima del método "begin()" que inicia la conversación, y acaba con la anotación "@End" encima del método "end()", ambos en el bean que implementa el componente que vamos a crear. Los parámetros a introducir son los siguientes:
  • seam component name: es el nombre del componente que representará la conversación, esto es, el "@Name("___"); lo llamamos "editaTag".
  • interface local: es el nombre de la interface que implementará a nuestro futuro componente: "EditaTag".
  • bean class: es el nombre de la clase java que implementa a la interface anterior y que será nuestro componente/bean: "EditaTagBean".
  • method name: es el nombre de la acción: "editar".
  • page name: es el nombre de la página que podrá iniciar la conversación: "editaTag".
...actualizamos (F5) el proyecto y vemos que en "src/action>es.cea.delicious" ha creado la interface "EditaTag.java" y la clase "EditaTagBean.java" con su método "editar()", y en la carpeta "view" el JSP "editaTag.xhtml".

Ahora, aprovechando el componente "RegistroActionBean", vamos a desarrollar la funcionalidad de registro de usuario, verificando que el usuario no existe en la base de datos con anterioridad, para lo cual hay que seguir unos pasos:
1)
Convertir el componente de entidad "Usuario.java" en componente de estado y de ámbito de sesión: para esto nos vamos a la clase "Usuario.java" y le colocamos las anotaciones "@Scope(ScopeType.SESSION)" y "@Name("usuario")" encima de la anotación "@Entity":

2) Inyectar dicho componente (Usuario usuario) en nuestro componente "RegistroActionBean" para acceder desde la acción registra: para esto nos vamos a la acción "RegistroActionBean.java" y, dentro de la clase y antes del método "registrar()", le añadimos la anotación "@In Usuario usuario;". Modificamos la vista "registroUsuario.xhtml", al que le añadimos un inputtext dentro del formulario para insertar el nombre del usuario a registrar:
...si queremos ver como ha cambiado la cosa, hacemos un explode y restart de la aplicación.

3) Inyectar el EntityManager (Gestor de entidades persistentes, a través de éste actualizaremos las entidades persistentes y con ello la base de datos) y persistir al usuario: para ello nos vamos a
la acción "RegistroActionBean.java" y, debajo de la inyección de usuario que hicimos antes, le metemos la inyección/anotación "@In EntityManager entityManager;", y dentro del método registrar, la persistencia del usuario: "entityManager.persist(usuario);". Quedaría así:

4) Persistir el usuario, en caso de que no exista en la base de datos, de lo contrario enviaremos un mensaje al usuario: se modifica la acción "RegistroActionBean.java":

...el mensaje que se le devuelve al usuario lo visualiza el componente "registroUsuario.xhtml": "≷messages globalOnly="true" styleClass="message"/>".

5) Redirigir la petición a la página "usuarioRegistrado.xhtml" si el usuario ya se ha registrado: empleamos el archivo "resources
>WEB-INF>pages.xml" para realizar una acción antes de procesar una solicitud. En este caso si se solicita la página "/registroUsuario.seam", se comprueba que el "id" de usuario es diferente de 0, en cuyo caso significaría que el usuario ya está en la base de datos con un "id" autogenerado:


...por otro lado preparamos el archivo "usuarioRegistrado.xhtml" que se mostrará en caso de que el usuario ya esté registrado:


THE END

martes, 22 de julio de 2008

Crear aplicación con jboss-seam

En primer lugar vamos a integrar los servidores en Eclipse: "window>show view>servers".. "new>server" y vemos los posibles servidores que podemos añadir. Tenemos un textArea de filtrado; si ponemos Tomcat, nos salen las distintas versiones. Seleccionamos la version 6.0, le decimos donde está el Home Directory (donde está instalado el Tomcat en nuestro ordenador) y finish..
Podemos hacer lo mismo con el JBoss 4.2, pero no podemos arracar los dos al mismo tiempo porque tienen el mismo puerto (se puede cambiar cambiando la configuración de arranque).

Generar código a través de seam-gen: arrastramos el "build.xml" de la carpeta "seam-gen" de eclipse en la ventanita ANT. Hacemos SETUP en el seam-gen de ANT y nos sale una ventanita que nos pide una serie de parámetros (está en el foro):
  • directorio de workspace:
  • directorio de jboss
  • nombre del proyecto
  • richfaces skin
  • ear o war project
  • el package de nuestra aplicación
  • el package de nuestros EJBs
  • el package de nuestros tests
  • base de datos
  • hibernate dialect
  • path a la libreria de mysql
  • jdbc driver
  • jdbc url
  • user database
  • clave database
  • database name
  • are you working with tables that already exist ...
  • do you want to drop and recreate the database ...
Después de seguir todos los pasos que vienen en el foro, nos vamos a la carpeta "seam-gen" del proyecto "jboss-seam-2.0.3.CR1" y actualizamos (F5). Si hemos cometido algún error abrimos "build.properties".

Ahora ya podemos hacer 'news', como un "new-project" (esto en la ventanita ant). Ahora, creamos un nuevo proyecto Java: file>new>java project... project name "eticom-seam" y directory "C:\WorkspaceSeam\eticom_seam".
Arrastramos su "build.xml" al ANT. Si le hacemos "Explode" veremos como si vamos a "C:\jboss-4.2.2.GA\server\default\deploy\eticom_seam.ear" se encuentra el proyecto y su datasource.

Arrancamos el servidor JBoss (ya sea por ordenador o por eclipse). Ahora, aparte de emplear el navegador externo, se puede emplear un navegador en eclipse (Web browser -que se identifica con una bola del mundo-); si le incluímos la dirección "http://localhost:8080/eticom_seam/home.seam" aparece el resultado del proyecto.

Si hacemos menú contextual sobre el proyecto y en el filtro ponemos builders, vemos que tenemos, además del "java builder", el "explode" como constructor para el proyecto.

Ahora nos vamos al ANT de "seam-gen" y hacemos doble clic sobre "new-entity". A la clase la llamamos 'Coche', como nombre de la pagina principal: 'cocheList' y como nombre de la página detalle: 'coche'. Si actualizamos (F5) nuestro proyecto vemos que en el source folder "src/model" nos crea la clase coche con todos sus atributos y demás.

En "eticom_seam" de ANT le hacemos un "restart" y en el "import-dev.sql" le hacemos el siguiente import:
insert into coche (id, version, name) values (1, 0, coche1)
insert into coche (id, version, name) values (2, 0, coche2)
insert into coche (id, version, name) values (3, 0, coche3)
..le volvemos a dar a "restart", generamos la web en el web browser, y en el menu de arriba de la web, pinchamos en "cocheList" y nos debe salir el listado de los coches que le hemos insertado anteriormente.

Ahora vamos a hacer un "new action", para lo cual nos vamos a "seam-gen" de ANT y ejecutamos "new-action". La llamamos "MiAccion", a la interfaz "MiAccionI", la clase que va a implementar la interfaz "MiAccionBean" y lo demás "niAccion". Refrescamos el proyecto y vemos que en el source folder "src/action" se han creado nuevas clases. Si vamos al navegador e incluimos la dirección "http://localhost:8080/eticom_seam/miAccion.seam" se ve que ha generado un nuevo botón "miAccion!".

Ahora vamos a realizar el proyecto "delicious" del foro, que está muy bien explicado.

Anotaciones:
Package javax.persistence
Enlaces de Seam-City:

lunes, 21 de julio de 2008

JBoss Seam

Vamos a instalar todo lo necesario para el uso del SEAM, instalamos el JDK5. Y en las variables de entorno cambiamos el JAVA_HOME a "C:\Archivos de programa\Java\jdk1.5.0_16", en vez de la 6 que es la que tenía.

Ahora se descomprime el "apache-tomcat-6.0.16-CON-JBOSS-EMBEDDED.rar" que tiene un TOMCAT, que tiene un servidor de aplicaciones dentro. Lo colocamos en C:\ y dentro de su carpeta BIN ejecutamos 'start.bat' para ver que todo anda bien.

Vamos a http://localhost:8080/ e introducimos usuario y clave: eticom. Vamos a "Tomcat Manager". Ahora ejecutamos el .jar: "jems-installer-1.2.1.CR4.jar": todo siguiente. Si ejecutamos de nuevo "http://localhost:8080/" vemos que nos da la bienvenida a JBoss. Descomprimimos "jboss-seam-2.0.3.CR1.zip" en un nuevo workspace: "C:\workspaceSeam". Abrimos la carpeta "build" y editamos la dos últimas líneas del archivo "default.build.properties". Se pone lo siguiente y guardamos. Con esto definimos las localizaciones de nuestros dos servidores:
jboss.home C:/jboss-4.2.2.GA
tomcat.home C:/apache-tomcat-6.0.16
Abrimos la consola y vamos a esta ruta: "C:\workspaceSeam\jboss-seam-2.0.3.CR1\examples\registration>", que es el registro que vamos a probar. Ejecutamos (antes arrancamos el tomcat):
ant tomcat.deploy
..nos vamos a "http://localhost:8080/". y vemos el ejemplo que acabamos de ejecutar en "http://localhost:8080/jboss-seam-registration":..Esto es para ver que funciona con Tomcat (página 23 del manual cuya ruta viene al final del post). Ahora para arrancar desde JBoss, tecleamos por consola: "ant deploy".

Abrimos eclipse y le metemos nuestro nuevo workspace: File -> switch workspace ->"
C:\workspaceSeam".
Creamos un nuevo proyecto con el nombre "jboss-seam-2.0.3.CR1": new project -> java -> from existing source.

Seleccionamos todos los "soucer folders" y ejecutamos "menú contextual -> build path -> remove from build path". Ahora, de la carpeta "examples/registration" del proyecto, seleccionamos las carpetas 'resources', 'src' y 'view' y la añadimos al build path:
"menú contextual -> build path -> use as source folder". Del "build.xml" que está dentro de esta carpeta la corremos a la ventanita de Ant (si no la tenemos abierta: "Window -> show view -> ant") en el que vemos la tarea que estemos tratando de nuestro ejemplo.

Todo lo que aparece en el archivo "build.xml" del ejemplo registration hereda del "build.xml" de la carpeta "examples".

Dentro de WEB-INF que está en "resources", están los archivos que definen nuestra aplicacion: "components.xml", "faces-config.xml" y "web.xml".

Ahora, con Seam, no es necesario definir los nombres de las anotaciones, sino que se definen directamente (ejemplo en la clase "User.java"):
@Entity
@Name("user")
@Scope(SESSION)
@Table(name="users")


Tutorial de Seam e
n la ruta: "C:\WorkspaceSeam\jboss-seam-2.0.3.CR1\doc\reference\en-US\pdf"
Enlace: seam city blog.

martes, 15 de julio de 2008

JDeveloper

Al ejectutar el archivo ejecutable "jdeveloper.exe" nos pedirá un path, que será "C:\Archivos de programa\Java\jdk1.6.0_06\bin\java.exe".
Una vez llegados a abrir el programa, creamos una nueva aplicación tal que así.

...Aceptamos.
Ahora menú contextual en la carpeta "Web content/new/JSF". Aceptar. El nombre del archivo a crear: "prueba1.jspx". Le decimos que no al Backing Bean:


..y siguiente hasta el final.

Vemos una de las ventanitas que se llama "Component Palette", que es donde se encuentra la lista de componentes para cada tipo de página. Nosotros seleccionamos para "JSF-HTML". PAra incluir un componente en una vista sólo arrastramos el componente que queramos a la misma, estando ésta en modo Design.

Ahora vamos a crear otro JSF (prueba2) pero esta vez con respaldo de bean (Backing Bean):

..esto te genera automáticamente un paquete y un Bean en la carpeta "Application Sources". Ahora, todo lo que vayamos modificando en el .jspx está relacionado con el bean. Si creamos un textBox, un boton, o lo que sea, el Bean se modifica; si modificamos las propiedades, también se modifica. Por ejemplo, si en un boton, le modificamos la propiedad "Action", aparecerá un método automaticamente en el Bean con el nombre que le hayamos puesto.

martes, 8 de julio de 2008

+ Spring MVC

Para ver lo que está pasando por debajo de la ejecución en el proyecto de ayer (Eticom-libreria-web), es decir, que aparezca por consola lo que está sucediendo en cuanto a las consultas SQL de Hibernate a la Base de datos, hay que modificar la propiedad "hibernateProperties" del bean "SessionFactory" en el archivo "applicationContext-hibernate.xml" añadiéndole una propiedad:

<prop key="hibernate.show_sql">true</prop>

Y ahora, continuando con el proyecto de ayer (Eticom-libreria-web), en la salida por pantalla de los "libros.html" vamos a añadir una nueva columna para que nos muestre solamente los libros del autor seleccionado, esto tiene que ocurrir en la página "capitulosDeLibro.html", para lo cual enviamos en el enlace, el id del autor del que queramos sus libros: "http://localhost:8080/capitulosDeLibro.html?id=2".

Para que al enviar el id del objeto de nuestra tabla sea recogido en el controlador de la solicitud, hay que realizar dicha solicitud y recogerla en un método de nuestro controlador, anotado con la etiqueta "@RequestMapping("/pathCorrespondiente.html")". Luego hay que incluir otra anotación dentro del parámetro para poder recogerlo (en mi caso el 'id'):
@RequestMapping("/capitulosDeLibro.html")
public String listadoCapitulosDeLibro(ModelMap model, @RequestParam(value="id", required=true) Long id){
Session session = getSessionFactory().openSession();
Libro libro = (Libro) session.get(Libro.class,id);
model.addAttribute("capitulos", libro.getCapitulos());
// session.close();

return "listaCapitulos";
}
Nota: se puede apreciar que no se cierra la sesión porque, como ocurría ayer, si se cierra entonces ya no te permite acceder a otra consulta en la base de datos.
Nota2: vemos que la etiqueta "@RequestParam" puede tiene dos parámetros, 1) el "value", que es el nombre del parámetro que se recibe por la barra de direcciones (en este caso el "id"), y 2) el "required" que indica si el parámetro va a ser obligatorio o no (true por defecto, o false). Se podrían omitir dichos parámetros porque en este caso el parámetro es obligatorio, con lo que la cabecera del método quedaría asi:
"public String listadoCapitulosDeLibro(ModelMap model, @RequestParam Long id){...}".

Bueno, ahora vamos a añadirle la nueva columna en la vista "listaLibros.jsp" donde aparezcan los capitulos de cada libro. Así que en esta vista le añadimos un nuevo "display:column" pero que cierre la etiqueta con otra etiqueta del mismo tipo para poder incluir en medio, el codigo HTML que queramos:
<display:table name="libros" class="table" requestURI="" id="librosList" export="true" pagesize="10">
...
<display:column>
<a href="/capitulosDeLibro.html?id=${librosList.id}" />
</display:column>
</display:table>
Nota: en el display:table, el "name" es el nombre de la colección que se va a representar en la tabla y el "id" es la variable/objeto que empleamos en cada pasada del bucle.

Enlace al foro sobre esto

######## Formularios de Búsqueda ########

pendiente.

lunes, 7 de julio de 2008

Spring MVC

Nos descargamos el proyecto "eticom-libreria-hibernate-xml" y el "eticom-libreria-spring", que se basa en SPRINGFramework, y trabaja con SpringMVC. No hace falta trabajar con ambas herramientas.

En AppFuse.org, es una aplicación que genera un archivo Ant o un comando Maven para generar proyectos vacíos que emplean/integran otras herramientas, pero ya preparados.

Al arrancar la aplicación intentará arrancar Hibernate teniendo en cuenta una serie de archivos, como "src/main/resources/jdbc.properties", "src/main/webapp/WEB-INF/applicationContext-hibernate.xml" o "src/main/resources/import.sql".

En "applicationContext-hibernate.xml" le inidicamos los archivos de mapeo. Los mapeos pueden provenir de distintos lugares o proyectos. En este proyecto vemos como unos vienen de un paquete y otros.. (MP3).

Como he dicho, "src/main/webapp/WEB-INF/applicationContext-hibernate.xml" arranca con la aplicación, y genera el "dataSource" y el "sessionFactory".
Es Spring el que se encarga de crearlos.

El problema del MVC se soluciona mediante anotaciones. Para el controlador "@Controller". Por cada petición web, hay que poner una anotación "@RequestMapping("/libros.html")", al que le sigue un método public String solicitud(ModelMap model){}, que devuelve una lista (en este caso de libros).
Spring MVC también proporciona una serie de tags de librerías, que se encuentran en "taglibs.jsp":

<%@ taglib uri="http://www.springmodules.org/tags/commons-validator" prefix="v" %> <%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>

También tenemos un escuchador/listener que se encarga de leer la configuración de Spring, es decir, arranca el SpringFramework (se encuentra en el "web.xml"):

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Hay que indicar el lugar donde se van a encontrar los controladores, así como la forma de inyección de recursos. Ambos se harán mediante anotaciones:

<!-- Activates mapping of @Controller -->
<context:component-scan base-package="eticom.libreria.web"/>

<!-- Activates @Autowired for Controllers -->
<context:annotation-config/>

--------------------

Vamos a poner esto en práctica en el proyecto "eticom-libreria-web".

jueves, 3 de julio de 2008

Seguimos con Struts

Vamos a crear un nuevo proyecto Maven (eticom-discografica-hibernate) del mismo modo que creamos un nuevo proyecto Maven (info aquí), al que le vamos a pasar, del proyecto "eticom-discografica-servlet-JSTL", las clases Cantante, Disco y Cancion, así como la carpeta "src/main/resources", del cual nos quedamos con 'hibernate-properties', 'import.sql' y 'log4j.xml', los cuales guardamos en "src/test/resources". También le borramos los paquetes que se crean automáticamente cuando creamos un nuevo proyecto maven. Seguidamente le hacemos un package-install.

Del "eticom-discografica-servlet-JSTL" borramos el paquete contenedor de las clases, y le hacemos una dependencia del proyecto que acabamos de crear (eticom-discografica-hibernate). Si nos da error, probar cerrando este proyecto, o desmavenizando y mavenizando de nuevo.

Nos descargamos el proyecto del repositorio "eticom-club-struts-basico".

Internacionalización (i18n) en Struts
Si abrimos el web.xml del proyecto, en...

<context-param>
<param-name>
javax.servlet.jsp.jstl.fmt.localizationContext
</param-name>
<param-value>Traducciones</param-value>
</context-param>

...lo que carga es el archivo "Traducciones.properties" que se encuentra en "src/main/resources", que es donde están nuetras traducciones.
Luego en "layout.jsp" hay que importar una librería de 'tags-bean' y con prefijo 'bean', para que podamos sacar la traducción a través de la etiqueta 'message':

<bean:message key="label.header" /
>

-------------------------

Existen dos tipos de etiquetas struts:
¿Cómo validar los datos de un ActionForm de Struts -formulario-?
ActionForm contiene un método 'validate()', y lo que tenemos que hacer es sobreescribir este método en nuestra clase formulario, en este caso en 'SaludoForm.java'.

Esto sirve para que el formulario, si no está correctamente definino, no llegue a acceder a la base de datos, es decir, que no lance el Action (SaludoAction).

-----------------------

Ahora estamos en 'struts-config.xml':
Si hacemos ctrl+espacio entre las etiquetas form-beans y action-mapping, nos ofrece 'global-forwards', que sirve para no repetir código, es decir, que si queremos que todas las acciones que nos devuelvan la palabra "error" nos envíen a "error.jsp", lo hacemos añadiendo la siguiente etiqueta:
<global-forwards>
<forward name="error" path="/error.jsp"></forward>
</global-forwards>
-------------------------

Si queremos hacer un plugin, solo tenemos que crear una clase que implemente a 'plugin'.

miércoles, 2 de julio de 2008

Descargando librerías para Struts. Struts2 y Appfuse

Bueno, en primer lugar voy a descargarme las librerías necesarias para el buen trabajo con struts2. para lo cual tenemos que abrir nuestra consola e irnos al directorio workspace:

Para generar con MAVEN una App con Struts2

c:\>cd workspace

c:\>mvn archetype:create -DgroupId=eticom -DartifactId=eticom-struts2-servlet -DarchetypeGroupId=org.apache.struts -DarchetypeArtifactId=struts2-archetype-starter -DarchetypeVersion=2.0.5-SNAPSHOT -DremoteRepositories=http://people.apache.org/repo/m2-snapshot-repository

c:\>cd eticom-struts2-servlet
c:\>mvn jetty:run-war (comando empleado para el despliegue)

Para generar con MAVEN una App con Struts y Appfuse

c:\>cd workspace

c:\>mvn archetype:create -DgroupId=eticom -DartifactId=eticom-appfuse-struts2-servlet -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-basic-struts -DarchetypeVersion=2.0 -DremoteRepositories=http://repo1.maven.org/maven2

c:\>cd eticom-struts2-servlet
c:\>mvn jetty:run-war

Instalando TOMCAT 6.0

El Tomcat es un contenedor web, es decir, de servlet's y jsp's. NO es un contenedor de aplicaciones. Es por tanto, similar al servidor Jetty.

Nos descargamos el archivo "apache-tomcat-6.0.16.zip". Descomprimimos el contenido donde queramos, yo lo voy a hacer en C:\Archivos de programa\Java

Cerramos el eclipse y paramos el Jetty si lo tenemos abierto.

Abrimos el archivo de texto "RUNNING.txt", donde vienen las instrucciones para su instalación:
You may also use the full JDK rather than just the JRE. In this
case set your JAVA_HOME environment variable to the pathname of
the directory into which you installed the JDK, e.g. c:\j2sdk5.0
or /usr/local/java/j2sdk5.0.
Como ya tenemos algunos de los requisitos de instalación realizados por la instalación de otros plugins

Abrimos la carpeta BIN y ejecutamos "startup.bat" para ver que el servidor se inicia correctamente... cerramos.

En la carpeta CONF, en el fichero "server.xml" están las propiedades y configuraciones de Tomcat. En "tomcat-users.xml" vienen los usuarios y roles que van a tener estos; lo modificamos y lo guardamos:

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="manager"/>
<user name="eticom" password="******" roles="manager" />
</tomcat-users>

Volvemos a arrancar el Tomcat con el "startup.bat", abrimos el navegador y en la barra de direcciones ponemos "http://localhost:8080" y nos tiene que salir un lindo gatito.

Pinchamos en esa página en el link "Status" e introducimos el nombre y la contraseña. Nos sale la memoria que nos queda, etc.
Si clicamos en "Listar Aplicaciones" podemos gestionar el servidor.
En "Archivo WAR a desplegar" seleccionamos un archivo WAR de nuestro workspace (tiene que estar en el Target. En mi caso usaré C:\Workspace\eticom-struts-servlet\target\eticom-struts-servlet.war) y pulsamos en desplegar. Esto sirve para ejecutar aplicaciones.

¿Y si no funciona algo?
Vamos a la carpeta "logs", dentro de la cual vemos archivos .log donde se logea la aplicación. Pinchamos en el "localhost.2008-07-02.log".

En la carpeta "lib" están las librerias que emplea Tomcat para arrancar las aplicaciones.

Carpeta "webapps": cuando hacemos un despliegue, lo que se hace es trasladar el .WAR a esta carpeta y lo desempaqueta.

Enlaces: instalación y configuración Tomcat 6.0

Poniendo en práctica los STRUTS

Partiendo del proyecto 'eticom-struts-servlet', vamos a realizar un formulario de saludo por el cual nos envíe a una página en concreto.

Lo primero que hago es añadirle una dependencia: en el query -> "struts struts".

Seguidamente añadimos al web.xml (archivo que describe la aplicación web) el Servlet de Struts, así como el su mapeo a todas aquellas solicitudes con terminación '.do', que son las que struts entiende que son un formulario, ya que en un principio, struts estaba orientado únicamente a formularios. También le añadimos una etiqueta 'load-on-startup, que sirve para que cuando arranquemos el jetty, se genere el servlet en ese mismo momento:

Así queda el web.xml.

Después creo el archivo de configuración de struts, al que hay que llamar 'struts-config.xml', y que hay que colocar en el directorio WEB-INF:
Ahora voy a crear el formulario en el archivo 'helloWorldStruts.jsp', empleando para ello etiquetas de struts. Esta página es la que enviará el action de struts del que hablé al principio, y que me mandará a una u otra página.
Creo otro jsp (hello.jsp) donde aparecerá la información generada por el formulario, siempre que en el mapping del action que tendremos que añadir después a 'struts-config.xml', el name sea "ok". Se podría enviar la información a cualquier página jsp, con sólo añadirle otra etiqueta forward que haga el reenvío dependiendo del nombre del action, pero esto se verá un poco más abajo.
Seguidamente hay que crear la clase java (un javabean) que va a representar la información que viene del formulario, con sus métodos getter y setter, los cuales representan los campos del formulario que se esperan.
Esta clase (SaludoForm.java) tiene que heredar de la clase "org.apache.struts.action.ActionForm".

La acción que se va a ejecutar al enviar el formulario es una clase java que hereda de
"org.apache.struts.action.Action" y que sobreescribe el método 'public ActionForward execute'. En esta clase (saludoAction.java) creo un objeto 'SaludoForm' y le añado el nombre que viene del textbox del formulario. El método de la clase, al devolver un ActionForward, le mando "ok", que es lo que a continuación vamos a utilizar como nombre identificador para que nos reenvíe a otro jsp, en este caso a 'hello.jsp', creado previamente. En definitiva, esta clase tiene la responsabilidad de dirigir la acción hacia la vista correspondiente en función del desarrollo de la invocación del método.

Por último hay que indicarle al archivo de configuración de struts (
'struts-config.xml'), que la aplicación tiene una nueva acción que recibe un formulario (form-bean) y que la recibe una acción (action). Corro el jetty para ver que todo va bien.

Proyecto ClubDeMayores

martes, 1 de julio de 2008

Modelo Vista-Controlador (MVC)

A partir del proyecto del repositorio 'eticom-discografica-servlet', me lo bajo pero con otro nombre: 'eticom-discografica-servlet-mvc'.

El MVC separa los datos de una aplicación, la interfaz de usuario, y la lógica de control en tres componentes distintos. En una web...
  1. la vista es la página HTML o JSP (el código que provee de datos dinémicos a la página)
  2. el modelo es el sistema de gestion de base de datos y la lógica de negocio, representa la información con la que opera el sistema
  3. el controlador es el encargado de recibir los eventos de entrada desde la vista y de responder a ellos (=genera el modelo y, a su vez, crea la vista en jsp de la página que va a representar la solicitud del usuario).
En el MVC vamos a utilizar un JSP por cada una de las páginas, y sólo un controlador, que es el que va a generar los modelos y controla la solicitud.
Un diagrama sencillo que muestra la relación entre el modelo, la vista y el controlador. Nota: las líneas sólidas indican una asociación directa, y las punteadas una indirecta (por ejemplo, patrón Observer).

Los flujos que se producen en el MVC es el siguiente:
  • El usuario genera una solicitud al controlador (p.e. pulsa un botón)
  • El controlador recibe la notificación de la acción que el usuario quiere realizar a través de la vista, y gestiona el evento que llega.
  • El controlador accede al modelo, al que actualiza o modifica dependiendo de la acción que el usuario solicita.
  • El controlador delega a los objetos de la vista la tarea de desplegar la interfaz de usuario. La vista obtiene sus datos del modelo para generar la interfaz apropiada para el usuario, donde se reflejan los cambios en el modelo (el modelo no debe tener conocimiento directo sobre la vista)
  • La iterfaz de usuario espera nuevas solicitudes del usuario.
Si vemos el archivo web.xml, se ve que todas las solicitudes van a pasar por la página http://localhost:8080:controlador.

Para acceder a los atributos: ${requestScope.____}
Para acceder a los parámetros:
${param.____}

Si a ControladorFrontal.java le añado un nuevo atributo:
req.setAttribute("webmaster", "rafakatu@gmail.com");

...y en el index.jsp llamamos a ese atributo: ${requestScope.webmaster}
...si abrimos la http://localhost:8080/Controlador nos aparece ese atributo por pantalla.

Enlaces: wikipedia.

EL - Expression Languaje

Lenguaje que sirve para evaluar expresiones.

Se emplea la sintaxis: ${___.___}

Vamos a usar ${pageContext.servletContext}, ${pageContext.session}, ${pageContext.request}, ${pageContext.response}

${param.id}

${pageScope}, ${requestScope}, ${sessionScope.usuario.nombre}, ${applicationScope}

En la expresión ${sessionScope.usuario.nombre}, la propiedad nombre tiene que tener los getter y setter, por lo que aquí se hace una llamada al nombre del usuario, por lo que accedemos a la base de dato sin realizar ninguna consulta.

Operadores para operar con los valores, literales, etc..

Mirar por nuestra cuenta: funciones y demás..

Enlaces: Expression Languaje.

lunes, 30 de junio de 2008

i18n Internacionalización en jsp con etiquetas

La internacionalización se emplea para realizar traducciones de partes de la web en determinados idiomas, dependiendo de donde sea el usuario que accede a la misma, teniendo una por defecto y otra(s) determinada(s) por el diseño de desarrollo.

Para realizar el proceso de internacionalización necesitamos incluir en el pom.xml (del proyecto que estemos tratando, en mi caso el de ayer: eticom-discografica-servlet-JSTL),
la dependencia 'standar-1.1.2.jar' (en mi caso ya la añadimos ayer).

Los distintos idiomas que vamos a emplear se crean a partir de distintos ficheros con distintas traducciones, teniendo uno por defecto (Nombre.properties), que normalmente es en inglés, y luego los concretos, cuyo nombre es igual pero con el distintivo del idioma: Nombre_en.properties (inglés), Nombre_es.properties (español), etc. Estos archivos van situados en el source folder 'src/main/resources'.

En mi caso he creado 3 files: Discografica.properties (por defecto),
Discografica_es.properties y Discografica_en.properties, en las que he inlcuido las claves y sus correspondientes traducciones.

Ahora realizo la importación de la librería 'fmt' en la página .jsp que quiera, yo lo hago en index.jsp:

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

Seguidamente cargo el archivo de traducciones, el cual hay que cargar una vez por cada página .jsp:

<fmt:setBundle basename="Discografica"/>

Para mostrar las traducciones:

<h2><fmt:message key="hola"/></h2>
<h2><fmt:message key="webmaster"/></h2>

Hay que tener muy en cuenta, que para no tener que cargar las traducciones en cada una de las páginas jsp, hay que indicar las traducciones en el archivo 'web.xml' añadiendole este código:

<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>Discografica</param-value>
</context-param>

El resultado del web.xml.

enlaces: foro.

JSTL y etiquetas personalizadas

JSTL (JavaServer Pages Standard Tag Library): sirve para separar en un JSP, el código java del código de representación.

Partiendo del proyecto del viernes (eticom-discografica-servlet), vamos a modificarlo empleando etiquetas personalizadas, que son etiquetas de uso parecido a las etiquetas HTML para la representación de datos en el archivo jsp (Servlet). Este proyecto es el "
eticom-discografica-servlet-JSTL".
Lo primero que haremos será crear una nueva dependencia (Maven/add dependency):



Ahora hacemos una clase (SimpleTag.java) que extienda de TagSupport.
Implemento los métodos 'doStartTag' y 'doEndTag', a través de la ruta menú Contextual/source/Override/Implements Methods. Esta clase va a servir para representar su contenido con un formato determinado, en este caso vamos a aplicarle color a un texto. La clase queda así: SimpleTag.java. Como se puede ver, se han implementado los getter y setter de los atributos (color y mensaje).

Después creamos el TLD (Tag Library Descriptor), es decir, el archivo librería donde vamos a describir las etiquetas que vamos a usar. Así pues, creamos una carpeta llamada TLD en la carpeta WEB-INF de nuestro proyecto, y dentro de ella el archivo 'simple.tld'. El resultado de este archivo es este: simple.tld.

Ahora tenemos que definir las librerías de etiquetas en el archivo web.xml. Incluimos la creada anteriormente (simple.tld). El archivo queda así: web.xml (solo hemos añadido la etiqueta jsp-config, lo demás estaba ya).

Finalmente importamos la librería en nuestro archivo JSP. Esto es lo que hay que incluir:


...yo lo añado en mi 'index.jsp'. uri="/simple" indica el lugar donde está la librería, y prefix="ex" indica que las etiquetas que comiencen con ex pertenecen a 'simple.tld'. Podíamos haber puesto cualquier otro prefijo. Si en la etiqueta donde he puesto el colo y el mensaje (ex:simpleTag color="red" mensaje="discografia con TLDs") no pongo el atributo mensaje, me sale el mensaje por defecto, que es el que pusimos en la clase SimpleTag.java, en mi caso "Hola bola Tag!!!". Igual ocurre con el color, que en la clase tengo por defecto el color negro, por lo que si omito el atributo color a la etiqueta, en vez del color que pongamos en la etiqueta, aparecerá el color por defecto.

Ahora arrancamos el servidor jetty ejecutamos en la barra de direcciones del navegador la direccion http://localhost:8080/ y vemos que nos sale el texto "discografica con TLDs" en rojo.


-------------------

Ahora vamos a crear otra etiqueta dentro del simple.tld, para lo cual tenemos que crear otra clase (ImgTag.java). Luego en simple.tld, creamos otra etiqueta 'tag' de nombre 'imgTag'. Ya en el archivo jsp, creamos otra etiqueta, en este caso etiqueta imgTag: --ex:imgTag url="http://www.....jpg"--

-------------------

Para poder utilizar librerías estandars (incluídas en la especificación de JSP) vamos a incluir una nueva dependencia en pom.xml: el 'taglibs standard' version 1.1.2.
Estas librerías estandars son:
  • core: para iteraciones, condicionales, manipulación de URLs y otras funciones generales.
  • xml: para la manipulación de XML y para XML-Transformation.
  • sql: para gestionar conexiones a bases de datos.
  • i18n: para la internacionalización y formateo de las cadenas de caracteres como cifras.
  • fn:
Una vez añadida la dependencia, y dentro del JSP, podemos hacer referencia a las librerías a través de los imports:

<%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>

<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

<%@taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>

<%@taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x" %>

Para ver ejemplos relacionados con la librería 'core', pincha en el ejemplo index.jsp.

Enlaces de interés: Librerías de etiquetas, JSTL