Me gustaría saber cuál es la forma más limpia y mejor de realizar la validación de formularios de las entradas de los usuarios. He visto algunos desarrolladores implementar org.springframework.validation.Validator
. Una pregunta sobre eso: vi que valida una clase. ¿La clase tiene que llenarse manualmente con los valores de la entrada del usuario y luego pasar al validador?
Estoy confundido acerca de la forma más limpia y mejor para validar la entrada del usuario. Sé sobre el método tradicional de usar request.getParameter()
y luego verificar manualmente nulls
, pero no quiero hacer toda la validación en mi Controller
. Algunos buenos consejos sobre esta área serán muy apreciados. No estoy usando Hibernate en esta aplicación.
java
spring-mvc
validation
user-input
devdar
fuente
fuente
Respuestas:
Con Spring MVC, hay 3 formas diferentes de realizar la validación: usando anotaciones, manualmente o una combinación de ambas. No existe una "forma más limpia y mejor" única para validar, pero probablemente haya una que se adapte mejor a su proyecto / problema / contexto.
Tengamos un usuario:
Método 1: si tiene Spring 3.x + y una validación simple que hacer, use
javax.validation.constraints
anotaciones (también conocidas como anotaciones JSR-303).Necesitará un proveedor JSR-303 en sus bibliotecas, como Hibernate Validator que es la implementación de referencia (esta biblioteca no tiene nada que ver con bases de datos y mapeo relacional, solo valida :-).
Luego, en su controlador, tendría algo como:
Observe el @Valid: si el usuario tiene un nombre nulo, result.hasErrors () será verdadero.
Método 2: Si tiene una validación compleja (como lógica de validación de grandes empresas, validación condicional en múltiples campos, etc.), o por alguna razón no puede usar el método 1, use la validación manual. Es una buena práctica separar el código del controlador de la lógica de validación. No cree su (s) clase (s) de validación desde cero, Spring proporciona una
org.springframework.validation.Validator
interfaz práctica (desde Spring 2).Entonces digamos que tienes
y desea hacer una validación "compleja" como: si la edad del usuario es menor de 18 años, el usuario responsable no debe ser nulo y la edad del usuario responsable debe ser mayor de 21 años.
Harás algo como esto
Entonces en su controlador tendría:
Si hay errores de validación, result.hasErrors () será verdadero.
Nota: También puede configurar el validador en un método @InitBinder del controlador, con "binder.setValidator (...)" (en cuyo caso no sería posible un uso mixto de los métodos 1 y 2, ya que reemplaza el valor predeterminado validador). O podría crear una instancia en el constructor predeterminado del controlador. O tenga un @ Component / @ Service UserValidator que inyecte (@Autowired) en su controlador: muy útil, porque la mayoría de los validadores son singletons + la prueba de unidad se burla más fácilmente + su validador podría llamar a otros componentes Spring.
Método 3: ¿Por qué no usar una combinación de ambos métodos? Valide las cosas simples, como el atributo "nombre", con anotaciones (es rápido, conciso y más legible). Mantenga las validaciones pesadas para los validadores (cuando tomaría horas codificar anotaciones de validación complejas personalizadas, o simplemente cuando no es posible usar anotaciones). Hice esto en un proyecto anterior, funcionó de maravilla, rápido y fácil.
Advertencia: no debe confundir el manejo de validación con el manejo de excepciones . Lea esta publicación para saber cuándo usarlos.
Referencias
fuente
Hay dos formas de validar la entrada del usuario: anotaciones y heredando la clase Validator de Spring. Para casos simples, las anotaciones son agradables. Si necesita validaciones complejas (como la validación de campo cruzado, por ejemplo, el campo "verificar dirección de correo electrónico"), o si su modelo está validado en varios lugares de su aplicación con reglas diferentes, o si no tiene la capacidad de modificar su modelo de objeto colocando anotaciones en él, el Validador basado en herencia de Spring es el camino a seguir. Mostraré ejemplos de ambos.
La parte de validación real es la misma independientemente del tipo de validación que esté utilizando:
Si está utilizando anotaciones, su
Foo
clase podría verse así:Las anotaciones anteriores son
javax.validation.constraints
anotaciones. También puedes usar Hibernate'sorg.hibernate.validator.constraints
, pero no parece que esté usando Hibernate.Alternativamente, si implementa Spring's Validator, crearía una clase de la siguiente manera:
Si usa el validador anterior, también debe vincular el validador al controlador Spring (no es necesario si usa anotaciones):
Ver también Spring docs .
Espero que ayude.
fuente
Foo
parámetro en el método del controlador. ¿Puedes aclarar?Me gustaría extender la buena respuesta de Jerome Dalbert. Encontré muy fácil escribir sus propios validadores de anotación en forma JSR-303. No está limitado a tener la validación de "un campo". Puede crear su propia anotación a nivel de tipo y tener una validación compleja (consulte los ejemplos a continuación). Prefiero esta forma porque no necesito mezclar diferentes tipos de validación (Spring y JSR-303) como lo hace Jerome. Además, estos validadores son "conscientes de Spring", por lo que puede utilizar @ Inject / @ Autowire fuera de la caja.
Ejemplo de validación de objeto personalizado:
Ejemplo de igualdad de campos genéricos:
fuente
ElementType.METHOD
en@Target
.Si tiene la misma lógica de manejo de errores para diferentes manejadores de métodos, entonces terminaría con muchos manejadores con el siguiente patrón de código:
Suponga que está creando servicios RESTful y desea regresar
400 Bad Request
junto con mensajes de error para cada caso de error de validación. Entonces, la parte de manejo de errores sería la misma para cada punto final REST que requiera validación. ¡Repetir esa misma lógica en cada controlador no es tan SECO !Una forma de resolver este problema es eliminar el elemento inmediatamente
BindingResult
después de cada bean To-Be-Validated . Ahora, su controlador sería así:De esta manera, si el bean enlazado no era válido,
MethodArgumentNotValidException
Spring lanzará un a. Puede definir unControllerAdvice
que maneje esta excepción con la misma lógica de manejo de errores:Todavía puede examinar el subyacente
BindingResult
utilizando elgetBindingResult
método deMethodArgumentNotValidException
.fuente
Encuentre un ejemplo completo de validación Spring Mvc
fuente
Pon este bean en tu clase de configuración.
y luego puedes usar
para validar un bean manualmente. Entonces obtendrá todos los resultados en BindingResult y podrá recuperarlos desde allí.
fuente