详解SpringMVC验证框架Validation特殊用法

发布时间 - 2026-01-10 23:16:38    点击率:

基本用法不说了,网上例子很多,这里主要介绍下比较特殊情况下使用的方法。

1. 分组

有的时候,我们对一个实体类需要有多中验证方式,在不同的情况下使用不同验证方式,比如说对于一个实体类来的id来说,保存的时候是不需要的,对于更新时是必须的,可以如下配置:

public class UserModel { 
 
  @NotNull(message = "{id.empty}", groups = { First.class }) 
  private int id; 
 
  @NotNull(message = "{username.empty}", groups = { First.class, Second.class }) 
  private String username; 
 
  @NotNull(message = "{content.empty}", groups = { First.class, Second.class }) 
  private String content; 
 
  public int getId() { 
    return id; 
  } 
 
  public void setId(int id) { 
    this.id = id; 
  } 
 
  public String getUsername() { 
    return username; 
  } 
 
  public void setUsername(String username) { 
    this.username = username; 
  } 
 
  public String getContent() { 
    return content; 
  } 
 
  public void setContent(String content) { 
    this.content = content; 
  } 
} 
public interface First { 
} 
 
public interface Second { 
} 

通过 groups 对验证进行分组

在controler中的代码如下:

@RequestMapping(value = "/save.action", method = RequestMethod.POST) 
public String save(@Validated( { Second.class }) UserModel userModel, BindingResult result) { 
  if (result.hasErrors()) { 
    return "validate/error"; 
  } 
  return "redirect:/success"; 
} 
 
@RequestMapping(value = "/update.action", method = RequestMethod.POST) 
public String update(@Validated( { First.class, Second.class }) UserModel user, BindingResult result) { 
  if (result.hasErrors()) { 
    return "validate/error"; 
  } 
  return "redirect:/success"; 
} 

2. 组序列

默认情况下,不同组别的约束验证是无序的,然而在某些情况下,约束验证的顺序却很重要,如下面两个例子:(1)第二个组中的约束验证依赖于一个稳定状态来运行,而这个稳定状态是由第一个组来进行验证的。(2)某个组的验证比较耗时,CPU 和内存的使用率相对比较大,最优的选择是将其放在最后进行验证。因此,在进行组验证的时候尚需提供一种有序的验证方式,这就提出了组序列的概念。

一个组可以定义为其他组的序列,使用它进行验证的时候必须符合该序列规定的顺序。在使用组序列验证的时候,如果序列前边的组验证失败,则后面的组将不再给予验证。

下例中声明了组 GroupA.class,GroupB.class 和 Group.class,其中 default,GroupA,GroupB 均为 Group 的序列。

public interface GroupA { 
} 
 
public interface GroupB { 
} 
 
@GroupSequence( { Default.class, GroupA.class, GroupB.class }) 
public interface Group { 
} 
 
public class User { 
  @NotEmpty(message = "firstname may be empty") 
  private String firstname; 
 
  @NotEmpty(message = "middlename may be empty", groups = Default.class) 
  private String middlename; 
 
  @NotEmpty(message = "lastname may be empty", groups = GroupA.class) 
  private String lastname; 
 
  @NotEmpty(message = "country may be empty", groups = GroupB.class) 
  private String country; 
} 
[java] view plain copy 在CODE上查看代码片派生到我的代码片
@RequestMapping(value = "/update.action", method = RequestMethod.POST) 
public String register(@Validated(Group.class) User user, BindingResult result) { 
  if (result.hasErrors()) { 
    return "validate/error"; 
  } 
  return "redirect:/success"; 
} 

3. 验证多个对象

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

@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对象来保存验证结果,其方法体内部可以使用这两个验证结果对象来选择出错时跳转的页面或处理的逻辑。

4. Junit测试

当自定义拓展Validation时,可以使用如下方法进行测试:

@Test 
public void testValidate() { 
  AnnotationDescriptor<EqualsAny> descriptor = new AnnotationDescriptor<EqualsAny>(EqualsAny.class); 
  EqualsAny equalsAny = AnnotationFactory.create(descriptor); 
  EqualsAnyValidator equalsAnyValidator = new EqualsAnyValidator(); 
  equalsAnyValidator.initialize(equalsAny); 
  Assert.assertTrue(equalsAnyValidator.isValid("123", null)); 
} 

另外再讲一点spring对自定义JSR-303限制类型支持的新特性,那就是Spring支持往ConstraintValidator里面注入bean对象。例如在EqualsAnyValidator中利用@Resource注解注入其他Bean对象。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# springmvc  # validation  # springmvc验证框架  # spring  # Spring自带的校验框架Validation的使用实例  # springboot使用校验框架validation校验的示例  # Spring 使用Validation 验证框架的问题详解  # 情况下  # 多个  # 自定义  # 可以使用  # 放在  # 第一个  # 不需要  # 是由  # 均为  # 将其  # 提出了  # 这就  # 这两个  # 有多  # 第二个  # 实体类  # 当我们  # 跳转  # 比较大  # 却很 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 轻松掌握MySQL函数中的last_insert_id()  想要更高端的建设网站,这些原则一定要坚持!  如何在Windows 2008云服务器安全搭建网站?  Java解压缩zip - 解压缩多个文件或文件夹实例  原生JS获取元素集合的子元素宽度实例  魔方云NAT建站如何实现端口转发?  php静态变量怎么调试_php静态变量作用域调试技巧【解答】  微信小程序 input输入框控件详解及实例(多种示例)  如何使用 Go 正则表达式精准提取括号内首个纯字母标识符(忽略数字与嵌套)  微信小程序 require机制详解及实例代码  Laravel如何配置任务调度?(Cron Job示例)  Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】  iOS验证手机号的正则表达式  HTML 中如何正确使用模板变量为元素的 name 属性赋值  家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?  Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧  香港服务器租用每月最低只需15元?  如何在建站之星绑定自定义域名?  标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?  Laravel如何处理和验证JSON类型的数据库字段  如何在阿里云完成域名注册与建站?  微信h5制作网站有哪些,免费微信H5页面制作工具?  如何在阿里云ECS服务器部署织梦CMS网站?  高防服务器:AI智能防御DDoS攻击与数据安全保障  电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?  香港服务器如何优化才能显著提升网站加载速度?  JavaScript如何实现错误处理_try...catch如何捕获异常?  google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤  Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置  Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】  如何在阿里云通过域名搭建网站?  如何在阿里云域名上完成建站全流程?  制作企业网站建设方案,怎样建设一个公司网站?  Win11怎样安装网易有道词典_Win11安装词典教程【步骤】  EditPlus中的正则表达式实战(5)  Laravel如何自定义错误页面(404, 500)?(代码示例)  EditPlus 正则表达式 实战(3)  如何自定义建站之星模板颜色并下载新样式?  品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?  Laravel如何实现用户注册和登录?(Auth脚手架指南)  Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程  Python自然语言搜索引擎项目教程_倒排索引查询优化案例  Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)  如何构建满足综合性能需求的优质建站方案?  什么是JavaScript解构赋值_解构赋值有哪些实用技巧  小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像  如何在腾讯云服务器上快速搭建个人网站?  零基础网站服务器架设实战:轻量应用与域名解析配置指南  通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】  音响网站制作视频教程,隆霸音响官方网站?