SpringMVC数据校验并通过国际化显示错误信息

SpringMVC数据校验

<mvc:annotation-driven/>会默认装配好一个LocalValidatorFactoryBean,通过在处理方法的入参上标注@Valid 注解即可让Spring MVC在完成数据绑定后执行数据校验的工作。

首先,我们在实体类上标注JSR303校验注解

public class User extends BaseDomain{
private int userId; //将属性值长度限定为2~10之间,但中文占两个字符
@Length(min = 2, max = 10)
private String userName; //匹配4~30个数字和字母以及下划线字符
@Pattern(regexp="w{4, 30}")
private String name; @Length(min = 6)
private String password;

注解规则有多个可以参考下表

JSR 303注解

Hibernate Validator拓展注解

接着我们要让springMVC使用这些规则对数据进行校验,下面将使用LoginController控制器进行演示。

@Controller
public class LoginController { @RequestMapping(value = "/login", produces="text/html;charset=UTF-8")
public String login(
@Valid @ModelAttribute("user") User user,
BindingResult result, HttpSession session){
if(result.hasErrors()){
return "forward:/loginPage";
}else{
session.setAttribute("user", user);
return "home";
}
}

​ 在已经标注了JSR303注解的表单/命令对象前标注一个@Valid,Spring MVC框架在将请求数据绑定到该入参对象后,就会调用校验框架根据注解声明的校验规则实施校验。

​ 在本例中我们对User对象标注@Valid注解。还有要记得标注@ModelAttribute,并显示的指定其value值为user,在显示错误信息时我们会用到它。

​ 还有一个问题就是校验所产生的校验结果保存在什么地方呢,如何传递给请求处理方法?Spring MVC是通过对处理方法签名的规约来保存校验结果的:前一个表单/命令对象的校验结果保存在其后的入参中,这个保存校验结果的入参必须是BindingResult 或Errors类型,这两个类都位于org.springframework.validation包中。

​ 而且需校验的表单/命令对象和其绑定结果对象或错误对象是成对出现的,它们之间不允许声明其他的入参。

在页面中显示错误信息

​ 由于表单/命令对象所对应的请求一般是从客户端的网页中传送过来的,如果发生了错误,我们必须通过网页显示出错误,提示用户更正错误。

<div class="login-container">

        <form:form modelAttribute="user" action="login" method="post">
<div class="login-inner">
<div class="login-inner-item login-operaType">
<div class="sign-in active">登录</div>
<div class="sign-up">注册</div>
</div>
<div class="login-inner-item">
<input type="text" class="layui-input" placeholder="账号" name="userName" value="${user.userName}">
<div class="message-error">
<form:errors path="userName" cssClass="message-error"/>
</div>
</div>
<div class="login-inner-item">
<input type="password" class="layui-input" placeholder="密码" name="password" value="${user.password}">
<div class="message-error">
<form:errors path="password" cssClass="message-error"/>
</div>
</div>
<div class="login-inner-item message-error">
${errorMsg}
</div>
<div class="login-inner-link">
<a href="">忘记密码</a>
</div>
<div class="login-inner-item .login-inner-submit">
<input type="submit" class="layui-input" value="登录">
</div>
</div>
</form:form>
</div>

首先我们修改一下form标签,并指定模型数据为user,与前面标注的@ModelAttribute一致,如下

<form:form modelAttribute="user" action="login" method="post">
...
</form:form>

然后使用<form:errors />标签来显示错误信息,path用来指定实体类中的属性,cssClass指定css样式类

<form:errors path="userName" cssClass="message-error"/>

也可以使用如下标签显示所有的错误信息,但是不精确没必要

<form:errors path="*"/>

接下来我们测试一下效果,如下就能显示错误信息了

​ 虽然能显示错误信息,但是这些错误信息是springMVC默认的,在实际运用中我们希望使用更加人性化的设置来显示错误信息。这时我们可以给校验注解添加message属性指定错误信息。

public class User extends BaseDomain{
private int userId; @Length(min = 2, max = 10, message = "用户名不正确,长度必须在2~10之间")
private String userName; @Length(min = 6, message = "密码长度不合法,长度必须大于6")
private String password;

这样我们就能按照我们自己的想法去显示不同的错误信息,如下

​ 虽然这样做成功了,能个性化的显示错误信息,但是这使用硬编码的方式依旧不推荐使用,我们希望在不修改源代码的情况下来修改这些错误信息,这时就可以使用国际化的方式来显示错误信息了。

通过国际化显示错误信息

当一个属性校验失败后,校验框架默认会为该属性生成4个消息代码,这些代码以校验注解类名前缀。例如User类中的password属性标准了一个@Length注解,当该属性值不满足@pattern所定义的规则时,就会产生一下4个错误代码:

Length.user.password
Length.password
Length.java.lang.String
Length

这里我们选择最精确的一个Length.user.password

​ 我们在类路径下添加一个文件夹i18n,用来存放国际化资源。然后再创建国际化资源,一个是message.properties,一个是message_zh_CN.properties,内容如下

接下来的工作是在springmvc-servlet中配置好这个国际化资源:

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="i18n.message"/>
</bean>

千万要注意,需要给这个bean添加一个id,且其值只能是messageSource,不然这个bean不会起作用。起初我配置好bean后,没给他加上id,然后配置的国际化根本不起作用,这个问题困扰我好久,最后通过查阅资料得知:

​ 对Spring容器启动时的步骤进行剖析,①处的initMessageSource()方法所执行的工作就是初始化容器中的国际化信息资源:它根据反射机制从BeanDefinitionRegistry中找出名称为“messageSource”且类型为org.springframework.context.MessageSource的Bean,将这个Bean定义的信息资源加载为容器级的国际化信息资源。

public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory); try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
//①初始化消息源
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
} this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
} }
}

然后看看MessageSource类图结构

所以容器中存在ResourceBundleMessageSource这个bean,并且id为messageSource时,spring才会把这个Bean定义的信息资源加载为容器级的国际化信息资源

然后就可以把实体类中硬编码的message属性给去掉了,如下就是效果,和之前的一样

SpringMVC数据校验并通过国际化显示错误信息的更多相关文章

  1. 《Java从入门到放弃》入门篇:springMVC数据校验

    昨天我们扯完了数据传递,今天我们来聊聊数据校验的问题.来,跟着我一起读:计一噢叫,一按艳. 在springMVC中校验数据也非常简单,spring3.0拥有自己独立的数据校验框架,同时支持JSR303 ...

  2. struts2 前端显示错误信息

    当我们显示错误信息的时候,会发现错误信息会以列表的形式显示,这样就不美观了,达不到我们想要的标准.所以我们可以用另外的方式输出错误信息. 例如我现在增加了两个错误信息: this.addFieldEr ...

  3. PHP通过ini_set()来设置显示错误信息和执行时间

    PHP的 ini_set函数是设置选项中的值,在执行函数后生效,脚本结束的时候,这个设置也失效.不是所有的选项都能被改函数设置的.具体那些值能够设置,可以查看手册中的列表. 就是能够设置php.ini ...

  4. Sharepoint2013:在页面上显示错误信息

    在sharepoint2013中我们需要修改以下三处的web.config,以显示错误信息 1, C:\inetpub\wwwroot\wss\VirtualDirectories\端口号\web.c ...

  5. 在ASP.NET 5中显示错误信息

    在 ASP.NET 5 中如果不进行显示错误信息的相关配置,在发生错误时,在浏览器中只能看到空白页面. 显示错误信息的配置方法如下: 1)在 project.json 中添加对 Microsoft.A ...

  6. 为什么mysql 5.7.24启停不显示错误信息?log-error_verbosity参数

    关键词:log-error_verbosity ,mysql启停没有信息,mysql启停不显示错误信息,mysql不显示启停信息 原因就是因为 log-error_verbosity = 2 被设置成 ...

  7. TP5.0: 显示错误信息

    在TP5中,我们运行的代码有错误无法执行时,只显示页面错误,而不显示错误信息 对我我来讲是无法接受滴!!毕竟我还是个小渣渣,查看了百度,解决方案是: 在application/config,php中找 ...

  8. SpringBoot 使用 RestTemplate 调用exchange方法 显示错误信息

    SpringBoot使用RestTempate SpringBoot使用RestTemplate摘要认证 SpringBoot使用RestTemplate基础认证 SpringBoot使用RestTe ...

  9. JavaBean组件<jsp:forward>动作<jsp:param>动作登录页面输入用户名和密码,然后进入检查页面判断是否符合要求,符合要求跳转到成功界面,不符合要求返回登录界面,显示错误信息。

    JavaBean组件 JavaBean组件实际是一种java类.通过封装属性和方法成为具有某种功能或者处理某个业务的对象. 特点:1.实现代码的重复利用.2.容易编写和维护.3.jsp页面调用方便. ...

随机推荐

  1. 风炫安全Web安全学习第十节课 数字型的Sql注入

    数字型的Sql注入 风炫安全Web安全学习第十一节课 字符型和搜索型的sql注入 风炫安全Web安全学习第十二节课 mysql报错函数注入 风炫安全Web安全学习第十三节课 CUD类型的sql注入 风 ...

  2. MySQL多版本并发控制——MVCC机制分析

    MVCC,即多版本并发控制(Multi-Version Concurrency Control)指的是,通过版本链维护一个数据的多个版本,使得读写操作没有冲突,可保证不同事务读写.写读操作并发执行,提 ...

  3. 关于maven多module的依赖问题

    之前的项目因为历史的原因,都是一个project里只包含了一个module,今年进入了新的项目组,出现了多个module,最近刚好也是在学<maven实战>因此想要将这个东西记录下来 工程 ...

  4. (十一)time模块

    三种时间表示 在Python中,通常有这几种方式来表示时间: 时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量.我们运行"ty ...

  5. LeetCode530. 二叉搜索树的最小绝对差

    题目 又是常见的BST,要利用BST的性质,即中序遍历是有序递增序列. 法一.中序遍历 1 class Solution { 2 public: 3 vector<int>res; 4 v ...

  6. [分享] 最流行的 10 个 JavaScript 库

    1. Lodash https://github.com/lodash/lodash 一个工具库,用得还蛮多. 2. Chalk https://github.com/chalk/chalk 给终端加 ...

  7. VGA调试心得

    以前自己调试过视频信号,无非就时钟加行场同步加数据线,如果视频信号出问题,第一看现象,第二测频率,反正出问题不是消隐信号出问题,就是时钟频率出问题.通过这种方式也调试成功过几个显示屏,然后就以为自己对 ...

  8. CISCO 如何重置3850交换机密码

    SUMMARY STEPS: Connect a terminal or PC to the switch. Set the line speed on the emulation software ...

  9. SDNU_ACM_ICPC_2021_Winter_Practice_4th [个人赛]

    传送门 D - Odd Divisor 题意: 给你一个n,问你n是否至少有一个奇数因子(这里题意没说清,没说是不是只有一个还是可以有多个!AC以后才发现是不止一个 思路: 如果这个数没有奇数因子,那 ...

  10. Bitter ORM NETCORE ORM 全网最粗暴简单易用高性能的 NETCore ORM 开源了

    开源的来了,懒人程序员的福音,.NET 生态闭环太缺开源精神了, 拥抱开源! 前言: 本人不是不喜欢现有ORM的轮子,而是发现现有的ORM 的都不太符合开发人员的一些习惯.现有的ORM 要么功能太冗余 ...