Validando un formulario en JSP

Estoy validando un formulario simple usando Spring e Hibernate en JSP (usando SimpleFormController) con la ayuda de HibernateValidator como se explica aquí. El formulario que contiene un solo campo es el siguiente.

<%@page contentType="text/html" pageEncoding="UTF-8" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>

<form:form method="post" id="userForm" name="userForm" action="Temp.htm" commandName="validationForm">          

    <table>
        <tr>
            <td>User Name:<font color="red"><form:errors path="userName" /></font></td>
        </tr>

        <tr>
            <td><form:input path="userName" /></td>
        </tr>               

        <tr>
            <td><input type="submit" value="Submit" /></td>
        </tr>
        </table>

</form:form>

La siguiente es la clase de comando en la que se definen los criterios de validación.

package validators;

import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;


final public class ValidationForm 
{
    @NotEmpty(message="Must not be left blank.")
    @Size(min = 1, max = 2)
    private String userName;

    public void setUserName(String userName)
    {
            this.userName = userName;
    }

    public String getUserName()
    {
            return userName;
    }        
}

El siguiente es el dispatchar-servlet.xml archivo donde se pueden realizar diferentes configuraciones.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:p="http://www.springframework.org/schema/p"
   xmlns:aop="http://www.springframework.org/schema/aop"              
   xmlns:mvc="http://www.springframework.org/schema/mvc"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
   http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">




<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />


<bean id="tempService" class="usebeans.TempServiceImpl" />
<bean id="tempController" class="controller.Temp" p:tempService-ref="tempService" p:formView="Temp" p:successView="Temp"/>

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename" value="/WEB-INF/messages" />
</bean>

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="index.htm">indexController</prop>
            <prop key="Temp.htm">tempController</prop>                
        </props>
    </property>
</bean>

<bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver"
      p:prefix="/WEB-INF/jsp/"
      p:suffix=".jsp" />

<bean name="indexController"
      class="org.springframework.web.servlet.mvc.ParameterizableViewController"
      p:viewName="index" />

Dónde TempService es una interfaz que contiene solo un método add(ValidationForm validationForm){...} y TempServiceImpl es una clase que implementa el TempService de la interfaz del.

La clase de controlador Temp es como sigue.

package controller;

import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import usebeans.TempService;
import validators.ValidationForm;

@SuppressWarnings("deprecation")
final public class Temp extends SimpleFormController
{
    private TempService tempService=null;
    public Temp()
    {            
        setCommandClass(ValidationForm.class);
        setCommandName("validationForm");
    }

    //This method may not be necessary.
    public void setTempService(TempService tempService) 
    {
        this.tempService = tempService;
    }

    @Override
    protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, @ModelAttribute("validationForm") @Valid Object command, BindException errors) throws Exception
    {
        ValidationForm validationForm=(ValidationForm) command;
        tempService.add(validationForm);   //May not be necessary.        

        if(errors.hasErrors())  //Never evaluates to true even though the text box on the form is left blank.
        {                
            System.out.println("User Name : "+validationForm.getUserName());
            //Or do something.
        }    
        else
        {
            //Do some stuff such as database operations like insert, update or delete. 
        }         

        ModelAndView mv=new ModelAndView("Temp", "validationForm", validationForm);
        return mv;
    }

    @Override
    protected ModelAndView showForm(HttpServletRequest request, HttpServletResponse response, BindException errors) throws Exception
    {            
        ModelAndView mv=new ModelAndView("Temp", "validationForm", new ValidationForm());
        return mv;
    }
}

Ahora, lo que está sucediendo aquí es que cuando se envía el formulario al hacer clic en el único botón Enviar en el formulario, el onSubmit() método en la clase del controlador Temp es invocada en la que estoy imponiendo una if condición if(errors.hasErrors()){}.

En consecuencia, si el único TextField en el formulario está vacío, el formulario que se está representando contiene errores de validación y el if La condición debe evaluarse como verdadera y debe mostrarse el mensaje de error especificado (como se especifica en el ValidationForm clase @NotEmpty(message="Must not be left blank.")) pero esto nunca sucede [El objeto de la ValidationForm está disponible a través del Object command parámetro de la onSubmit() Método]. La condición nunca se evalúa como verdadera, ya sea que el cuadro de texto contenga un valor o no.

¿Que me estoy perdiendo aqui? Siento que estoy siguiendo la forma incorrecta de usar HibernateValidator. Cualquier sugerencia o guía sería útil para mí.

[La aplicación se ejecuta sin errores, pero el formulario que se pretende validar no se valida]

preguntado el 30 de junio de 12 a las 19:06

1 Respuestas

Poner @Valid en parámetros de método no funciona con controladores antiguos que se extienden desde CommandController y sus hijos (por ejemplo, SimpleFormController). Es una característica de la AnnotationMethodHandlerAdapter, por lo que debe usar un controlador anotado para que funcione.

(¡Hay una razón por la que tuviste que suprimir una advertencia de obsolescencia en esa clase! :))

Versión del resumen del lector:

En lugar de definir su propio urlMapping y todo en el uso del despachador <mvc:annotation-driven/>

Luego, en lugar de extender desde SimpleFormController, simplemente crea una clase normal y la anota con @Controller y su método con @RequestMapping.

@Controller
@RequestMapping("/Temp.htm")
public class Temp {

@RequestMapping(method=RequestMethod.GET)
public ModelAndView getForm() {
  ModelAndView mv=new ModelAndView("Temp", "validationForm", new ValidationForm());
  return mv;
}

@RequestMapping(method=RequestMethod.POST)
public ModelAndView postForm(@Valid ValidationForm validationForm, BindingResult errors) {
        tempService.add(validationForm);   //May not be necessary.        

        if(errors.hasErrors())  //Never evaluates to true even though the text box on the form is left blank.
        {                
            System.out.println("User Name : "+validationForm.getUserName());
            //Or do something.
        }    
        else
        {
            //Do some stuff such as database operations like insert, update or delete. 
        }         

        ModelAndView mv=new ModelAndView("Temp", "validationForm", validationForm);
        return mv;
}

Hay toneladas de tutoriales en Internet con mucho más contenido del que puedo reproducir aquí. Consulte la versión actual de la aplicación de muestra Spring PetClinic para obtener ejemplos detallados.

Respondido el 30 de junio de 12 a las 20:06

¿Qué cambios debo hacer en mi código para que funcione entonces? ¿Me podrias decir por favor? - Minúsculo

aquí hay una versión rápida y sucia, consulte el tutorial de primavera para ver ejemplos detallados. - Mono

Hola @Affe. He cambiado la forma de validar formularios. ahora estoy usando Validator en lugar de HibernateValidator ya que actualmente tengo que trabajar con SimpleFormController aunque ya estaba en desuso. Acabo de implementar el método de validación de formulario con Validator Y funciona bien. Muchas gracias por su sugerencia. De hecho, estaba siguiendo la forma incorrecta de validar formularios que podría saber por su respuesta. Sin duda pondré en práctica el método que sugieres más tarde. - Minúsculo

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.