SpringMVCJSR-303规范进行校验简单示例

来源:互联网 发布:c语言贪吃蛇程序设计 编辑:程序博客网 时间:2024/06/06 10:47

需要引入

validation-api-1.0.0.GA.jar、hibernate-validator-4.2.0.Final.jar

jstl.jar、standard.js用于jsp页面的标签引用

LoginModel(省略属性的getter、setter方法)

package com.chensan.web.sys.model;import java.io.Serializable;import javax.validation.constraints.NotNull;import org.hibernate.validator.constraints.Length;/** * 登陆表单model. */public class LoginModel implements Serializable {private static final long serialVersionUID = 1L;/** * 用户名. */@NotBlank(message = "用户名不能为空")@Length(min = 4, max = 50, message = "用户名长度应该为4-50位")private String userName;/** * 密码. */@NotBlank(message = "密码不能为空")@Length(min = 6, max = 20, message = "密码长度应该为6-20位")private String password;}

本示例非空和格式验证的信息拼接在一起了,本应该是先验证非空,值不为空再验证长度或值的类型等;

Controller中的方法

@RequestMapping(value="/signIn", method=RequestMethod.POST)public String signIn(@Valid @ModelAttribute("formModel") LoginModel formModel, BindingResult bindingResult) {if (bindingResult.hasErrors()) {return Login_View_Name;}UserMedic user = currentUserService.getUser(formModel.getUserName());if (user == null) {bindingResult.rejectValue("userName", "user.not.exist");return Login_View_Name;}if (!user.getLoginPwd().equals(formModel.getPassword())) {bindingResult.rejectValue("password", "password.error", "密码不正确");return Login_View_Name;}HttpSession session = request.getSession();session.setAttribute("loginname", formModel.getUserName());//将用户存到sessionreturn String.format("redirect:/%s", "home");}

jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><%@ taglib uri="http://www.springframework.org/tags/form" prefix="sf"%><%  String path = request.getContextPath();  String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  %><!DOCTYPE html><html><head><meta charset="UTF-8"><title>登录页</title></head><body><sf:form modelAttribute="formModel" action="${pageContext.request.contextPath}/signIn" method="post">   <div>     <label for="userName">用户名:</label>     <input id="userName" type="text" name="userName" />     <div>     <sf:errors path="userName" cssClass="errorMsg"></sf:errors>   </div>   </div>   <div>     <label for="password">密码:</label>     <input id="password" type="password" name="password" />     <div>     <sf:errors path="password" cssClass="errorMsg"></sf:errors>   </div>   </div>  <input type="submit" value="登录" /></sf:form></body></html>

注意:

1. Controller的方法中@valid对应的@ModelAttribute参数与bindingResult之间不能有参数,它们必须紧挨在一起,否则报错;(我之前就是在它们之间有HttpServletRequest参数,一直报400错误;当然你可以去掉model中验证规则的注解,只是验证将不起作用;)

2. Controller的方法中@modelAttribute对应的参数与jsp的form中定义的modelAttribute属性值一致;

3. JSP页面中<sf:errors path="userName" cssClass="errorMsg"></sf:errors>将为错误信息占位;


将错误信息放在配置文件中引用,方便国际化;

在springmvc配置文件中加入

<!-- 开启springmvc注解 --><mvc:annotation-driven validator="validator" conversion-service="conversion-service"/><bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">  <property name="providerClass"  value="org.hibernate.validator.HibernateValidator"/>  <!--不设置则默认为classpath下的 ValidationMessages.properties -->  <property name="validationMessageSource" ref="validationMessageSource"/></bean><bean id="conversion-service" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" /><bean id="validationMessageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">    <property name="basename" value="/WEB-INF/static/i18n/validateMessages"/>    <property name="fileEncodings" value="utf-8"/>    <property name="cacheSeconds" value="120"/>  </bean>
在resource中加入validateMessages_zh_CN.properties和validateMessages_en_US.properties,确保文件为utf8格式

国际化配置文件validateMessages_zh_CN.properties

loginForm.userName.length = 用户名长度在 {min} 至 {max} 个字符之间
loginForm.password.length = 密码长度为 {min} 到 {max} 位
userName.not.exist = 用户不存在
password.error = 密码错误

国际化配置文件validateMessages_en_US.properties

loginForm.userName.length = userName length is {min} to {max} char
loginForm.password.length = password length is {min} to {max} char
userName.not.exist = userName is not exists
password.error = password is error

国际化文件位置属性basename,须根据实际情况配置;如果在resources下,则为classpath:validateMessages

注意:这里的basename文件名指定validateMessages而不是具体哪个文件,是为了根据实际情况实现国际化效果,自动选择文件;
loginModel改为(省略setter、getter方法)

package com.chensan.web.sys.model;import java.io.Serializable;import org.hibernate.validator.constraints.Length;/** * 登陆表单model. */public class LoginModel implements Serializable {private static final long serialVersionUID = 1L;/** * 用户名. */@Length(min = 4, max = 50,message="{loginForm.userName}")private String userName;/** * 密码. */@Length(min = 6, max = 20, message = "{loginForm.password}")private String password;}

引入配置外部配置文件配置验证信息的,可参考:https://my.oschina.net/shyloveliyi/blog/525252

国际化文件validateMessages_zh_CN.properties

loginForm.userName.length = 用户名长度在{min}至{max}个字符之间loginForm.password.length = 密码长度为{min}到{max}位userName.not.exist = 用户不存在

用户名输入数据库中不存在的用户报如下错误;

HTTP Status 500 - org.springframework.context.NoSuchMessageException: No message found under code 'userName.not.exist.formModel.userName' for locale 'zh_CN'.

因为loginModel中验证字段格式都可以找到resources下的validateMessages_zh_CN.properties,只是bindingResult.rejectValue("userName", "userName.not.exist");无法匹配到key值userName.not.exist和userName.not.exist.formModel.userName,也试过是不是jsp页面错误标签那里要放code元素来对应接收信息,均不奏效;

最后根据网上看到的些许字眼试了下springmvc配置文件的org.springframework.context.support.ReloadableResourceBundleMessageSource对应bean的id由validationMessageSource换为messageSource方才有用,国际化文件

网上看见有很多都说在<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"></bean>中加入

<!-- 如果在国际化资源文件中找不到对应代码的信息,就用这个代码作为名称 -->            <property name="useCodeAsDefaultMessage" value="true" />
加了之后确实可以将找不到code的key原样输出,但是同样会出现问题,即:
loginForm.userName.length = 用户名长度在 {min} 至 {max} 个字符之间输出的内容将是:用户名长度在 min 至 max 个字符之间,而没法将min和max这样的占位符填充具体值了。所以请将useCodeAsDefaultMessage设置为false,或者省略。

完整版的springMVC配置文件如下:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xmlns:p="http://www.springframework.org/schema/p"   xmlns:context="http://www.springframework.org/schema/context"   xmlns:mvc="http://www.springframework.org/schema/mvc"   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">    <!-- 开启springmvc注解 -->  <mvc:annotation-driven validator="validator" conversion-service="conversion-service"/>    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">    <property name="providerClass"  value="org.hibernate.validator.HibernateValidator"/>    <!--不设置则默认为classpath下的 validationMessages_zh_CN.properties -->    <property name="validationMessageSource" ref="messageSource"/>  </bean>  <bean id="conversion-service" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />  <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">    <property name="basename" value="/WEB-INF/static/i18n/validateMessages"/>    <property name="fileEncodings" value="utf-8"/>    <property name="cacheSeconds" value="120"/>    <property name="useCodeAsDefaultMessage" value="false" />  </bean>    <!-- 自动扫描包 -->  <context:component-scan base-package="com.chensan"/>    <!-- springmvc不过滤的目录和文件 -->  <mvc:resources mapping="/public/**" location="/WEB-INF/public/" />    <!-- 配置视图解析器:如何把Handler方法返回值解析为实际的物理视图 -->  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">    <property name="prefix" value="/WEB-INF/jsp/" />    <property name="suffix" value=".jsp" />  </bean>    <!-- 拦截器 -->  <mvc:interceptors>    <!-- 多个拦截器,顺序执行 -->    <mvc:interceptor>      <mvc:mapping path="/**"/>      <!-- 需排除拦截的地址 -->      <mvc:exclude-mapping path="/public/**"/>      <bean class="com.chensan.interceptor.LoginInterceptor"></bean>    </mvc:interceptor>  </mvc:interceptors></beans>


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝35.5度体温怎么办 宝宝出汗体温低怎么办 小孩体温35.2度怎么办 孩子睡觉出冷汗怎么办 小孩感冒发烧咳嗽怎么办 小孩咳嗽出汗多怎么办 小孩手脚出汗多怎么办 小孩感冒出虚汗怎么办 宝宝感冒出冷汗怎么办 宝宝感冒睡觉出汗怎么办 宝宝感冒冒冷汗怎么办 宝宝感冒爱出汗怎么办 宝宝感冒老出汗怎么办 两只小鸡打架怎么办 老年人老是换保姆怎么办 孩子9不吃饭怎么办 两岁半宝宝不爱喝水怎么办 宝宝老是不吃饭怎么办 宝宝不爱吃饭喝水怎么办 小宝宝突然不爱吃饭怎么办 一岁多小宝宝不爱吃饭怎么办 宝宝肚子发撑怎么办 小宝宝咳嗽有痰怎么办 一岁小宝宝咳嗽怎么办 oppo连wifi超时怎么办 小孩不会写3怎么办 秘密花园黑色底怎么办 孩子说话不利索怎么办? 两岁半宝宝x腿怎么办 孩子低烧不退怎么办 小班迷眼了怎么办教案 玩呗麻将群老封怎么办 游戏玩不厉害怎么办 厕所太小洗衣机怎么办 洗衣机进水太小怎么办 油性笔干了怎么办 水笔写不出来怎么办 手机图案密码打不开怎么办 图案锁住了打不开怎么办 手机绘制图案打不开怎么办 小孩吃了润滑油怎么办