Añadir nuestro modelo en un SimpleFormController de Spring MVC Framework

De ChuWiki

La documentación de Spring Framework nos muestra más o menos claramente cómo hacer una página con un formulario para añadir/editar datos usando SimpleFormController http://static.springsource.org/docs/Spring-MVC-step-by-step/part4.html#step4.5

Sin embargo, es posible que en ese formulario (o fuera de él pero en la misma página) queramos tener disponibles otros datos de nuestro modelo para "dibujar" otras cosas en la página que no sea el formulario. Un ejemplo típico sería tener una página con una lista de datos y justo al final un pequeño formulario para añadir un dato nuevo a esea lista, sin necesidad de crear dos páginas, una para la lista y otra para el formulario. Si tenemos una clase "Proyecto", con un atributo "nombre", la página podía ser como esta

<%@ page session="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

<html>
<head>
<title><fmt:message key="title" /></title>
<style>
.error {
	color: red;
}
</style>

</head>
<body>

<!-- La lista de proyectos -->
<table>
    <c:forEach items="${model.proyectos}" var="proyecto">
        <tr>
            <td><c:out value="${proyecto.nombre}" /></td>
    </c:forEach>
</table>

<!-- El formulario para añadir un nuevo proyecto -->
<form:form method="post" commandName="addProyecto">
    Nombre:
    <form:input path="nombre" />
    <input type="submit" align="center" value="Add"/>
</form:form>
</body>
</html>

Como queremos que la página sea la misma, en la definición del bean SimpleFormController debemos poner que el form y el successView son la misma

    <bean name="/proyectolist.htm" class="com.chuidiang.ejemplo_spring.web.ProyectoController">
        <property name="sessionForm" value="true" />
        <property name="commandName" value="addProyecto" />
        <property name="commandClass" value="com.chuidiang.ejemplo_spring.domain.Proyecto" />

        <!-- Ambas vistas son la misma -->
        <property name="formView" value="proyectolist" />
        <property name="successView" value="proyectolist.htm" />
    </bean>

Y esta sería nuestra implementación normal del método onSubmit() de nuestro SimpleFormController (proyectoManager seria la clase que nos permite guardar y acceder a los proyectos en base de datos o donde los tengamos).

    public ModelAndView onSubmit(Object command) throws Exception {
        Proyecto proyecto = (Proyecto) command;

        proyectoManager.add(proyecto);

        return new ModelAndView(new RedirectView(getSuccessView()));
    }

Bien. ¿Cómo hacemos ahora para meter en el modelo los datos de nuestra lista, es decir, un {"model" {"proyectos", List<Proyecto>}}. Hay un método de SimpleFormController al que se llama cuando se visualiza la página. Este método es referenceData(), ahí podemos devolver un Map con los datos que queramos y a esté Map se añadirá al ModelAndView devuelto por la página.

    @Override
    protected Map referenceData(HttpServletRequest request) throws Exception {
        Map<String, Object> proyectos = new HashMap<String, Object>();
        proyectos.put("proyectos", proyectoManager.getProyectos());

        Map<String, Object> modelo = new HashMap<String, Object>();
        modelo.put("model", proyectos);

        return modelo;
    }

Listo, con esto tenemos los datos con los que alimentamos al

del primer jsp que mostramos.