SpringMVC 17. Data validation (JSR 303, Hibernate Validator extension annotations, message internationalization)

Data validation

JSR 303

  • JSR 303 is a standard framework provided by Java for bean data validation, which has been included in JavaEE 6.0.

  • JSR 303 specifies validation rules by annotating standard annotations such as @NotNull and @Max on bean properties, and validates beans through standard validation interfaces

JSR303

Hibernate Validator extension annotations

  • Hibernate Validator is a reference implementation of JSR 303. In addition to supporting all standard validation annotations, it also supports the following extended annotations

Hibernate Validator

Spring MVC data validation

  • Spring 4.0 has its own independent data verification framework and supports the JSR303 standard verification framework.

  • When Spring performs data binding, it can call the verification framework at the same time to complete the data verification work. In Spring MVC, data validation can be performed directly through annotation-driven methods.

  • Spring's LocalValidatorFactroyBean implements both Spring's Validator interface and JSR 303's Validator interface. As long as a LocalValidatorFactoryBean is defined in the Spring container, it can be injected into beans that require data validation.

  • Spring itself does not provide the implementation of JSR303, so the jar package of the implementer of JSR303 must be placed on the classpath.

  • <mvc:annotation-driven/>A LocalValidatorFactoryBean will be assembled by default, and Spring MVC can perform data validation after data binding is completed by annotating the @valid annotation on the input parameters of the processing method.

  • Mark a @Valid in front of the form/command object that has been annotated with JSR303 annotations. After the Spring MVC framework binds the request parameters to the input object, it will call the verification framework to perform verification according to the verification rules declared by the annotation.

  • Spring MVC saves the verification result by specifying the signature of the processing method: the verification result of the previous form/command object is saved to the subsequent input parameter, and the input parameter that saves the verification result must be of type BindingResult or Errors. Both of these classes are located in the org.springframework.validation package.

  • When the Bean object to be verified and its binding result object or error object appear in pairs, other input parameters are not allowed to be declared between them.

  • The Errors interface provides methods to obtain error information, such as getErrorCount() or getFieldErrors(String field)

  • BindingResult extends the Errors interface
    BindingResult

Get the validation result in the target method

  • Mark the validation annotation in the properties of the form/command object class, add @Valid before the input parameter corresponding to the processing method, Spring MVC will implement the validation and save the validation result in the BindingResult or after the validation input object.
    Errors into the parameter.

  • Common method:

– FieldError getFieldError(String field)
– List<FieldError> getFieldErrors()Object getFieldValue(String field)
– Int getErrorCount()

show errors on the page

  • In addition to saving the verification results of the form/command object to the corresponding BindingResult or Errors object, Spring MVC also saves all verification results to the "implicit model"

  • Even if there is no result input parameter corresponding to the form/command object in the signature of the handler method, the validation result will be stored in the "implicit object".

  • All data in the implicit model will eventually be exposed to the JSP view object through the attribute list of HttpServletRequest, so error information can be obtained in the JSP

  • Error messages can be <form:errors path=“userName”>displayed

Sample code:

  • First, you need to import the jar package of Hibernate Validator, add in pom.xml:
    <dependency>
      <groupId>org.hibernate.validator</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.0.9.Final</version>
    </dependency>
  • employee.java: Add annotation @NotEmpty to lastName, add annotation to Email: @Email, add annotation @Past to birth.
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Past;
import java.util.Date;

public class Employee {
    private Integer id ;

    @NotEmpty
    private String lastName ;

    @Email
    private String email ;

    private Integer gender ;
    private Department department ;


    @Past
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birth ;

    @NumberFormat(pattern = "#,###,###.#")
    private Float salary ;


    public Float getSalary() {
        return salary;
    }

    public void setSalary(Float salary) {
        this.salary = salary;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }



    public Employee() {
    }

    public Employee(Integer id, String lastName, String email, Integer gender, Department department) {
        this.id = id;
        this.lastName = lastName;
        this.email = email;
        this.gender = gender;
        this.department = department;
    }

    public Employee(Integer id, String lastName, String email, Integer gender, Department department, Date birth) {
        this.id = id;
        this.lastName = lastName;
        this.email = email;
        this.gender = gender;
        this.department = department;
        this.birth = birth;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", gender=" + gender +
                ", department=" + department +
                ", birth=" + birth +
                ", salary=" + salary +
                '}';
    }
}
  • input.jsp page:
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>
    <title>restful CRUD input</title>
</head>
<body>

    <form action="testConversionServiceConverer" method="post">
        <%[email protected]0-105--%>
        Employee: <input type="text" name="employee">
        <input type="submit" value="Submit">
    </form>

<%----%>
<form:form action="${pageContext.request.contextPath}/emp" method="post" modelAttribute="employee">
    <c:if test="${employee.id == null}">
    LastName: <form:input path="lastName"></form:input>
        <%--关注这里:错误消息会显示--%>
        <form:errors path="lastName" cssStyle="color: red"></form:errors>
    </c:if>
    <br>

    <c:if test="${employee.id != null}">
        <form:hidden path="id"></form:hidden>
        <input type="hidden" name="_method" value="PUT">
    </c:if>
    Email:<form:input path="email"></form:input>
     <%--关注这里:错误消息会显示--%>
    <form:errors path="email"></form:errors>
    <br>
    <%
        Map<String,String> genders = new HashMap<>() ;
        genders.put("0","Male") ;
        genders.put("1","Female") ;
        request.setAttribute("genders",genders);
    %>
    Gender:<form:radiobuttons path="gender" items="${genders}" delimiter="&nbsp;&nbsp;"></form:radiobuttons>
    <br>
    Department:<form:select path="department.id" items="${departments}" itemLabel="departmentName" itemValue="id" ></form:select>
    <br>
    Birth:<form:input path="birth"></form:input>
     <%--关注这里:错误消息会显示--%>
    <form:errors path="birth"></form:errors>
    <br>
    Salary:<form:input path="salary"></form:input>
    <input type="submit" value="Submit">
</form:form>

</body>
</html>
  • handlers: EmployeeHandler.java中:
@RequestMapping(value = "/emp",method = RequestMethod.POST)
    public String save(@Valid Employee employee , BindingResult result , Map<String,Object> map){

        if (result.getErrorCount() > 0 ){
            System.out.println("出错了:");
            for (FieldError error : result.getFieldErrors()){
                System.out.println(error.getField()+":"+error.getDefaultMessage());
            }
            //出错,转向指定页面
            map.put("departments",departmentDao.getDepartments()) ;
            return  "input" ;
        }
        System.out.println("save:"+employee);
        employeeDao.save(employee);
        return "redirect:/emps" ;
    }

Internationalization of prompt messages

  • Each property generates a corresponding FieldError object when an error occurs in data binding and data validation.

  • When an attribute verification fails, the verification framework will generate 4 message codes for the attribute. These codes are prefixed with the verification annotation class name, and combined with the modelAttribute, attribute name and attribute type name to generate multiple corresponding message codes: for example The password attribute in the User class is annotated with a @Pattern. When the attribute value does not meet the rules defined by @Pattern, the following four error codes will be generated:

– Pattern.user.password
– Pattern.password
– Pattern.java.lang.String
– Pattern
  • When using the Spring MVC tag to display an error message, Spring MVC will check whether the WEB context is equipped with the corresponding internationalized message. If not, the default error message will be displayed, otherwise the internationalized message will be used.

  • If an error occurs during data type conversion or data format conversion, or if the required parameter does not exist, or if an error occurs when calling the handler method, an error message is created in the implicit model. The error code prefixes are described as follows:
    required: The required parameter does not exist. For example, @RequiredParam("param1") annotates an input parameter, but the parameter does not exist
    typeMismatch: During data binding, a data type mismatch occurs
    methodInvocation: Spring MVC has an error when calling the processing method

  • Registering internationalized resource files

<!--配置国际化资源文件-->
    <bean  id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="i18n"></property>
    </bean>
  • i18n.properties
NotEmpty.employee.lastName=^^lastName不能为空
Email.employee.email=Email不合法
Past.employee.birth=Birth不能是一个将来的时间

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325405914&siteId=291194637