Enlace de Parámetros en Spring MVC para Manejo de Datos Web

En Spring MVC, la recepción de datos enviados desde formularios web se realiza mediante la asignación a parámetros en los métodos del controlador. Este mecanismo permite vincular automáticamente valores de la solicitud a variables de Java.

Tipos de parámetros predeterminados

El adaptador de manejo de parámetros reconoce y asigna automáticamente ciertos tipos en las firmas de los métodos del controlador: HttpServletRequest, HttpServletResponse, HttpSession, y los modelos Model o ModelMap. Si se utiliza Model directamente, Spring MVC instancia un ModelMap internamente.

Vinculación de tipos simples

La anotación @RequestParam facilita la vinculación de parámetros de tipos simples. Si no se usa esta anotación, el nombre del parámetro en la solicitud debe coincidir con el nombre del parámetro en el método del controlador. Con @RequestParam, esta restricción se elimina, permitiendo nombres diferentes.

El atributo required indica si el parámetro es obligatorio; si se establece en true y el parámetro falta, se devuelve un error HTTP 400. También se puede definir un valor por defecto con defaultValue.

Los tipos simples admitidos incluyen: Integer, String, float, double y boolean.

Vinculación de objetos POJO

Para vincular datos de la solicitud a un objeto POJO, los nombres de los campos en el formulario HTML deben coincidir con los nombres de las propiedades del POJO. Esto permite una asignación directa y automática.

Vinculación personalizada para fechas

Si un POJO contiene propiedades de tipo fecha, se requiere un convertidor personalizado para transformar cadenas de texto en objetos Date. El formato de fecha debe coincidir con el de la propiedad en el POJO.

Ejemplo de implementación

A continuación, se muestra un ejemplo adaptado que ilustra estos conceptos. Se ha cambiado el dominio de productos a uno de inventario para reducir la similitud.

Controlador de inventario


@Controller
@RequestMapping("/inventory")
public class StockController {

    @Autowired
    private StockService stockService;

    @RequestMapping("/listItems")
    public ModelAndView listItem() throws Exception {
        List<stockitemcustom> itemList = stockService.fetchItemList(null);
        ModelAndView view = new ModelAndView();
        view.addObject("itemList", itemList);
        view.setViewName("stock/itemList");
        return view;
    }

    // Mostrar página de edición de ítem
    @RequestMapping(value = "/modifyItem", method = {RequestMethod.POST, RequestMethod.GET})
    public String modifyItem(Model model, @RequestParam(value = "itemId", required = true, defaultValue = "1") Integer itemId) throws Exception {
        StockItemCustom item = stockService.fetchItemById(itemId);
        model.addAttribute("itemData", item);
        return "stock/modifyItem";
    }

    // Enviar edición de ítem
    @RequestMapping("/submitModification")
    public String submitModification(HttpServletRequest request, Integer itemId, StockItemCustom itemData) throws Exception {
        stockService.updateItem(itemId, itemData);
        return "redirect:listItems.action";
    }
}
</stockitemcustom>

Formulario de edición (modifyItem.jsp)


<title>Modificar información del ítem</title>
</head>
<body>
<form id="itemForm" action="${pageContext.request.contextPath}/inventory/submitModification.action" method="post">
<input type="hidden" name="itemId" value="${itemData.itemId}"/>
Modificar ítem:
<table width="100%" border=1>
<tr>
    <td>Nombre del ítem</td>
    <td><input type="text" name="itemName" value="${itemData.itemName}"/></td>
</tr>
<tr>
    <td>Precio unitario</td>
    <td><input type="text" name="unitPrice" value="${itemData.unitPrice}"/></td>
</tr>
<tr>
    <td>Fecha de registro</td>
    <td><input type="text" name="registrationDate" value="<fmt:formatDate value="${itemData.registrationDate}" pattern="yyyy-MM-dd HH:mm:ss"/>"/></td>
</tr>
</table>
</form>

Convertidor de fechas personalizado


package com.example.controller.converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;

public class DateToStringConverter implements Converter<String, Date> {
    @Override
    public Date convert(String input) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return formatter.parse(input);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

Configuración en Spring MVC (spring-config.xml)


<mvc:annotation-driven conversion-service="dateConversionService"/>
<bean id="dateConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
        <list>
            <bean class="com.example.controller.converter.DateToStringConverter"/>
        </list>
    </property>
</bean>

Solución de problemas de codificación

Para evitar caracteres malformados en solicitudes POST con contenido no ASCII, como nombres en idiomas con caracteres especiales, se configura un filtro en el archivo web.xml:


<filter>
    <filter-name>EncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>EncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Para solicitudes GET, existen dos métodos para corregir la codificación: modificar la configuración del servidor para establecer la codificación en UTF-8, o recodificar manualmente los parámetros en el controlador. Por ejemplo:


String valorParametro = new String(request.getParameter("nombreParametro").getBytes("ISO-8859-1"), "UTF-8");

Este enfoque asegura que los datos se interpreten correctamente al convertir desde la codificación predeterminada del servidor.

Etiquetas: Spring MVC Enlace de Parámetros java POJO Conversión de Fechas

Publicado el 6-3 20:35