一、消息处理功能

Spring提供MessageSource接口用于提供消息处理功能:

public interface MessageSource {
String getMessage(String code, Object[] args, String defaultMessage, Locale locale);
String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;
String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}

Spring提供了两个默认实现:

StaticMessageSource      // 测试用
ResourceBundleMessageSource // 用于生产环境

ApplicationContext接口扩展了MessageSource接口,当ApplicationContext被加载时,它会自动在context中查找已定义为MessageSource类型的bean。此bean的名称须为messageSource。如果找到,那么所有对上述方法的调用将被委托给该bean。否则ApplicationContext会在其父类中查找是否含有同名的bean。如果有,就把它作为MessageSource。如果它最终没有找到任何的消息源,一个空的StaticMessageSource将会被实例化,使它能够接受上述方法的调用。

示例如下:

属性文件

# exception.properties
message.arg=the {0} {1} is requred. # format.properties
message=这是一条测试消息 # format_en_GB.properties
message=this is a test

spring 配置(spring-validation.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd "> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:format</value>
<value>classpath:exception</value>
</list>
</property>
<property name="fileEncodings">
<props>
<prop key="classpath:format">utf-8</prop>
</props>
</property>
</bean> </beans>

测试

public class MessageTest {

    public static void main(String[] args) {

        MessageSource ms = new ClassPathXmlApplicationContext("spring-validation.xml");
String msg1 = ms.getMessage("message", null, "yeah", null);
String msg2 = ms.getMessage("message.arg", new Object[] { "aa", "bb" }, "yeah", null); // 参数定制
String msg3 = ms.getMessage("message", null, "yeah", Locale.UK); // 支持国际化
System.out.println(msg1);
System.out.println(msg2);
System.out.println(msg3);
} }

运行结果

这是一条测试消息
the aa bb is requred.
this is a test

补充:spring提供了MessageSourceAware接口,用于在bean创建时自动注入MessageSource。

 二、数据验证

JSR-303 (Bean Validation 1.0)定义了基于注解JavaBean数据验证规范,注解如下:

@Null                  被注释的元素必须为null
@NotNull         被注释的元素必须不为null
@AssertTrue        被注释的元素必须为true
@AssertFalse        被注释的元素必须为false
@Min(value)        被注释的元素必须为一个数字,其值必须大于等于指定值
@Max(value)        被注释的元素必须为一个数字,其值必须小于等于指定值
@DecimalMin(value)      被注释的元素必须为一个数字,其值必须大于等于指定值
@DecimalMax(value)      被注释的元素必须为一个数字,其值必须小于等于指定值
@Size(max, min)      被注释的元素必须在指定范围内
@Digits(integer, fraction) 被注释的元素必须为一个数字,其值必须在可接受的范围内
@Past         被注释的元素必须是一个过去的日期
@Future          被注释的元素必须是一个将来的日期
@Pattern(value)     被注释的元素必须符合指定的正则表达式
@Valid       被注释的元素必须为对象,表示递归验证对象属性

hibernate validator 在JSR303的基础上对校验注解进行了扩展,扩展注解如下:

@Emai                    被注释的元素必须是电子邮件格式
@Length       被注释的字符串大小必须在指定范围内
@NotEmpty         被注释的字符串必须非空
@Range         被注释的元素必须在合适的范围内

所有被支持的注解列表参见:hibernate-validator -> /org/hibernate/validator/ValidationMessages.properties

spring在hibernate validator基础上对JavaBean的数据校验方式进行了封装,配置与使用方式如下:

1、添加依赖

<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.16.Final</version>
</dependency>

2、添加配置

<!-- validator bean -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
<property name="validationMessageSource" ref="messageSource"/>
</bean> <!-- 注册(注册方式与Converter相同,参见Spring MVC 使用介绍(八)—— 类型转换) -->
<mvc:annotation-driven validator="validator" />

  注:messageSource的配置与上例相同

# format.properties
msg.age=性别须大于{value}岁

3、使用

Java Bean

public class Person {
@NotNull
private String name; @Min(value = 12, message = "{msg.age2}")
private int age;
...
}

controller

@ControllerAdvice
public class MyControllerAdvice {
@ResponseBody
@ExceptionHandler
public Map<String, String> errorhandler(Exception ex) {
BindException e = (BindException) ex;
Map<String, String> map = new HashMap<>();
map.put("error", e.getBindingResult().getFieldError().getDefaultMessage());
return map;
}
}
@RestController
public class ValidController {
@RequestMapping("/test1")
public Person test1(@Valid Person person) {
return person;
}
}

4、测试

访问:http://localhost:8080/shiro-test/test1?name=12&age=6,输出

{"error":"性别须大于12岁"}

访问:http://localhost:8080/shiro-test/test1?age=20,输出

{"error":"must not be null"}

三、错误消息

数据验证错误消息的指定有多种方式:

1、默认错误消息

默认的错误消息文件是/org/hibernate/validator/ValidationMessages.properties,如下图所示:

消息键默认为:验证约束注解的全限定类名.message

当不指定验证注解的message属性时,则使用默认消息

2、覆盖默认错误消息

方法很简单:在MessageSource的属性文件中依据默认消息键重新定义键值:

# format.properties
javax.validation.constraints.NotNull.message = 不能为空

3、自定义错误消息

在属性文件中定义错误消息,使用注解的message属性引用:

# format.properties
msg.notnull=不能为空
public class Person {
@NotNull(message = "{msg.notnull}")
private String name;
...
}

3.1 消息占位符

可在错误消息中使用占位符获取约束值,规则为:{验证注解属性名},如@Length有min和max属性,可在消息文件中使用{min}和{max}获取;@Max有value属性,可使用{value}获取

msg.age=性别须大于{value}岁

3.2 EL表达式

可在错误消息中使用EL表达式,规则为:${表达式},如可使用${validatedValue}获取验证值,使用${min > 1 ? '大于1' : '小于等于1'}添加逻辑判断:

javax.validation.constraints.Size.message = [${validatedValue}]须大于等于{min}字符
javax.validation.constraints.Min.message = 数量${min > 1 ? '大于1' : '小于等于1'}

在EL表达式中,可使用java.util.Formatter类型的formatter变量进行格式化:

${formatter.format("%04d", min)}

参考:

spring中ResourceBundleMessageSource的配置使用方法

SpringMVC数据验证——第七章 注解式控制器的数据验证、类型转换及格式化——跟着开涛学SpringMVC

Java Bean Validation 最佳实践

Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC

JAVA字段校验(validation)

Spring MVC 使用介绍(十三)数据验证 (一)基本介绍的更多相关文章

  1. 当使用Spring MVC @Valid对输入框进行验证的时候,可能会遇到以下的异常:Neither BindingResult nor plain target object for bean name ‘mybean’ available as request attribute

    转自:https://www.cnblogs.com/wenhulu/p/5555457.html 当使用Spring MVC @Valid对输入框进行验证的时候,可能会遇到以下的异常: Neithe ...

  2. Spring MVC基础知识整理➣数据校验与格式化

    概述 将view中Form的数据提交到后台之后,后台如何验证数据的有效性?在这里Spring MVC提供了相应的Hibernate类包(hibernate-validator-4.3.1.Final. ...

  3. spring mvc:练习:表单验证(javaConfig配置和注解)

    使用Spring表单标签, 表单验证使用 JSR303 的验证注解,hibernate-validators,提供了使用MessageSource和访问静态资源(如CSS,JavaScript,图片) ...

  4. spring mvc返回json字符串数据,只需要返回一个java bean对象就行,只要这个java bean 对象实现了序列化serializeable

    1.spring mvc返回json数据,只需要返回一个java bean对象就行,只要这个java bean 对象实现了序列化serializeable 2. @RequestMapping(val ...

  5. Spring mvc,jQuery和JSON数据交互

    一.实验环境的搭建 1.Spring mvc jar. 导入spring mvc运行所需jar包.导入如下(有多余) 2.json的支持jar 3.加入jQuery. 选用jquery-3.0.0.m ...

  6. spring mvc(4)处理模型数据

    处理模型数据 Spring MVC 提供了以下几种途径输出模型数据: – ModelAndView: 处理方法返回值类型为 ModelAndView时, 方法体即可通过该对象添加 模型数据 – Map ...

  7. spring mvc 返回xml格式数据

    1.问题 : 因为业务需要,需要发送xml格式的数据,使用spring mvc 自己解析,就不用费心去自己搞这些东西. 2.解决: 新建一个实体类,直接在实体类中添加注解即可,如下: @XmlRoot ...

  8. Spring MVC中返回JSON数据的几种方式

    我们都知道Spring MVC 的Controller方法中默认可以返回ModeAndView 和String 类型,返回的这两种类型数据是被DispatcherServlet拿来给到视图解析器进行继 ...

  9. MQTT 4 ——MQTT的Spring Mvc 配置接收字节流数据

    本篇记录一下MQTT整合Spring Mvc配置直接收发字节流数据 设备方是纯C开发,并且为了交互数据的安全,将传送的数据用了AES CBC进行了加密. 接下来正常方便做法应该是 将加密后的字节流转换 ...

  10. spring mvc 的jpa JpaRepository数据层 访问方式汇总

    本文转载至:http://perfy315.iteye.com/blog/1460226 AppleFramework在数据访问控制层采用了Spring Data作为这一层的解决方案,下面就对Spri ...

随机推荐

  1. Python两步实现关联规则Apriori算法,参考机器学习实战,包括频繁项集的构建以及关联规则的挖掘

    .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...

  2. 【深度学习系列】PaddlePaddle垃圾邮件处理实战(二)

    PaddlePaddle垃圾邮件处理实战(二) 前文回顾   在上篇文章中我们讲了如何用支持向量机对垃圾邮件进行分类,auc为73.3%,本篇讲继续讲如何用PaddlePaddle实现邮件分类,将深度 ...

  3. C# 曲线上的点(一) 获取指定横坐标对应的纵坐标值

    获取直线上的点,很容易,那曲线呢?二阶贝塞尔.三阶贝塞尔.多段混合曲线,如何获取指定横坐标对应的纵坐标? 如下图形: 实现方案 曲线上的点集 Geometry提供了一个函数GetFlattenedPa ...

  4. SAP HUM 拆包之后的HU号码依旧存在

    比如HU 194811210666,已经被执行了Unpack操作. HUMO看这个HU号码, 执行, 可以发现,这个HU是空的,里面什么都没有. 双击HU号码,进入HU显示界面, 系统状态竟然是PHE ...

  5. 关于javascript异步

    1.简单的理解 JavaScript是单线程的!总所周知,正常代码是从上而下,一条一条顺序执行的.就好比下楼梯,第一条代码先获得内存或者先执行操作.当遇到漫长的处理操作时(比如读取庞大的文件时,执行大 ...

  6. 【设计模式】工厂方法模式 Factory Method Pattern

    在简单工厂模式中产品的创建统一在工厂类的静态工厂方法中创建,体现了面形对象的封装性,客户程序不需要知道产品产生的细节,也体现了面向对象的单一职责原则(SRP),这样在产品很少的情况下使用起来还是很方便 ...

  7. 小米平板6.0以上系统如何不用Root激活Xposed框架的步骤

    在异常多公司的引流,或业务操作中,大多数需要使用安卓的神一般的Xposed框架,几天前我们公司买来了一批新的小米平板6.0以上系统,大多数都是基于7.0以上版本,大多数不能够获取Root超级权限,虽然 ...

  8. java:数据结构(二)栈的应用(进制转换全收集)

    说到进制转换,java已经封装了基本的方法,在竞赛中使用封装的方法自然能节省大量时间 另一位仁兄介绍的封装好的方法: https://blog.csdn.net/m0_37961948/article ...

  9. gradle下载及配置

    windows安装 1.下载地址:http://services.gradle.org/distributions/ 2.下载**-bin.zip,解压即可 配置环境变量:gradle_home:D: ...

  10. C#行转列&绑定DGV

    c#行转列 今天工作中,恰好写到此处,想起之前第一次行转列的时候,卡壳了好久,今天正好碰上,故而花费几分钟,整理成案例,分享到博客上. 这是个很简单的功能,第一次可以使用案例,后面最好能达到信手拈来的 ...