zoukankan      html  css  js  c++  java
  • springmvc表单验证

    http://blog.csdn.net/daryl715/article/details/1645880

    http://blog.csdn.net/shuwei003/article/details/7213662

    上面两篇文章文笔比较混乱,但能看出大概的过程。

    个人实践:

    1、概述:主要用到以下几个要素:一个与表单内容对应的JavaBean类,一个用来验证这个Bean的Validator类,一个调用这个Validator的Controller类。

    所以,Validator需要知道JavaBean,Controller需要知道Validator。

    剩下的都是细节。

    2、例子:

    (1) JavaBean

    public class User {
        private Integer userId;
    
        private Integer parentId;
    
        private String userName;
    
        private String password;
    
        private String tel;
    
        private String email;
    
        private String qq;
    
        private String webChat;
    
        private Integer groupId;
    
        private Boolean state;
    
        private Date createTime;
    
        private Date lastTime;
    }

    getter和setter省略了。

    (2)、表单jsp页面

    
    

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>添加用户</title>
    <link href="/Public/media/css/new/page.css" rel="stylesheet"
    type="text/css" />
    <style type="text/css">
    .errormsg {
    font-family: "微软雅黑";
    color: #F30;
    }
    </style>
    </head>
    <body>


    <
    form:form action="${pageContext.request.contextPath}/userConfig/addDA" method="post" commandName="user"> <div class="formDiv"> <table width="1020" border="0"> <tr> <td align="right">用户名:</td> <td align="left"><form:input path="userName"/><span class="errormsg"><form:errors path="userName"/></span></td> </tr> <tr> <td align="right">密码:</td> <td align="left"><form:password path="password"/><span class="errormsg"><form:errors path="password"/></span></td> </tr> <tr> <td align="right">电话:</td> <td align="left"><form:input path="tel"/><span class="errormsg"><form:errors path="tel"/></span></td> </tr> <tr> <td align="right">邮件:</td> <td align="left"><form:input path="email"/><span class="errormsg"><form:errors path="email"/></span></td> </tr> <tr> <td align="right">QQ:</td> <td align="left"><form:input path="qq"/><span class="errormsg"><form:errors path="qq"/></span></td> </tr> <tr> <td align="right">微信:</td> <td align="left"><form:input path="webChat"/><span class="errormsg"><form:errors path="webChat"/></span></td> </tr> <tr> <td align="right">状态:</td> <td align="left"><table width="200"> <tr> <td><label> <input type="radio" name="StatusRadioGroup" value="禁用" id="StatusRadioGroup_0" /> 禁用 </label></td> </tr> <tr> <td><label> <input type="radio" name="StatusRadioGroup" value="生效" id="StatusRadioGroup_1" /> 生效 </label></td> </tr> </table></td> </tr> <tr> <td></td> <td><input name="" type="submit" value="提交" /></td> </tr> </table> </div> </form:form>

    </body>
    </html>

     

    想要详细了解这里用到的springmvc form标签的意思,需要先学习相应知识:http://haohaoxuexi.iteye.com/blog/1807330

    关键点:

    a、commandName属性指定了后台Model中与表单对应的对象的名字,需要在后台modelAndView.setObject("user",user);如果不写该属性,默认key是"command",那在后台就要

        modelAndView.setObject("command",user)。

    b、<form:input和<form:errors标签中使用path属性指定该表单项对应的user的属性名。

    c、注意引入springmvc的form标签<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>

    (3)Validator代码

    
    

    package com.leslie;

    import org.springframework.validation.Errors;
    import org.springframework.validation.ValidationUtils;
    import org.springframework.validation.Validator;

    
    

    import com.leslie.User;


    public
    class UserValidator implements Validator{ @Override public boolean supports(Class<?> clazz) { return User.class.equals(clazz); } @Override public void validate(Object obj, Errors e) { // ValidationUtils.rejectIfEmpty(e, "name", "name.empty"); // ValidationUtils.rejectIfEmpty(e, "gender", "null"); // ValidationUtils.rejectIfEmpty(e, "age", "null"); // User s = (User)obj; // if(s.getAge() < 18){ // e.rejectValue("age","young"); // }else if(s.getAge() > 50){ // //e.reject("age", "old"); // } // if(s.getName().length() < 1){ // e.reject("name", "short"); // }else if(s.getName().length() > 10){ // e.reject("name", "long"); // } ValidationUtils.rejectIfEmpty(e, "userName", null, "用户名不能为空"); ValidationUtils.rejectIfEmpty(e, "password", null, "密码不能为空"); } }

    关键点:

    a、supports方法中指定了对哪个类进行验证。

    b、ValidationUtils是springmvc的工具类,你可以方便地使用它进行常用的判断,你也可以直接使用e.rejectValue定义你自己的判断信息,

    注释掉的语句列出了常用的用法。

    c、rejectIfEmpty方法第三个参数是国际化properties文件中的key值,由于我没有使用国际化,此处使用了第四个参数,也就是默认值。

    (4) Controller实现

    @Controller
    @RequestMapping("/userConfig")
    public class SJUserConfigController {

    @InitBinder
    public void initBinder(WebDataBinder binder) {
    binder.setValidator(new UserValidator());
    }

    
    
      @RequestMapping("/openAddUser")
    public ModelAndView openAddUser() { ModelAndView mv = new ModelAndView(); User u = new User(); mv.addObject("user",u); mv.setViewName("addUser"); return mv; } @RequestMapping("/addUser") public ModelAndView addUser(@Valid @ModelAttribute User user, BindingResult br, HttpServletRequest requset) { ModelAndView mv = new ModelAndView(); mv.addObject("user", user); if (br.hasErrors()) { mv.setViewName("addUser"); } else { mv.setViewName("success"); } return mv; } }

    关键点:

    a、@InitBinder指定了Validator。

    b、注意openAddUser这个方法,这个方法执行以后首次打开表单页供用户填写信息,mv.addObject("user",u);这句非常必要,u不能为null,否则jsp报错。

    c、addUser方法处理表单提交上来的内容,@Valid指定了要对其修饰的对象进行验证,如果没有这个注解,springmvc就不会对表单进行验证。

    3、后记

    使用了上述的验证机制以后,虽然经过测试,可以正常验证表单,但后台服务器报

    javax.validation.ValidationException: Unable to create a Configuration, because no Bean Validation provider could be found.

    加入hibernate-validator.jar(以及其依赖的jboss-logging.jar和classmate.jar)以后就正常了,具体Jar的版本号此处略去。

    4、后记的后记:一个巨大的坑和巨大的潜规则--commandName与@ModelAttribute必须配合默契否则不报错但就是不显示错误信息

    什么意思呢?说明如下。

    在前面的例子中,我很巧合地将页面的commandName值赋为"user",而我的表单对应Java类刚好也是叫User,而且我直接这样@ModelAttribute使用了注解,并没有指定@ModelAttribute("xxxx"),结果

    一切顺利,但这只是一种巧合情况。

    好,那下面我总结一下我实验出的最后结论:

    1、如果你直接使用@ModelAttribute,并没有指定其value,那对不起,你页面中的commandName的值必须是你的表单对应类的类名的小写!最恶心的是,如果你不知道这一点,

    随意地给commandName起名字的话,validator会正确验证表单,controller会正确跳转,一切都正常,就是页面中不显示错误信息!而且不报任何错误!

    2、如果你这样使用@ModelAttribute注解,比如@ModelAttribute("abcdef"),那么你页面中的commandName也必须等于"abcdef",二者匹配起来用,这样,你才可能达到自己给commandName

    起名字的目的!

    后记的后记二:

    如果一个controller中的方法处理两个及两个以上的form表单,比如,方法A()接收并处理用户注册信息,而方法B()接收并处理定单查询条件,由于controller只能绑定一个validator,没有与validator匹配的那个

    表单在被提交之后也会被validator验证并报错,即使你没加@Valid也会。目前没有解决的办法,只能将这种情况拆开两个controller处理。

  • 相关阅读:
    说说Java中的代理模式
    一个奇怪的异常
    JDBC第二次学习
    浅谈事务
    JDBC第一次学习
    Firebug & Chrome Console 控制台使用指南
    js 事件创建发布
    vue ui之 iview 事件拦截
    fetch获取json的正确姿势
    js对象通过属性路径获取属性值
  • 原文地址:https://www.cnblogs.com/mabaishui/p/5490312.html
Copyright © 2011-2022 走看看