Archive

Posts Tagged ‘Spring’

Como usar el MultiActionController de Spring 2.5

March 4th, 2009

Hola spring adictos,

Esta vez les mostrare un pequeño ejemplo de como usar el MultiActionController de Spring 2.5

Descripción del ejemplo

Bueno, esta pequeña aplicación lo único que hace es mostrar un formulario con un solo campo que corresponde al nombre de una mascota. Cada vez que se hace submit del nombre de la mascota, esta se adiciona a una lista en session llamada pets (no recomiendo usar variables en session). Luego esta lista se va desplegando en la parte inferior del formulario.

Para este ejemplo voy a asumir que ya tienen las librerías de spring y también configurado en el archivo web.xml de tu aplicación.

A  grandes rasgos lo que vamos a hacer es lo siguiente:

  • Creamos el bean Pet (solo para los propósitos de este ejemplo)
  • Crear y declarar PetController en el contexto de spring.
  • Crear el view JSP y declararlos en el contexto de spring.
  • Probar la funcionalidad.

Creamos el bean Pet (solo para los propósitos de este ejemplo)

package bo.sumasoftware.hellospring;
/**
 * @author renan
 */
public class Pet {
    String name;
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
}

Este bean, es solo para nuestro ejemplo y solo tiene una propiedad llamada name con su respectivo get y set. Se utilizara para leer datos del formulario y tambien para desplegar.

Crear y declarar PetController en el contexto de spring.

package bo.sumasoftware.hellospring;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.ArrayList;
 
/**
 * @author renan
 */
public class PetController extends MultiActionController {
    /**
     * This is called form http://localhost:8080/<context>/pet.do?method=form
     *
     * @param request
     * @param response
     * @param pet
     * @return
     */
    public ModelAndView form(HttpServletRequest request, HttpServletResponse response, Pet pet) {
        if(pet.getName()!=null){
            List pets = (List) request.getSession().getAttribute("pets");
            if(pets == null) {
                pets = new ArrayList();
                request.getSession().setAttribute("pets",pets);
            }
            pets.add(pet);
        }
        ModelAndView mav = new ModelAndView("pet");
        mav.getModel().put("pet", new Pet());
        return mav;
    }
}

Fuiu, es un poco largo la clase no? :)  pero ni modo, lo mas importante es que que estamos declarando un método con el nombre form, por si acaso esto no es un nombre especial ni nada por el estilo, puede ser cualquier nombre que ustedes definan. Lo importante es saber solo usando este nombre se podrá llamar a este método desde url o formulario.

pet, es el nombre del beanForm o commandName como se lo llama en spring. Es en este objeto que spring colocar los valores de los import del html from que viene del browser. Algo también interesante es que no es requerido definir este parámetro, también se puede colocar otros, mas información en http://static.springframework.org/spring/docs/2.0.x/reference/mvc.html#mvc-controller-multiaction.

pets, es la lista que desplegaremos en el jsp, lo interesante es que se hace proceso para crearla si no esta en session.

new ModelAndView(”pet”), de esta forma le decimos a spring a que view queremos que direccione la salida del controller.

ahora veremos como se define el controller en el contexto de spring

<bean name="/pet.do" class="bo.sumasoftware.hellospring.PetController">
	<property name="methodNameResolver">
		<bean class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
			<property name="paramName" value="method"/>
		</bean>
	</property>
</bean>

/pet.do,  es la forma de mapear la llamada desde un url. Cabe señalar que esta forma de mapeo es una de las mas basicas, spring tienes algunas como por ejemplo basado en archivo xml y tambien archivo de propiedades. ParameterMethodNameResolver, este es el que me interesa mas, con esto le estamos diciendo al controller como se van a llamar a sus metodos. Aca estamos definiendo que para llamar a algun metodo de la clase PetController, ya sera por un get(url) o post(formulario) se tiene que incluir como dato un valor llamado ‘method‘, esta variable contendra el nombre del metodo dentro del controller que queremos llamar. (para el emplo el valor que tendra sera ‘form’)

Crear el view JSP y declararlos en el contexto de spring.

Creamos un archivo con el nombre pet.jsp dentro de un folder llamado /jsp. (mas adelante la explicacion del por que)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 
<html>
<head><title>Pet</title></head>
<body>
<form:form action="pet.do" method="post" commandName="pet">
    <h4>Pet</h4>
    Pet Name:<form:input path="name"/><br/>
    <input type="hidden" name="method" value="form"/><br/>
    <input type="submit"/>
</form:form>
<h4>pets</h4>
<c:forEach items="${sessionScope.pets}" var="pet">
    ${pet.name} <br/>
</c:forEach>
 
</body>
</html>

Este jsp, no estan largo. que bueno :), la primera parte solo es para definir los tags que vamos a usar en este caso el tag form de spring y el tag c de jstl.

Como veran se define un formulario donde se define que el action sera pet.do, osea que cuando se haga submir del formulario el request se dirigira a este. Despues se define tambien un input, que sirve para declarar un input field, que tiene el nombre name.

name=”method” value=”form”, este es el mas, mas importante, acá indicamos cual sera el método a llamar del controller, sino hacemos esto, les aseguro que tendremos muchos dolores de cabeza. Cabe tambien señalar que no es necesario que sea una constante, puede cambiar, lo puedes setear con java script o algun otro truco que conozcas. Lo importante es enviar un valor.

Despues lo que hacemo es iterar una lista que esta en session que se llama pets, se despliega el nombre y nada mas.

Ahora a mapear las views

Bueno, esta es la forma mas basica de mapear view, todos los jsps tienen que estar dentro de el folder /jsp/. Como es tan basica y tambien la mas sencilla  a veces uno no se da cuenta como es que se puede llamar a una view especifica. :)

La clave esta en la clase ModelAndView en el controller, si vuelven al codigo del controller veran que hay una sentencia como esta: new ModelAndView(”pet”). Lo que hara spring es buscar un archivo pet.jsp que este dentro de la carpeta jsp.

Probar la funcionalidad.

Ahora a probar,  el url para llamar al controller sera:

http://localhost:8080/hello/pet.do?method=form

Como veran, estoy colocando como paremetro extra que metodo del controller voy a llamar.

Luego aparecera un formulario como esto:

hellospring1

En el input field pueden colocar nombres de sus mascotas y veran que se iran adicionando en una lista debajo de la palabra pets.

Finalmente para aquellos que quieren ver algo mas, acá tengo el código fuente. (para los que usan maven, tambien esta el pom.xml, para los que no, tendran que incluir los jars necesarios)

Encontré un buen post acerca de como funciona el SpringMVC veanlo.

Comentarios son bien recibidos, hasta la próxima :)



Renan Huanca Spring , ,

Como configurar una aplicacion basica Spring 2.5 con Maven 2

February 28th, 2009

Hola java adictos,

Esta vez mostrare como crear una aplicación Spring con Maven :)

Descripción del Ejemplo

Se creara una aplicación que simplemente mostrar “Hello World with Spring :) “. El mensaje sera obtenido de un bean llamado Greeting.

Vamos asumir que ya tienen instalado maven2, y java :), no sera necesario que bajen Spring ya que el mismo maven lo hara por ustedes.

A grandes rasgos, los pasos serán los siguientes:

  • Crear aplicación base con maven.
  • Editar pom.xml para adicionar dependencia base de Spring.
  • Crear el bean Greeting.
  • Crear archivo de contexto de aplicación de Spring.
  • Modificar clase App y para probar funcionalidad.

Crear aplicación base con maven

Para esto vamos a hechar mano del comando mvn archetype:create. Nos posicionaremos en el folder donde deseemos trabajar y ejecutamos el siguiente comando:

mvn archetype:create -DgroupId=com.sumasoftware.hellospring -DartifactId=HelloSpring

Con la ejecución del anterior comando se creara un folder llamado HelloSpring

con la respectiva estructura de directorios de maven.

(Justo vi un post en otro blog sobre este aspecto, asi que pueden verlo para mas detalles)

Editar pom.xml para adicionar dependencia base de Spring

Ingresamos al folder llamado HelloSpring y editamos el archivo con cualquier editor a disposición.

Sera algo parecido a esto:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.sumasoftware.hellospring</groupId>
    <artifactId>HelloSpring</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>HelloSpring</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

Dentro del tag <dependencies> adicionamos:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring</artifactId>
    <version>2.5.6</version>
</dependency>

Como verán solo vamos a utilizar el core de spring, osea la base. Esto es suficiente para lo que necesitamos ahora. Por supuesto para una aplicación mas compleja necesitaríamos adicionar mas dependencias (ej.: spring-context, spring-tx, spring-web, etc…)

Crear el bean Greeting

Ok. ahora vamos al código. por fin!:) pero es algo fácil. Vamos a crear el siguiente bean Greeting en el folder HelloSpring/src/main/java/com/sumasoftware/hellospring. (Ojo, que com/sumasoftware/hellospring es el paquete de la clase :))

package com.sumasoftware.hellospring;
public class Greeting {
    public void sayHello(){
        System.out.println("Hello World with Spring :)");
    }
}

Ahora ejecutamos en la consola el comando:

mvn package

Con esto se verifica que no hay errores de sintaxis y se aprovecha de bajar las dependencias.

Crear archivo de contexto de aplicacion de Spring

Ahora vamos con spring, eeeh!!! :). Para esto vamos a crear el archivo appContext.xml dentro de un folder nuevo llamado resources que estara dentro de HelloSpring/src/main. Entonces el path del archivo sera HelloSpring/src/main/resources/appContext.xml.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    <bean id="greeting" class="com.sumasoftware.hellospring.Greeting"/>
</beans>

Modificar clase App y para probar funcionalidad

Por defecto, cuando maven crea una aplicacion, crea la clase App que solo tiene un Hello World vamos a modificar la clase, para que cargue el contexto de spring, obtenga el bean y llame al metodo sayHello().

package com.sumasoftware.hellospring;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * Hello world!
 *
 */
public class App
{
    public static void main( String[] args )
    {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("classpath:appContext.xml");
        Greeting greeting = (Greeting) context.getBean("greeting");
        greeting.sayHello();
    }
}

Mas referencia acerca de como crear o instanciar el factory lo encuentra en la documentación de Spring

Listo ya terminamos, ahora como lo ejecutamos :)? bueno yo lo hice con idea. justo maven tiene un otro plugin que se llama idea que te ayuda a crear el archivo de projecto configurado con las dependencias. Solo se tiene que escribir en la linea de comando mvn idea:idea, maven crea el archivo de proyecto, abrimos el proyecto configuramos la clase main y listo. (Lo mismo hay para eclipse)

Claro te también se puede ejecutar desde linea de comando. Solo que es mas trabajoso, ustedes elijan el que mas les guste.

Una vez ejecutada la clase App, esta despliega en consola lo siguiente:

Feb 28, 2009 1:19:19 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@32fb4f: display name [org.springframework.context.support.ClassPathXmlApplicationContext@32fb4f]; startup date [Sat Feb 28 01:19:19 BOT 2009]; root of context hierarchy
Feb 28, 2009 1:19:19 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [appContext.xml]
Feb 28, 2009 1:19:19 AM org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
INFO: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@32fb4f]: org.springframework.beans.factory.support.DefaultListableBeanFactory@16a786
Feb 28, 2009 1:19:19 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@16a786: defining beans [greeting]; root of factory hierarchy
Hello World with Spring :) 

Espero este tutorial sirva de mucha ayuda. Acá esta el código fuente. Comentarios son bien recibidos.

Hasta la proxima ;)

Renan Huanca Spring, maven ,

How to use transacions with Spring 2.5 AOP and Hibernate 3.2.5

February 25th, 2009

Hello friends.

The first time when i was training to use spring and hibernate i wanted to avoid to open and close transaction manually in every method that does some transaction.

   i.e. (pseudo code)
       void createSomeObject(par1, par2, par3) {
           open transaccion
           create object using the given parameters
           persist the object
           close transaction
       }

So i found that spring helps you to do that.

I will assume that you already created the Java Bean (POJO) and it’s hibernate mapping file. ( SomePOJO.java and SomePOJO.hbm.xml files).

1. Define AOP and Transaction  namespace in spring application context configuration file. (Find more about AOP and Transaction Management)

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
       ... ...
</beans>

2. Define data source to configure the database connection parameters.

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="org.postgresql.Driver"/>
    <property name="url" value="jdbc:postgresql://localhost/somedb"/>
    <property name="username" value="someuser"/>
    <property name="password" value="somepassword"/>
</bean>

3. Define Hibernate SessionFactory.

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="mappingResources">
        <list>
            <value>/some/package/model/SomePOJO.hbm.xml</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <value>
            hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
        </value>
    </property>
</bean>

4. Define Transaction aspect. (more info)

<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

5. Define point cuts in your service.

<aop:config>
    <aop:pointcut id="someServiceMethods" expression="execution(* some.package.service.SomeService.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="someServiceMethods"/>
</aop:config>

Spring will begin a transaction each time a method in SomeService is called. This behavior can be changed (see) , I just tried to do the example the most simple as possible.

I will try to prepare some package with source code. just let me know. :)
Regards

-Renan

Renan Huanca Spring , ,