关于spring中Assert的应用(方法入参检测工具类)

Web 应用在接受表单提交的数据后都需要对其进行合法性检查,如果表单数据不合法,请求将被驳回。类似的,当我们在编写类的方法时,也常常需要对方法入参进行合 法性检查,如果入参不符合要求,方法将通过抛出异常的方式拒绝后续处理。举一个例子:有一个根据文件名获取输入流的方法:InputStream getData(String file),为了使方法能够成功执行,必须保证 file 入参不能为 null 或空白字符,否则根本无须进行后继的处理。这时方法的编写者通常会在方法体的最前面编写一段对入参进行检测的代码,如下所示:

1
2
3
4
5
6
public InputStream getData(String file) {
    if (file == null || file.length() == 0|| file.replaceAll("//s""").length() == 0) {
        throw new IllegalArgumentException("file入参不是有效的文件地址");
    }
}

类似以上检测方法入参的代码是非常常见,但是在每个方法中都使用手工编写检测逻辑的方式并不是一个好主意。阅读 Spring 源码,您会发现 Spring 采用一个 org.springframework.util.Assert (不是junit下的Assert)通用类完成这一任务。

Assert 翻译为中文为“断言”,使用过 JUnit 的读者都熟知这个概念,它断定某一个实际的运行值和预期想一样,否则就抛出异常。Spring 对方法入参的检测借用了这个概念,其提供的 Assert 类拥有众多按规则对方法入参进行断言的方法,可以满足大部分方法入参检测的要求。这些断言方法在入参不满足要求时就会抛出 IllegalArgumentException。下面,我们来认识一下 Assert 类中的常用断言方法:

断言方法说明

notNull(Object object)

当 object 不为 null 时抛出异常,notNull(Object object, String message) 方法允许您通过 message 定制异常信息。和 notNull() 方法断言规则相反的方法是 isNull(Object object)/isNull(Object object, String message),它要求入参一定是 null;

isTrue(boolean expression) / isTrue(boolean expression, String message)

当 expression 不为 true 抛出异常;

notEmpty(Collection collection) / notEmpty(Collection collection, String message)

当 集合未包含元素时抛出异常。notEmpty(Map map) / notEmpty(Map map, String message) 和 notEmpty(Object[] array, String message) / notEmpty(Object[] array, String message) 分别对 Map 和 Object[] 类型的入参进行判断;

hasLength(String text) / hasLength(String text, String message)

当 text 为 null 或长度为 0 时抛出异常;

hasText(String text) / hasText(String text, String message)

text 不能为 null 且必须至少包含一个非空格的字符,否则抛出异常;

isInstanceOf(Class clazz, Object obj) / isInstanceOf(Class type, Object obj, String message)

如果 obj 不能被正确造型为 clazz 指定的类将抛出异常;

isAssignable(Class superType, Class subType) / isAssignable(Class superType, Class subType, String message)

subType 必须可以按类型匹配于 superType,否则将抛出异常;

使用 Assert 断言类可以简化方法入参检测的代码,如 InputStream getData(String file) 在应用 Assert 断言类后,其代码可以简化为以下的形式:

1
2
3
4
5
public InputStream getData(String file){
    Assert.hasText(file,"file入参不是有效的文件地址"); 
    ① 使用 Spring 断言类进行方法入参检测
}

可见使用 Spring 的 Assert 替代自编码实现的入参检测逻辑后,方法的简洁性得到了不少的提高。Assert 不依赖于 Spring 容器,您可以大胆地在自己的应用中使用这个工具类。

-----------------------------

1
2
3
4
5
6
7
8
9
10
11
12
13
@RestController
public class TestController
{
    private static final Logger LOGGER = LoggerFactory.getLogger(TestController.class);
     
    @RequestMapping("/test1")
    public String test(String name) {
        Assert.hasText(name,"name不能为空"); 
        LOGGER.info("测试日志......");
        return "zhangsan";
    }
     
}

当访问http://localhost:8083/test1时,会报错,提示:

java.lang.IllegalArgumentException: name不能为空

当访问http://localhost:8083/test1?name='lisi'是,程序正常。

关于spring中Assert的应用(方法入参检测工具类)的更多相关文章

  1. Spring Assert(方法入参检测工具类-断言)

    Web 应用在接受表单提交的数据后都需要对其进行合法性检查,如果表单数据不合法,请求将被驳回.类似的,当我们在编写类的方法时,也常常需要对方法入参进行合 法性检查,如果入参不符合要求,方法将通过抛出异 ...

  2. Spring AOP项目应用——方法入参校验 & 日志横切

    转载:https://blog.csdn.net/Daybreak1209/article/details/80591566 应用一:方法入参校验 由于系统多个方法入参均对外封装了统一的Dto,其中D ...

  3. HandlerMethodArgumentResolver(一):Controller方法入参自动封装器【享学Spring MVC】

    每篇一句 你的工作效率高,老板会认为你强度不够.你代码bug多,各种生产环境救火,老板会觉得你是团队的核心成员. 前言 在享受Spring MVC带给你便捷的时候,你是否曾经这样疑问过:Control ...

  4. Mybatis方法入参处理

    1,在单个入参的情况下,mybatis不做任何处理,#{参数名} 即可,甚至连参数名都可以不需要,因为只有一个参数,或者使用 Mybatis的内置参数 _parameter. 2,多个入参: 接口方法 ...

  5. js方法入参或局部变量和全局变量重名,用来赋值全局变量会失败

    今天遇到个bug,最后终于知道原因了,js方法入参和全局变量重名,用入参赋值全局变量失败,就是说方法入参不能和全局变量重名. 现在下面的例子也说明,局部变量和全局变量不可以同名不光是入参,只要同名赋值 ...

  6. frida框架hook参数获取方法入参模板

    python脚本 # -*- coding: utf-8 -*- import logging import frida import sys logging.basicConfig(level=lo ...

  7. Java中创建操作文件和文件夹的工具类

    Java中创建操作文件和文件夹的工具类 FileUtils.java import java.io.BufferedInputStream; import java.io.BufferedOutput ...

  8. Java中windows路径转换成linux路径等工具类

    项目中发现别人写好的操作系统相关的工具类: 我总结的类似相关博客:http://www.cnblogs.com/DreamDrive/p/4289860.html import java.net.In ...

  9. Java中常用的加密方式(附多个工具类)

    一.Java常用加密方式 Base64加密算法(编码方式) MD5加密(消息摘要算法,验证信息完整性) 对称加密算法 非对称加密算法 数字签名算法 数字证书 二.分类按加密算法是否需要key被分为两类 ...

随机推荐

  1. MySQL 字符串截取函数

    MySQL 字符串截取函数:left(), right(), substring(), substring_index().还有 mid(), substr().其中,mid(), substr() ...

  2. Spring注入的不同方式

    1.直接创建一个Bean <bean id="dboperate" class="study.spring2.Test"></bean> ...

  3. Vue项目框架

    Vue项目框架 基本组件的使用: new Vue({ el, //要绑定的DOM element data, //要绑定的资料 props, //可用来接收父原件资料的属性 template, //要 ...

  4. 【模板】BM + CH(线性递推式的求解,常系数齐次线性递推)

    这里所有的内容都将有关于一个线性递推: $f_{n} = \sum\limits_{i = 1}^{k} a_{i} * f_{n - i}$,其中$f_{0}, f_{1}, ... , f_{k ...

  5. Go 语言中的方法,接口和嵌入类型

    https://studygolang.com/articles/1113 概述 在 Go 语言中,如果一个结构体和一个嵌入字段同时实现了相同的接口会发生什么呢?我们猜一下,可能有两个问题: 编译器会 ...

  6. PostgreSQL(一)教程 -----高级特性

    一.视图 假设天气记录和城市为止的组合列表对我们的应用有用,但我们又不想每次需要使用它时都敲入整个查询.我们可以在该查询上创建一个视图,这会给该查询一个名字,我们可以像使用一个普通表一样来使用它: C ...

  7. c/c++ 某些特殊数的大小

    INT_MAX:2^31-1 2147483647 RAND_MAX:2^15-1    32768

  8. 「Django」浏览+1的操作

    适应于网页.文章等浏览次数统计 1.Models设置:添加viewed方法 class NewsTitle(models.Model): title = models.CharField(max_le ...

  9. POJ - 2299 Ultra-QuickSort(归并排序)

    https://vjudge.net/problem/POJ-2299 题意 求对于给定的无序数组,求出经过最少多少次相邻元素的交换之后,可以使数组从小到大有序. 分析 很明显是求逆序对的数目,那就要 ...

  10. Java入门系列(八)多线程

    基本线程类指的是Thread类,Runnable接口,Callable接口 典型多线程问题 生产者-消费者 死锁问题