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>
- SpringMVCJSR-303规范进行校验简单示例
- struts2 简单登录校验示例
- 一个简单的日期校验示例
- Struts2使用过滤器和拦截器进行简单权限校验
- Struts2使用过滤器和拦截器进行简单权限校验
- SpringMVC 使用JSR-303进行校验 @Valid
- springmvc使用JSR-303进行校验
- SpringMVC 使用JSR-303进行校验 @Valid
- SpringMVC 使用JSR-303进行校验 @Valid
- SpringMVC 使用JSR-303进行校验 @Valid
- springmvc使用JSR-303进行校验
- SpringMVC 使用JSR-303进行校验 @Valid
- SpringMVC 使用JSR-303进行校验 @Valid
- SpringMVC 使用JSR-303进行校验 @Valid
- SpringMVC 使用JSR-303进行校验 @Valid
- SpringMVC 使用JSR-303进行校验 @Valid
- SpringMVC 使用JSR-303进行校验 @Valid
- SpringMVC 使用JSR-303进行校验 @Valid
- sdut-离散题目3
- 面向对象与原型一
- 淘淘商城第十一天
- VI退出 退出VIM 适用新手
- 面向对象与原型二
- SpringMVCJSR-303规范进行校验简单示例
- linux下忘记mysql密码
- 面向对象与原型三
- 淘淘商城第十二天
- JavaPoet
- Educational Codeforces Round 9 Longest Subsequence 思维+筛法
- 淘淘商城第十三天
- POJ
- mysql数据库从A表查询数据插入到B表中