【Spring技术原理】SpringMVC集成Java Bean Validation实现参数检验功能

简介: 【Spring技术原理】SpringMVC集成Java Bean Validation实现参数检验功能

目前Bean Validation(JSR-349)的新特性可以到官网查看,之前用的参数校验有很多,主要集中于:


  • 跨参数验证(比如密码和确认密码的验证)
  • 支持在消息中使用EL表达式
  • 方法参数/返回值验证
  • CDI和依赖注入
  • 分组转换



最开始接触Java Bean Validation的时候是Hibernate validator 5,而且spring4才开始使用的,接下来我们从以下几个方法讲解Bean Validation,当然不一定是新特性:


  • 集成Java Bean Validation到SpringMVC
  • 分组验证、分组顺序及级联验证
  • 消息中使用EL表达式
  • 方法参数/返回值验证
  • 自定义验证规则
  • 类级别验证器
  • 脚本验证器
  • cross-parameter,跨参数验证
  • 混合类级别验证器和跨参数验证器
  • 组合多个验证注解
  • 本地化


因为大多数时候验证都配合web框架使用,而且很多朋友都咨询过如分组/跨参数验证,所以本文介绍下这些,且是和SpringMVC框架集成的例子,其他使用方式(比如集成到JPA中)可以参考其官方文档:





添加hibernate validator依赖:


<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>latest.version</version>
</dependency>
复制代码


如果想在消息中使用EL表达式,请确保EL表达式版本是 2.2或以上,至少需要进行Tomcat7以上。

<dependency>  
    <groupId>javax.el</groupId>  
    <artifactId>javax.el-api</artifactId>  
    <version>2.2.4</version>  
    <scope>provided</scope>  
</dependency>  
复制代码


请确保您使用的Web容器有相应版本的el jar包。




web服务的展示


@Controller
public class HelloWorldController {
    @RequestMapping("/validate/hello")
    public String validate(@Valided @ModelAttribute("user") UserModel user, Errors errors) {
        if(errors.hasErrors()) {
            return "validate/error";
        }
        return "redirect:/success";
    }
}
复制代码



硬编码错误消息


直接在验证约束注解上指定错误消息,如下所示:

@NotNull(message = "用户名不能为空")
@Length(min=5, max=20, message="用户名长度必须在5-20之间")
@Pattern(regexp = "^[a-zA-Z_]\\w{4,19}$", message = "用户名必须以字母下划线开头,可由字母数字下划线组成")
private String username;
复制代码


如上所示,错误消息使用硬编码指定,这种方式是不推荐使用的,因为在如下场景是不适用的:


  1. 在国际化场景下,需要对不同的国家显示不同的错误消息;
  2. 需要更换错误消息时是比较麻烦的,需要找到相应的类进行更换,并重新编译发布。




交接于资源文件


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

public class User implements Serializable {
    @NotNull(message = "{user.id.null}")
    private Long id;
    @NotEmpty(message = "{user.name.null}")
    @Length(min = 5, max = 20, message = "{user.name.length.illegal}")
    @Pattern(regexp = "[a-zA-Z]{5,20}", message = "{user.name.illegal}")
    private String name;
    @NotNull(message = "{user.password.null}")
    private String password;
}
复制代码



错误信息内容


默认的错误消息键值如下图所示:


  • 消息键默认为:验证约束注解的全限定类名.message。
  • 在我们之前的测试文件中,错误消息键值是使用默认的,如何自定义错误消息文件和错误消息键值呢?



自定义的错误消息文件和错误消息键值


  • 自定义错误消息文件里的错误消息键值将覆盖默认的错误消息文件中的错误消息键值。
  • 自定义错误消息文件是具有国际化功能的。



定义错误消息文件


在类装载路径的根下创建ValidationMessages.properties文件,如在src目录下创建会自动复制到类装载路径的根下,并添加如下消息键值


自定义的错误消息文件和错误消息键值 自定义的错误消息文件里的错误消息键值将覆盖默认的错误消息文件中的错误消息键值。我们自定义的错误消息文件是具有国际化功能的。


javax.validation.constraints.Pattern.message=用户名必须以字母或下划线开头,后边可以跟字母数字下划线,长度在5-20之间。


  • org.springframework.validation.beanvalidation.LocalValidatorFactoryBean
  • org.hibernate.validator.HibernateValidator


此时错误消息键值的查找会先到classpath下ValidationMessages.properties中找,找不到再到默认的错误消息文件中找。


使用Spring的MessageSource Bean进行消息键值的查找 如果我们的环境是与spring集成,还是应该使用Spring提供的消息支持,具体配置如下


  • org.springframework.context.support.ReloadableResourceBundleMessageSource
  • basename:classpath:messages
  • fileEncodings:utf-8
  • cacheSeconds:120



在消息文件src/messages.properties中添加如下错误消息:


  • javax.validation.constraints.Pattern.message=用户名必须以字母或下划线开头,后边可以跟字母数字下划线,长度在5-20之间。



配置了messageSource Bean时,默认将为验证的对象自动生成如下错误消息键:


  • 验证错误注解简单类名.验证对象名.字段名
  • 验证错误注解简单类名.字段名
  • 验证错误注解简单类名.字段类型全限定类名
  • 验证错误注解简单类名


使用的优先级是:从高到低,即最前边的具有最高的优先级,而且以上所有默认的错误消息键优先级高于自定义的错误消息键。


public String pattern(@Valided @ModelAttribute("model") PatternModel model, Errors errors)
复制代码


将自动产生如下错误消息键:


  • Pattern.model.value=验证错误注解简单类名.验证对象名.字段名
  • Pattern.value=验证错误注解简单类名.字段名
  • Pattern.java.lang.String=验证错误注解简单类名.字段类型全限定类名
  • Pattern=验证错误注解简单类名




自定义错误消息键值


大部分场景下,以上两种方式无法满足我们的需求,因此我们需要自定义错误消息键值。

public class PatternModel {
    @Pattern(regexp = "^[a-zA-Z_][\\w]{4,19}$", message="{user.name.error}")
    private String value;
}
复制代码


在消息文件src/messages.properties中添加如下错误消息:

user.name.error=用户名格式不合法


在消息文件src/messages.properties中添加如下错误消息:

@Length(min=5, max=20, message="{user.name.length.error}")  
复制代码


  • user.name.length.error=用户名长度必须在5-20之间

错误消息中的5-20应该是从@Length验证约束注解中获取的,而不是在错误消息中硬编码,因此我们需要占位符的支持:

@Length(min=5, max=20, message="{user.name.length.error}")
复制代码


错误消息可以这样写:用户名长度必须在{min}-{max}之间。


错误消息占位符规则:{验证注解属性名}:


  • @Length有min和max属性,则在错误消息文件中可以通过{min}和{max}来获取;
  • @Max有value属性,则在错误消息文件中可以通过{value}来获取。
user.name.length.error=用户名长度必须在{min}-{max}之间
复制代码


功能处理方法上多个验证参数的处理


当我们在一个功能处理方法上需要验证多个模型对象时,需要通过如下形式来获取验证结果:

@RequestMapping("/validate/multi")  
public String multi(  
            @Valid @ModelAttribute("a") A a, BindingResult aErrors,  
            @Valid @ModelAttribute("b") B b, BindingResult bErrors) {  
        if(aErrors.hasErrors()) { //如果a模型对象验证失败  
            return "validate/error";  
        }  
        if(bErrors.hasErrors()) { //如果a模型对象验证失败  
            return "validate/error";  
        }  
        return "redirect:/success";  
}
复制代码


每一个模型对象后边都需要跟一个Errors或BindingResult对象来保存验证结果,其方法体内部可以使用这两个验证结果对象来选择出错时跳转的页面。




相关文章
|
2月前
|
数据可视化 Java BI
将 Spring 微服务与 BI 工具集成:最佳实践
本文探讨了 Spring 微服务与商业智能(BI)工具集成的潜力与实践。随着微服务架构和数据分析需求的增长,Spring Boot 和 Spring Cloud 提供了构建可扩展、弹性服务的框架,而 BI 工具则增强了数据可视化与实时分析能力。文章介绍了 Spring 微服务的核心概念、BI 工具在企业中的作用,并深入分析了两者集成带来的优势,如实时数据处理、个性化报告、数据聚合与安全保障。同时,文中还总结了集成过程中的最佳实践,包括事件驱动架构、集中配置管理、数据安全控制、模块化设计与持续优化策略,旨在帮助企业构建高效、智能的数据驱动系统。
159 1
将 Spring 微服务与 BI 工具集成:最佳实践
|
4月前
|
XML 人工智能 Java
Spring Boot集成Aviator实现参数校验
Aviator是一个高性能、轻量级的Java表达式求值引擎,适用于动态表达式计算。其特点包括支持多种运算符、函数调用、正则匹配、自动类型转换及嵌套变量访问,性能优异且依赖小。适用于规则引擎、公式计算和动态脚本控制等场景。本文介绍了如何结合Aviator与AOP实现参数校验,并附有代码示例和仓库链接。
254 0
|
4月前
|
安全 Java 数据库
第16课:Spring Boot中集成 Shiro
第16课:Spring Boot中集成 Shiro
691 0
|
4月前
|
消息中间件 存储 Java
第15课: Spring Boot中集成ActiveMQ
第15课: Spring Boot中集成ActiveMQ
409 0
|
2月前
|
监控 Cloud Native Java
Spring Integration 企业集成模式技术详解与实践指南
本文档全面介绍 Spring Integration 框架的核心概念、架构设计和实际应用。作为 Spring 生态系统中的企业集成解决方案,Spring Integration 基于著名的 Enterprise Integration Patterns(EIP)提供了轻量级的消息驱动架构。本文将深入探讨其消息通道、端点、过滤器、转换器等核心组件,以及如何构建可靠的企业集成解决方案。
203 0
|
4月前
|
Java 关系型数据库 数据库连接
Spring Boot项目集成MyBatis Plus操作PostgreSQL全解析
集成 Spring Boot、PostgreSQL 和 MyBatis Plus 的步骤与 MyBatis 类似,只不过在 MyBatis Plus 中提供了更多的便利功能,如自动生成 SQL、分页查询、Wrapper 查询等。
356 3
|
7月前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
438 70
|
安全 前端开发 Java
随着企业应用复杂度提升,Java Spring框架以其强大与灵活特性简化开发流程,成为构建高效、可维护应用的理想选择
随着企业应用复杂度提升,Java Spring框架以其强大与灵活特性简化开发流程,成为构建高效、可维护应用的理想选择。依赖注入使对象管理交由Spring容器处理,实现低耦合高内聚;AOP则分离横切关注点如事务管理,增强代码模块化。Spring还提供MVC、Data、Security等模块满足多样需求,并通过Spring Boot简化配置与部署,加速微服务架构构建。掌握这些核心概念与工具,开发者能更从容应对挑战,打造卓越应用。
138 1
|
8月前
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
171 0