Hibernate Validator实现数据校验

来源:互联网 发布:淘宝 手办时光机 编辑:程序博客网 时间:2024/05/21 21:47
• JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架,它已经包含在 JavaEE 6.0 中 .

• JSR 303 通过在 Bean 属性上标注类似于 @NotNull、@Max等标准的注解指定校验规则,并通过标准的验证接口对 Bean进行验证.

Hibernate Validator 是 JSR 303 的一个参考实现,除支持所有标准的校验注解外,它还支持以下的扩展注解:

@Email(被注解的元素必须是电子邮箱)

@Length(被注释的字符串的大小必须在指定的范围内)

@NotEmpty(被注释的字符串必须非空)

@Range(被注释的元素必须在合法 的范围内)

Spring 4.0 拥有自己独立的数据校验框架,同时支持 JSR303 标准的校验框架。
• Spring 在进行数据绑定时,可同时调用校验框架完成数据校验工作。在 Spring MVC 中,可直接通过注解驱动的方式进行数据校验。
• Spring 的 LocalValidatorFactroyBean 既实现了 Spring 的Validator 接口,也实现了 JSR 303 的 Validator 接口。只要在 Spring 容器中定义了一个LocalValidatorFactoryBean,即可将其注入到需要数据校验的 Bean 中。
• Spring 本身并没有提供 JSR303 的实现,所以必须将JSR303 的实现者的 jar 包放到类路径下。

<mvc:annotation-driven/> 会默认装配好一个LocalValidatorFactoryBean,通过在处理方法的入参上标注 @valid 注解即可让 Spring MVC 在完成数据绑定后执行数据校验的工作
• 在已经标注了 JSR303 注解的表单/命令对象前标注一个@Valid,Spring MVC 框架在将请求参数绑定到该入参对象后,就会调用校验框架根据注解声明的校验规则实施校验
• Spring MVC 是通过对处理方法签名的规约来保存校验结果的:前一个表单/命令对象的校验结果保存到随后的入参中,这个保存校验结果的入参必须是 BindingResult 或Errors 类型,这两个类都位于org.springframework.validation 包中。

需校验的 Bean 对象和其绑定结果对象或错误对象时成对出现的,它们之间不允许声明其他的入参
• Errors 接口提供了获取错误信息的方法,如 getErrorCount() 或getFieldErrors(String field)
• BindingResult 扩展了 Errors 接口



• 在表单/命令对象类的属性中标注校验注解,在处理方法对应的入参前添加 @Valid,Spring MVC 就会实施校验并将校验结果保存在被校验入参对象之后的 BindingResult 或
Errors 入参中。
• 常用方法:
FieldError getFieldError(String field)
List<FieldError> getFieldErrors()
Object getFieldValue(String field)
Int getErrorCount()


如果把错误的结果显示到页面上应该怎么做呢?

• Spring MVC 除了会将表单/命令对象的校验结果保存到对应的 BindingResult 或 Errors 对象中外,还会将所有校验结果保存到 “隐含模型”。
• 即使处理方法的签名中没有对应于表单/命令对象的结果入参,校验结果也会保存在 “隐含对象” 中。
• 隐含模型中的所有数据最终将通过 HttpServletRequest 的属性列表暴露给 JSP 视图对象,因此在 JSP 中可以获取错误信息。
• 在 JSP 页面上可通过 <form:errors path=“userName”>显示错误消息。

ex:

首先在项目添加maven的依赖:

<!--添加hibernate validator 5依赖-->    <dependency>      <groupId>org.hibernate</groupId>      <artifactId>hibernate-validator</artifactId>      <version>5.0.2.Final</version>    </dependency>
创建如下的bean:

public class Employee {private Integer id;@NotEmptyprivate String lastName;@Emailprivate String email;//1 male, 0 femaleprivate Integer gender;private Department department;@Past@DateTimeFormat(pattern="yyyy-MM-dd")private Date birth;@NumberFormat(pattern="#,###,###.#")private Float salary;}

在Handler中添加@Valid注解:

@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";        }        employeeDao.save(employee);        return "redirect:/emps";    }

页面上的错误显示:

<body>        <%--如果修改的时候会发生错误,实际上开发的时候都推荐使用绝对路径--%>    <form:form action="${pageContext.request.contextPath}/emp" method="POST"               modelAttribute="employee">        <c:if test="${employee.id==null}">            LastName:<form:input path="lastName"/><%--input表示文本框--%>            <form:errors path="lastName"></form:errors>        </c:if>        <c:if test="${employee.id!=null}">            <form:hidden path="id"/>            <input type="hidden" name="_method" value="PUT"><%--表示这个方法是一个PUT请求--%>            <%--对于method不能使用form:hidden标签,因为modelAttrbiute对应的bean中没有_method这个属性--%>            <%--<form:hidden path="_method" value="PUT"/>--%>        </c:if>        <br>        Email:<form:input path="email"/>        <form:errors path="email"></form:errors>        <br>        <%            Map<String,String> genders=new HashMap<>();            genders.put("1","Male");            genders.put("0","Female");            request.setAttribute("genders",genders);//需要放在域对象中        %>        <%--radio Button--%>        Gender:<form:radiobuttons path="gender" items="${genders }"/>        <br>        <%--下拉框--%>        Department:<form:select path="department.id"                                items="${departments}"                                itemLabel="departmentName"                                itemValue="id">        </form:select>        <br>        Birth:<form:input path="birth"/>        <form:errors path="birth"></form:errors>        <br>        Salary:<form:input path="salary"/>        <br>        <input type="submit" value="Submit">    </form:form>    <form action="testConversionServiceConverter" method="POST">        Employee:<input type="text" name="employee">        <input type="submit" value="Submit">    </form></body>
path属性对应html表单标签的name属性即可。




0 0
原创粉丝点击