详解SpringMVC中的数据验证示例

JAVA herman 704浏览 0评论
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog,发送下载链接帮助你免费下载!
本博客日IP超过1800,PV 2600 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog,之前的微信号好友位已满,备注:返现
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领

在《详解SpringMVC中的Errors和BindingResult数据验证》这篇文章中,我们已经学习了一个案例,本文将继续学习一个数据绑定失败的案例。

下面先看看控制器DataBinderErrorTestController的实现代码:

package com.xttblog.chapter4.web.controller;  
//省略import  
public class DataBinderErrorTestController extends SimpleFormController {  
    public DataBinderErrorTestController() {  
        setCommandClass(DataBinderTestModel.class);  
        setCommandName("dataBinderTest");  
    }  
    @Override  
    protected ModelAndView showForm(HttpServletRequest request, 
		HttpServletResponse response, BindException errors) throws Exception {  
              //如果表单提交有任何错误都会再回到表单展示页面  
              System.out.println(errors);  
              return super.showForm(request, response, errors);  
    }  
    @Override  
    protected void doSubmitAction(Object command) throws Exception {  
        System.out.println(command); //表单提交成功(数据绑定成功)进行功能处理  
    }  
    @Override  
    protected void initBinder(HttpServletRequest request, 
		ServletRequestDataBinder binder) throws Exception {  
        super.initBinder(request, binder);  
	  //注册自定义的属性编辑器  
	  //1、日期  
	  DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
	  CustomDateEditor dateEditor = new CustomDateEditor(df, true);  
	  //表示如果命令对象有Date类型的属性,将使用该属性编辑器进行类型转换  
	  binder.registerCustomEditor(Date.class, dateEditor);  
	   
	  //自定义的电话号码编辑器  
	  binder.registerCustomEditor(PhoneNumberModel.class, new PhoneNumberEditor());  
    }  
}  

此处我们使用SimpleFormController:

  • showForm:展示表单,当提交表单有任何数据绑定错误会再回到该方法进行表单输入(在此处我们打印错误对象);
  • doSubmitAction:表单提交成功,只要当表单的数据到命令对象绑定成功时,才会执行;

spring配置文件chapter4-servlet.xml

<bean name="/dataBindError"  
class="com.xttblog.web.controller.DataBinderErrorTestController">  
   <property name="formView" value="bindAndValidate/input"/>  
   <property name="successView" value="bindAndValidate/success"/>  
</bean>  

视图页面(WEB-INF/jsp/bindAndValidate/input.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>  
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>  
<!-- 表单的命令对象名为dataBinderTest -->  
<form:form commandName="dataBinderTest">  
    <form:errors path="*" cssStyle="color:red"></form:errors><br/><br/>  
    bool:<form:input path="bool"/><br/>  
    phoneNumber:<form:input path="phoneNumber"/><br/>  
    date:<form:input path="date"/><br/>  
    <input type="submit" value="提交"/>  
</form:form>

此处一定要使用form标签库,借此我们可以看到它的强大支持(别的大部分Web框架所不具备的,展示用户验证失败的数据)。

  • <form:form commandName="dataBinderTest">:指定命令对象为dataBinderTest,默认command;
  • <form:errors path="*" cssStyle="color:red"></form:errors>:显示错误消息,当提交表单有错误时展示错误消息(数据绑定错误/数据不合法);
  • <form:input path="bool"/>:等价于(<input type=’text’>),但会从命令对象中取出bool属性进行填充value属性,或如果表单提交有错误会从错误对象取出之前的错误数据(而非空或默认值);
  • <input type="submit" value="提交"/>:spring没有提供相应的提交按钮,因此需要使用html的。

在地址栏输入如下地址:http://localhost:9080/springmvc-chapter4/dataBindError

dataBindError

全部是错误数据,即不能绑定到我们的命令对象;当提交表单后,我们又回到表单输入页面,而且输出了一堆错误信息。

错误信息

  • 错误消息不可读;
  • 表单元素可以显示之前的错误的数据,而不是默认值/空;

这里最大的问题是不可读的错误消息,如何让这些错误消息可读呢?

首先我们看我们的showForm方法里输出的“errors”错误对象信息:

org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 3 errors  
Field error in object 'dataBinderTest' on field 'bool': rejected value [www]; codes [typeMismatch.dataBinderTest.bool,typeMismatch.bool,typeMismatch.boolean,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [dataBinderTest.bool,bool]; arguments []; default message [bool]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'boolean' for property 'bool'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [www]]  
Field error in object 'dataBinderTest' on field 'date': rejected value [123]; codes [typeMismatch.dataBinderTest.date,typeMismatch.date,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [dataBinderTest.date,date]; arguments []; default message [date]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'date'; nested exception is java.lang.IllegalArgumentException: Could not parse date: Unparseable date: "123"]  
Field error in object 'dataBinderTest' on field 'phoneNumber': rejected value [123]; codes [typeMismatch.dataBinderTest.phoneNumber,typeMismatch.phoneNumber,typeMismatch.cn.javass.chapter4.model.PhoneNumberModel,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [dataBinderTest.phoneNumber,phoneNumber]; arguments []; default message [phoneNumber]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'cn.javass.chapter4.model.PhoneNumberModel' for property 'phoneNumber'; nested exception is java.lang.IllegalArgumentException: 类型转换失败,需要格式[010-12345678],但格式是[123]]  

数据绑定失败(类型不匹配)会自动生成如下错误码(错误码对应的错误消息按照如下顺序依次查找):

  • typeMismatch.命令对象名.属性名
  • typeMismatch.属性名
  • typeMismatch.属性全限定类名(包名.类名)
  • typeMismatch

内部使用MessageCodesResolver解析数据绑定错误到错误码,默认DefaultMessageCodesResolver,因此想要详细了解如何解析请看其javadoc;建议使用第1个进行错误码的配置。

因此修改我们的messages.properties添加如下错误消息(需要执行NativeToAscii):

typeMismatch.dataBinderTest.date=您输入的数据格式错误,请重新输入(格式:2012-03-19 22:17:17)  
#typeMismatch.date=2  
#typeMismatch.java.util.Date=3  
#typeMismatch=4  

再次提交表单我们会看到我们设置的错误消息。到此,数据绑定错误我们介绍完了,接下来我们再看一下数据不合法错误。

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763(2000人群已满),QQ2群:454796847(已满),QQ3群:187424846(已满)。QQ群进群密码:xttblog,想加微信群的朋友,之前的微信号好友已满,请加博主新的微信号:xttblog,备注:“xttblog”,添加博主微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

本文原文出处:业余草: » 详解SpringMVC中的数据验证示例