五. JSR 303 验证分组
把 User 中的属性上面都放置了注解,这个User 被很多 Action 调用,在校验的时候,有的是不需要校验的,有的是必须要校验的, 如password 属性,只在登录的Action 校验, 在修改资料的Action 中是不校验的,还有id属性, 在新增的方法中是不校验的, 在修改的方法中是需要校验的。 需要让User 中的校验器可以根据不同的情况,进行不同的划分。 需要添加不同的校验组。 每个Action的每个方法根据自己的不同验证来调用不同的校验组。
五.一 根据验证情况,创建不同的分组接口
老蝴蝶在这儿只简单创建两个
UserGroup1.class
package com.yjl.validator; public interface UserGroup1 { //没有任何方法,也不实现任何接口,只是做个标记而已。 }
UserGroup2.class
package com.yjl.validator; public interface UserGroup2 { //没有任何方法,也不实现任何接口,只是做个标记而已。 }
五.二 在User.class 中为每一个属性的每一个注解分配组
老蝴蝶在这儿,只简单用 name和password 来举例子,其他的属性不配置组,不进行验证。
User.class
@NotBlank(message="用户名不能为空",groups={UserGroup1.class,UserGroup2.class}) @Length(max=10,message="用户名不能超过10个字",groups={UserGroup1.class}) private String name; @NotBlank(message="密码不能为空",groups={UserGroup2.class}) @Length(min=6,max=15,message="密码长度应在6~15之间",groups={UserGroup2.class}) private String password;
可知, 在usergroup1 中只验证 用户名和用户名长度, 在usergroup2 中验证用户名不为空和密码不为空,密码的长度。
五.三 Action 方法中添加不同的分组
UserAction.class 中,只在 @Validated 中添加value的属性即可。
@RequestMapping(value="login") public String login(@Validated(value={UserGroup1.class}) User user, BindingResult bindingResult,Model model){ model.addAttribute("user",user); if(bindingResult.hasErrors()){ //有错的话,就返回登录页面。 return "user/login"; } return "user/list"; }
五.四 重启服务器,进行校验
密码可以不输入便可通过。
五.五 将分组变成 UserGroup2.class 进行验证
@RequestMapping(value="login") public String login(@Validated(value={UserGroup2.class}) User user, BindingResult bindingResult,Model model){ model.addAttribute("user",user); if(bindingResult.hasErrors()){ //有错的话,就返回登录页面。 return "user/login"; } return "user/list"; }
重启服务器,进行验证。
六. 验证信息国际化
在提示的错误信息,在国际化的系统中,也需要进行国际化。
可结合上一章的国际化来进行学习。
六.一 创建国际化验证提示信息文件
i18n 为源文件夹。
默认的 UserMessage.properties
user.name.null=\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A user.name.length=\u7528\u6237\u540D\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC710 user.password.null=\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A user.password.length=\u5BC6\u7801\u957F\u5EA6\u5E94\u57286~15\u4E4B\u95F4
UserMessage_zh_CN.properties
user.name.null=\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A user.name.length=\u7528\u6237\u540D\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC710 user.password.null=\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A user.password.length=\u5BC6\u7801\u957F\u5EA6\u5E94\u57286~15\u4E4B\u95F4
UserMessage_en_US.properites
user.name.null=name is not null user.name.length=The user name cannot be longer than 10 user.password.null=password is not null user.password.length=Password length should be between 6 and 15
六.二 User.java 中 message内容改成国际化
老蝴蝶这里也是针对 name 和password 进行验证
@NotBlank(message="{user.name.null}",groups={UserGroup1.class,UserGroup2.class}) @Length(max=10,message="{user.name.length}",groups={UserGroup1.class}) private String name; @NotBlank(message="{user.password.null}",groups={UserGroup2.class}) @Length(min=6,max=15,message="{user.password.length}",groups={UserGroup2.class}) private String password;
UserAction 中的内容不变,与五.五 部分的内容一致。
六.三 springmvc.xml 文件中配置资源文件路径
<mvc:annotation-driven validator="validator"></mvc:annotation-driven> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <!-- hibernate校验器 --> <property name="providerClass" value="org.hibernate.validator.HibernateValidator"></property> <!-- 国际化文件 --> <property name="validationMessageSource" ref="messageSource"> </property> </bean> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames"> <list> <value>classpath:UserMessage</value> <!-- 可继续添加多个 --> </list> </property> <!-- 资源文件编码格式 --> <property name="fileEncodings" value="utf-8"/> <!-- 资源文件的缓存时间,单位是s 秒 --> <property name="cacheSeconds" value="120"/> </bean>
六.四 重启服务器,进行验证
刚开始浏览器环境是中文的
提交后:
更改成英文的环境,(更改环境,上一章已经讲过了, 选项,常规,语言,改成英文,应用并重启) 提交后:
发现,仍然是中文的,并没有改成英文的。
这种方式的国际化发现失败了。 找了很长时间的错误,不知道,是为什么。
后来,用 Session 的国际化实现了这一操作。
(六.三 和六.四 这两个步骤是错误的。 暂时不删除,老蝴蝶为了警示自己)
六.三(正确的) 写前端代码,添加 中文和英文的链接
<body> <h2>两个蝴蝶飞,数据验证使用</h2> <a href="toLogin.action?request_locale=zh_CN">中文</a> <a href="toLogin.action?request_locale=en_US">美国</a> <form:form commandName="user" action="login.action" method="post"> <form:label path="name">姓名:</form:label> <form:input path="name"/> <form:errors path="name"></form:errors> <br/> <form:label path="password">密码:</form:label> <form:input path="password"/> <!--为了能看见值,这里用 form:input,而不是form:password --> <form:errors path="password"></form:errors> <br/> <form:label path="age">年龄:</form:label> <form:input path="age"/> <form:errors path="age"></form:errors> <br/> <form:label path="description">描述:</form:label> <form:input path="description"/> <form:errors path="description"></form:errors> <br/> <form:label path="score">成绩:</form:label> <form:input path="score"/> <form:errors path="score"></form:errors> <br/> <form:label path="birthday">出生日期:</form:label> <form:input path="birthday"/> <form:errors path="birthday"></form:errors> <br/> <form:label path="phone">联系方式:</form:label> <form:input path="phone"/> <form:errors path="phone"></form:errors> <br/> <form:label path="email">邮箱:</form:label> <form:input path="email"/> <form:errors path="email"></form:errors> <br/> <form:button>提交</form:button> </form:form> </body>
六.四 (正确) springmvc.xml 配置文件中写 Hibernate验证和国际化
<mvc:annotation-driven validator="validator"></mvc:annotation-driven> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <!-- hibernate校验器 --> <property name="providerClass" value="org.hibernate.validator.HibernateValidator"></property> <!-- 国际化文件 --> <property name="validationMessageSource" ref="messageSource"> </property> </bean> <!-- 配置国际化的拦截器 --> <mvc:interceptors> <!-- 必须配置 --> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean> </mvc:interceptors> <!-- 配置 SessionLocaleResolver 国际化bean,必须写 --> <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>UserMessage</value> </list> </property> </bean>
六.五 后端UserAction 代码
//转到登录的页面 @RequestMapping(value="toLogin") public String toLogin(String request_locale,Model model,HttpServletRequest request){ if(request_locale!=null&&!"".equals(request_locale)){ Locale locale=null; if("zh_CN".equals(request_locale)){ locale=new Locale("zh","CN"); }else if("en_US".equals(request_locale)){ locale=new Locale("en","US"); }else{ locale=LocaleContextHolder.getLocale(); } request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, locale); }else{ request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, LocaleContextHolder.getLocale()); } model.addAttribute("user",new User()); return "user/login"; } //绑定到user对象。 @RequestMapping(value="login") public String login(@Validated(value={UserGroup2.class}) User user, BindingResult bindingResult,Model model){ model.addAttribute("user",user); if(bindingResult.hasErrors()){ //有错的话,就返回登录页面。 return "user/login"; } return "user/list"; }
六.六 重启服务器,进行验证
刚开始是中文的,图片显示
点击链接,换成英文的,图片显示
国际化显示提示信息正确。
谢谢!!!