Wanneer we gebruikersinvoer accepteren in een webtoepassing, is het noodzakelijk om deze te valideren. We kunnen de gebruikersinvoer aan de clientzijde valideren met JavaScript, maar het is ook noodzakelijk om deze aan de serverzijde te valideren om ervoor te zorgen dat we geldige gegevens verwerken in het geval dat de gebruiker JavaScript heeft uitgeschakeld.
Spring-validatie
Spring MVC Framework ondersteunt standaard de JSR-303 specificaties en het enige dat we moeten doen is JSR-303 en de bijbehorende implementatiedependency’s toevoegen aan de Spring MVC-toepassing. Spring biedt ook de @Validator
-annotatie en de BindingResult
-klasse aan, waarmee we de fouten kunnen opvragen die zijn gegenereerd door de Validator-implementatie in de methode van de controllerverzoekhandler. We kunnen onze aangepaste validator-implementaties op twee manieren maken: de eerste is om een annotatie te maken die voldoet aan de JSR-303 specificaties en de Validator-klasse ervan implementeren. De tweede aanpak is om de org.springframework.validation.Validator
-interface te implementeren en deze in te stellen als validator in de Controller-klasse met behulp van de @InitBinder
-annotatie. Laten we een eenvoudig Spring MVC-project maken in Spring Tool Suite waarin we JSR-303 specificaties zullen gebruiken met de implementatie-artefact hibernate-validator. We zullen op annotaties gebaseerde formuliervalidatie gebruiken en onze eigen aangepaste validator maken op basis van de JSR-303 specificaties. We zullen ook onze eigen aangepaste validatorklasse maken door de Validator
-interface te implementeren en deze gebruiken in een van de controller-handlermethoden. Ons uiteindelijke project ziet eruit als de onderstaande afbeelding. Laten we elk van de componenten een voor een bekijken.
Spring MVC Form Validator
Onze uiteindelijke pom.xml-bestand ziet er als volgt uit. Afgezien van de standaard Spring MVC-artefacten, hebben we de dependencies validation-api en hibernate-validator in het project.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev</groupId>
<artifactId>spring</artifactId>
<name>SpringFormValidation</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.7</java-version>
<org.springframework-version>4.0.2.RELEASE</org.springframework-version>
<org.aspectj-version>1.7.4</org.aspectj-version>
<org.slf4j-version>1.7.5</org.slf4j-version>
</properties>
<dependencies>
<!-- Form Validation using Annotations -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.1.0.Final</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
Implementatie Beschrijving
Wanneer je een Spring MVC-project maakt vanuit STS, worden er twee contextconfiguratiebestanden aangemaakt. Ik heb het een beetje opgeruimd en heb slechts één Spring Bean-configuratiebestand. Mijn uiteindelijke web.xml-bestand ziet er als volgt uit.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/spring.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Spring Bean Configuratiebestand
Normaal gesproken kijken we pas naar de Spring-bedradingen als laatste, maar deze keer hebben we niet veel configuraties in het Spring Bean-configuratiebestand. Ons uiteindelijke spring.xml-bestand ziet er als volgt uit.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="https://www.springframework.org/schema/mvc"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="https://www.springframework.org/schema/beans"
xmlns:context="https://www.springframework.org/schema/context"
xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<beans:bean id="employeeValidator" class="com.journaldev.spring.form.validator.EmployeeFormValidator" />
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:message" />
<beans:property name="defaultEncoding" value="UTF-8" />
</beans:bean>
<context:component-scan base-package="com.journaldev.spring" />
</beans:beans>
Het enige belangrijke punt om op te merken is het employeeValidator
-bean dat we zullen injecteren in een van de controllers en het messageSource
-bean om gelokaliseerde gegevens uit resourcebundels te lezen. De rest van het gedeelte is ter ondersteuning van annotaties, view resolvers en het opgeven van het pakket om te scannen voor controllerklassen en andere componenten.
Model Klassen
We hebben twee modelklassen in dit project – de eerste waar we JSR-303 annotaties en onze op maat gemaakte annotatiegebaseerde validator zullen gebruiken en de tweede waar we alleen onze Validator-implementatie zullen gebruiken. Klasse Customer.java:
package com.journaldev.spring.form.model;
import java.util.Date;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat;
import com.journaldev.spring.form.validator.Phone;
public class Customer {
@Size(min=2, max=30)
private String name;
@NotEmpty @Email
private String email;
@NotNull @Min(18) @Max(100)
private Integer age;
@NotNull
private Gender gender;
@DateTimeFormat(pattern="MM/dd/yyyy")
@NotNull @Past
private Date birthday;
@Phone
private String phone;
public enum Gender {
MALE, FEMALE
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
Merk op dat we @Email, @NotEmpty en @DateTimeFormat annotaties gebruiken die aanvullend zijn op JSR-303 en worden geleverd door de Hibernate-validatorimplementatie. Enkele van de JSR-303 annotaties die we gebruiken zijn @Size, @NotNull, enz. De gebruikte @Phone-annotatie is onze op maat gemaakte implementatie op basis van JSR-303-specificaties, we zullen dit in de volgende sectie bekijken. Klasse Employee.java:
package com.journaldev.spring.form.model;
public class Employee {
private int id;
private String name;
private String role;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
De Employee is een standaard Java bean en we zullen onze aangepaste Validator-implementatie gebruiken om het formulier met de Employee bean te valideren.
Aangepaste Validator Implementaties
Telefoon.java-code:
package com.journaldev.spring.form.validator;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
import javax.validation.Constraint;
import javax.validation.Payload;
@Documented
@Constraint(validatedBy = PhoneValidator.class)
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Phone {
String message() default "{Phone}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
De meeste delen zijn standaardcode om te voldoen aan de JSR-303 specificaties. Het belangrijkste deel is de annotatie @Constraint
waar we de klasse opgeven die zal worden gebruikt voor validatie, d.w.z. PhoneValidator
. Code van PhoneValidator.java:
package com.journaldev.spring.form.validator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class PhoneValidator implements ConstraintValidator {
@Override
public void initialize(Phone paramA) {
}
@Override
public boolean isValid(String phoneNo, ConstraintValidatorContext ctx) {
if(phoneNo == null){
return false;
}
//valideer telefoonnummers in het formaat "1234567890"
if (phoneNo.matches("\\d{10}")) return true;
//valideer telefoonnummer met -, . of spaties
else if(phoneNo.matches("\\d{3}[-\\.\\s]\\d{3}[-\\.\\s]\\d{4}")) return true;
//valideer telefoonnummer met extensielengte van 3 tot 5
else if(phoneNo.matches("\\d{3}-\\d{3}-\\d{4}\\s(x|(ext))\\d{3,5}")) return true;
//valideer telefoonnummer waarbij het netnummer tussen haakjes staat ()
else if(phoneNo.matches("\\(\\d{3}\\)-\\d{3}-\\d{4}")) return true;
//geeft false terug als niets overeenkomt met de invoer
else return false;
}
}
Onze JSR-303 specificatie validator implementatie moet de javax.validation.ConstraintValidator
interface implementeren. Als we een bron zoals DataSource gebruiken, kunnen we deze initialiseren in de initialize()
methode. De validatiemethode is isValid
en retourneert true als de gegevens geldig zijn, anders moet deze false retourneren. Als je nieuw bent in reguliere expressies, kun je er meer over lezen op Java Regular Expressions Tutorial. Code van de klasse EmployeeFormValidator.java:
package com.journaldev.spring.form.validator;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import com.journaldev.spring.form.model.Employee;
public class EmployeeFormValidator implements Validator {
//welke objecten kunnen worden gevalideerd door deze validator
@Override
public boolean supports(Class > paramClass) {
return Employee.class.equals(paramClass);
}
@Override
public void validate(Object obj, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "id", "id.required");
Employee emp = (Employee) obj;
if(emp.getId() <=0){
errors.rejectValue("id", "negativeValue", new Object[]{"'id'"}, "id can't be negative");
}
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "name.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "role", "role.required");
}
}
De `EmployeeFormValidator` is de validatie-implementatie die specifiek is voor het Spring Framework. De supports()
methode wordt geïmplementeerd door het Spring Framework om te weten op welke objecten deze validatie kan worden toegepast. We implementeren de validate()
methode en voegen fouten toe als enige veldvalidatie mislukt. Spring biedt de org.springframework.validation.ValidationUtils
hulpprogrammaklasse voor basisvalidaties zoals null of leeg. Zodra deze methode retourneert, koppelt het Spring Framework het Errors-object aan het BindingResult-object dat we gebruiken in onze controller-handlermethode. Let op dat het laatste argument van ValidationUtils.rejectIfEmptyOrWhitespace()
de sleutelnaam voor berichtenbronnen aanneemt. Op deze manier kunnen we gelokaliseerde foutmeldingen aan de gebruiker leveren. Voor meer informatie over i18n in Spring, lees Spring i18n Voorbeeld.
Controller Klassen
We hebben twee controllerklassen, één voor op annotaties gebaseerde formuliervalidatie en een andere voor onze aangepaste validator. De klasse CustomerController.java code:
package com.journaldev.spring.form.controllers;
import java.util.HashMap;
import java.util.Map;
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.journaldev.spring.form.model.Customer;
@Controller
public class CustomerController {
private static final Logger logger = LoggerFactory
.getLogger(CustomerController.class);
private Map<String, Customer> customers = null;
public CustomerController(){
customers = new HashMap<String, Customer>();
}
@RequestMapping(value = "/cust/save", method = RequestMethod.GET)
public String saveCustomerPage(Model model) {
logger.info("Returning custSave.jsp page");
model.addAttribute("customer", new Customer());
return "custSave";
}
@RequestMapping(value = "/cust/save.do", method = RequestMethod.POST)
public String saveCustomerAction(
@Valid Customer customer,
BindingResult bindingResult, Model model) {
if (bindingResult.hasErrors()) {
logger.info("Returning custSave.jsp page");
return "custSave";
}
logger.info("Returning custSaveSuccess.jsp page");
model.addAttribute("customer", customer);
customers.put(customer.getEmail(), customer);
return "custSaveSuccess";
}
}
Wanneer we annotatiegebaseerde formuliervalidatie gebruiken, hoeven we alleen kleine wijzigingen aan te brengen in de implementatie van onze controller-handlermethode om het te laten werken. Allereerst moeten we het modelobject dat we willen valideren annoteren met de @Valid
-annotatie. Vervolgens hebben we een BindingResult-argument nodig in de methode, Spring zorgt ervoor dat het wordt ingevuld met foutmeldingen. De logica van de handlermethode is heel eenvoudig, als er fouten zijn, reageren we met dezelfde pagina, anders leiden we de gebruiker door naar de succespagina. Een ander belangrijk punt om op te merken is dat we het attribuut “customer” aan het model toevoegen, dit is noodzakelijk om het Spring-framework te laten weten welk modelobject moet worden gebruikt op de formulierpagina. Als we dit niet doen, zal het objectbinding aan formuliergegevens niet plaatsvinden en zal onze formuliervalidatie niet werken. De code van de klasse EmployeeController.java:
package com.journaldev.spring.form.controllers;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.journaldev.spring.form.model.Employee;
@Controller
public class EmployeeController {
private static final Logger logger = LoggerFactory
.getLogger(EmployeeController.class);
private Map emps = null;
@Autowired
@Qualifier("employeeValidator")
private Validator validator;
@InitBinder
private void initBinder(WebDataBinder binder) {
binder.setValidator(validator);
}
public EmployeeController() {
emps = new HashMap();
}
@ModelAttribute("employee")
public Employee createEmployeeModel() {
// ModelAttribute-waarde moet hetzelfde zijn als die in de empSave.jsp
return new Employee();
}
@RequestMapping(value = "/emp/save", method = RequestMethod.GET)
public String saveEmployeePage(Model model) {
logger.info("Returning empSave.jsp page");
return "empSave";
}
@RequestMapping(value = "/emp/save.do", method = RequestMethod.POST)
public String saveEmployeeAction(
@ModelAttribute("employee") @Validated Employee employee,
BindingResult bindingResult, Model model) {
if (bindingResult.hasErrors()) {
logger.info("Returning empSave.jsp page");
return "empSave";
}
logger.info("Returning empSaveSuccess.jsp page");
model.addAttribute("emp", employee);
emps.put(employee.getId(), employee);
return "empSaveSuccess";
}
}
Voor het gebruik van aangepaste validator moeten we deze eerst injecteren in de controllerklasse. We gebruiken spring bean auto bedrading om dit te bereiken met behulp van de annotaties @Autowired
en @Qualifier
. Vervolgens hebben we een methode nodig die WebDataBinder als argument zal aannemen en we stellen onze aangepaste validator in om te worden gebruikt. Deze methode moet worden geannoteerd met de @InitBinder
-annotatie. Het gebruik van @ModelAttribute
is een andere manier om ons beanobject aan het Model toe te voegen. De rest van de code is vergelijkbaar met de implementatie van de klantcontroller.
Formuliervalidatiefoutmeldingen Resource-bundel
Het is tijd om naar onze resource-bundel te kijken, waar we verschillende soorten berichten hebben die worden gebruikt voor validatiefouten. message_en.properties-bestand:
# door de toepassing gedefinieerde foutberichten
id.required=Employee ID is required
name.required=Employee Name is required
role.required=Employee Role is required
negativeValue={0} can't be negative or zero
# Spring framework foutberichten die moeten worden gebruikt wanneer de conversie van formuliergegevens naar een bean mislukt
typeMismatch.int={0} Value must be an integer
typeMismatch.java.lang.Integer={0} must be an integer
typeMismatch={0} is of invalid format
# toepassingsberichten voor annotaties, {ValidationClass}.{modelObjectName}.{field}
# de {0} is de naam van het veld, andere velden staan in alfabetische volgorde, max en dan min
Size.customer.name=Customer {0} should be between {2} and {1} characters long
NotEmpty.customer.email=Email is a required field
NotNull.customer.age=Customer {0} should be in years
# Berichten van generieke annotatieklasse
Email=Email address is not valid
NotNull=This is a required field
NotEmpty=This is a required field
Past=Date should be Past
# Aangepaste validatie-annotatie
Phone=Invalid format, valid formats are 1234567890, 123-456-7890 x1234
I have provided message key details in the comment itself, so I will skip them here. The only important point to note here is the way messages will be looked up, first key name {ValidationClass}.{modelObjectName}.{field} is looked up and if that is not found then {ValidationClass}.{modelObjectName} is looked up. If that is missing, then finally {ValidationClass} key is looked up. If nothing is found then the default message provided will be returned. Read more about resource messages at Spring Localization Example.
Weergavepagina’s met formulier en fouten
Aangezien we de validatie-implementatie van het Spring-framework gebruiken, moeten we Spring Form-tags gebruiken om de fouten op te halen en de formulierbean- en variabelenamen in te stellen. De code van ons custSave.jsp-bestand staat hieronder.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="https://www.springframework.org/tags/form"
prefix="springForm"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Customer Save Page</title>
<style>
.error {
color: #ff0000;
font-style: italic;
font-weight: bold;
}
</style>
</head>
<body>
<springForm:form method="POST" commandName="customer"
action="save.do">
<table>
<tr>
<td>Name:</td>
<td><springForm:input path="name" /></td>
<td><springForm:errors path="name" cssClass="error" /></td>
</tr>
<tr>
<td>Email:</td>
<td><springForm:input path="email" /></td>
<td><springForm:errors path="email" cssClass="error" /></td>
</tr>
<tr>
<td>Age:</td>
<td><springForm:input path="age" /></td>
<td><springForm:errors path="age" cssClass="error" /></td>
</tr>
<tr>
<td>Gender:</td>
<td><springForm:select path="gender">
<springForm:option value="" label="Select Gender" />
<springForm:option value="MALE" label="Male" />
<springForm:option value="FEMALE" label="Female" />
</springForm:select></td>
<td><springForm:errors path="gender" cssClass="error" /></td>
</tr>
<tr>
<td>Birthday:</td>
<td><springForm:input path="birthday" placeholder="MM/dd/yyyy"/></td>
<td><springForm:errors path="birthday" cssClass="error" /></td>
</tr>
<tr>
<td>Phone:</td>
<td><springForm:input path="phone" /></td>
<td><springForm:errors path="phone" cssClass="error" /></td>
</tr>
<tr>
<td colspan="3"><input type="submit" value="Save Customer"></td>
</tr>
</table>
</springForm:form>
</body>
</html>
commandName="klant"
wordt gebruikt om de naam van het modelattribuut in te stellen waarin het formulierobject wordt blootgesteld. De standaardwaarde is “command”, daarom moeten we het instellen op de naam van het modelattribuut dat we gebruiken in onze controllerklassen. springForm:errors
wordt gebruikt om eventuele fouten weer te geven die worden gevonden bij het renderen van de pagina. Het attribuut path
wordt gebruikt om de objecteigenschap te definiëren die moet worden gebruikt voor gegevensbinding. De rest van de code is standaard HTML met wat CSS voor het opmaken van foutmeldingen. Ons bestand custSaveSuccess.jsp ziet er als volgt uit.
<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="fmt" uri="https://java.sun.com/jsp/jstl/fmt" %>
<%@ page session="false" %>
<html>
<head>
<title>Customer Saved Successfully</title>
</head>
<body>
<h3>
Customer Saved Successfully.
</h3>
<strong>Customer Name:${customer.name}</strong><br>
<strong>Customer Email:${customer.email}</strong><br>
<strong>Customer Age:${customer.age}</strong><br>
<strong>Customer Gender:${customer.gender}</strong><br>
<strong>Customer Birthday:<fmt:formatDate value="${customer.birthday}" type="date" /></strong><br>
</body>
</html>
Eenvoudige JSP-pagina die de klantwaarden toont als er geen validatiefouten zijn en deze pagina als antwoord wordt geretourneerd. De naam ervan is empSave.jsp.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="https://www.springframework.org/tags/form"
prefix="springForm"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Employee Save Page</title>
<style>
.error {
color: #ff0000;
font-style: italic;
font-weight: bold;
}
</style>
</head>
<body>
<springForm:form method="POST" commandName="employee"
action="save.do">
<table>
<tr>
<td>Employee ID:</td>
<td><springForm:input path="id" /></td>
<td><springForm:errors path="id" cssClass="error" /></td>
</tr>
<tr>
<td>Employee Name:</td>
<td><springForm:input path="name" /></td>
<td><springForm:errors path="name" cssClass="error" /></td>
</tr>
<tr>
<td>Employee Role:</td>
<td><springForm:select path="role">
<springForm:option value="" label="Select Role" />
<springForm:option value="ceo" label="CEO" />
<springForm:option value="developer" label="Developer" />
<springForm:option value="manager" label="Manager" />
</springForm:select></td>
<td><springForm:errors path="role" cssClass="error" /></td>
</tr>
<tr>
<td colspan="3"><input type="submit" value="Save"></td>
</tr>
</table>
</springForm:form>
</body>
</html>
empSaveSuccess.jsp-bestand:
<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Employee Saved Successfully</title>
</head>
<body>
<h3>
Employee Saved Successfully.
</h3>
<strong>Employee ID:${emp.id}</strong><br>
<strong>Employee Name:${emp.name}</strong><br>
<strong>Employee Role:${emp.role}</strong><br>
</body>
</html>
Test de toepassing voor validatie van Spring MVC-formulieren
Onze applicatie is klaar om te implementeren en enkele tests uit te voeren, implementeer het in je favoriete servlet-container. Ik gebruik Apache Tomcat 7 en de onderstaande afbeeldingen tonen enkele pagina’s met validatiefoutmeldingen. Op basis van jouw invoergegevens kun je mogelijk ook verschillende foutmeldingen krijgen.
Dat is alles voor Spring MVC Form-validatie op verschillende manieren en het gebruik van resource-bundels voor gelokaliseerde foutmeldingen. Je kunt het voorbeeldproject downloaden via onderstaande link en ermee experimenteren om meer te leren.
Source:
https://www.digitalocean.com/community/tutorials/spring-validation-example-mvc-validator