Como usar el MultiActionController de Spring 2.5
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:

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
Follow me on twitter
Hola, muy util y explicativo tu ejemplo. Me gusta q no sea tan complejo… es como un ‘Hello world’ para ver q hay q hacer para que todo funcione
Gracia!
Muchas gracias
si tienes sugerencias para futuros posts no dudes en decirme
Hola.
Muchas gracias por el tutorial, lo acabo de montar y me funciona correctamente. Requiere un conocimiento rebasico sobre Spring MVC, menos mal ya lo adquirí
Seria bueno que agregaras ejemplos utilizando otros controladores, te lo agradecerian muchos principiantes. Aun mejor, añadiendo la teoria explicada del controlador estudiado en cada ejemplo.
Saludos, muchas gracias
Muy bueno! excelente el post, pero lo puedes complementar?, “como?” hace falta un paso mas y es donde me he quedado,ej:
cuando tenemos un formulario cuyo controller extiende de simpleformcontroller, si queremos validar el form basta con:
*** //validar el formulario **********aqui
//donde está el validador
lo anterior nos permite visualizar mensajes de error, bajo o junto a cada imput, dependiendo de como lo ubicamos: , ahora como sería la validación cuando extendemos de MultiActionController? la validación la realizo pero no me permite ver los mensajes en el form, mi clase de validación que implementa org.springframework.validation.Validator, me puedes ayudar con esto? un saludo desde Ecuador!
no sale el codigo que te escribí como nos podemos poner en contacto?
hola puedes escribirme a renan@huanca.net
la validacion en este momento lo hago manualmente
Muy buena tu explicación, me ha ayudado mucho a realizar este controlador, algo que hacía de una forma más manual… en un solo método hadlerequest. Gracias
Consulta… ¿Por qué dices que no recomiendas usar variables en session?
Disculpa por responder tan tarde.
En realidad debo corregirme. lo que queria decir en realidad es que no recomiendo el abuso de variables en session, ya que estas variable ocupan memoria.
Hola lo primero gracias por tu tutorial.
Sabrias como hacerlo sin tener que devolver un ModelAndVieW?
Me explico, mediante una llamada ajax necesito que se ejecute un metodo mediante multiActionController, asta hay mi aplicación a llegado, lo malo es al devolver el objeto desde el método, tal y como esta explicado en el tutorial se devuelve una vista completa, que no es lo que yo necesito. Ademas no tiene compatibilidad con la llamada ajax puesto que la llamada siempre retorna a la funcion de error.
Sabrias darme alguna solucion.
Un saludo y gracias por tu tutorial.
Hola Marcos.
Disculpa por la tardanza en la respuesta.
Si se puede, solo tienes que hacer que el el método retorne void, escribir directamente en el objeto response tal como lo harias en una servlet.
Una vez mas disculpa por no haber respondido antes.
Renan
Buenas tardes, tras googlear un poco he aparecido en tu blog, que por cierto parece muy interesante. He estado analizando el controllerMultiaction, pero de momento creo que no es la solucion al problema que yo tengo. El problema es que yo tengo un formulario de login, configurado con el siguiente bean
Hasta hay todo bien, si yo introduzco la url, login.htm, me devuelve la vista correspondiente. El problema viene si yo desde otro controller, devuelvo la vista login, return new ModelAndView(”login”).
Me devuelve la siguiente excepcion: Neither BindingResult nor plain target object for bean name ‘login’ available as request attribute.
Entiendo que el problema viene porque no tengo bien configurado el servlet.xml o porque no lo devuelvo con el metodo correcto, pero las demas vistas las devuelvo asi y no me dan problemas.
Un saludo y gracias de antemano.
Habia introducido, la configuracion del bean en el xml, pero no se muestra el codigo.
bean id=”logueo” class=”springapp.web.LoginFormController”
property name=”formView” value=”login”
property name=”successView” value=”acceso” /
property name=”commandClass” value=”springapp.service.Login”/
property name=”commandName” value=”login”/
property name=”validator”>
bean class=”springapp.service.LoginValidator”/
/property
/bean