0
点赞
收藏
分享

微信扫一扫

Hutool工具类的使用

you的日常 2022-02-18 阅读 178
java后端

Hutool工具

如要查看详细文档,请到Hutool官方文档查看

包含的组件

hutool-aopJDK动态代理封装,提供非IOC下的切面支持
hutool-bloomFilter布隆过滤,提供一些Hash算法的布隆过滤
hutool-cache简单缓存实现
hutool-core核心,包括Bean操作、日期、各种Util等
hutool-cron定时任务模块,提供类Crontab表达式的定时任务
hutool-crypto加密解密模块,提供对称、非对称和摘要算法封装
hutool-dbJDBC封装后的数据操作,基于ActiveRecord思想
hutool-dfa基于DFA模型的多关键字查找
hutool-extra扩展模块,对第三方封装(模板引擎、邮件、Servlet、二维码、Emoji、FTP、分词等)
hutool-http基于HttpUrlConnection的Http客户端封装
hutool-log自动识别日志实现的日志门面
hutool-script脚本执行封装,例如Javascript
hutool-setting功能更强大的Setting配置文件和Properties封装
hutool-system系统参数调用封装(JVM信息等)
hutool-jsonJSON实现
hutool-captcha图片验证码实现
hutool-poi针对POI中Excel和Word的封装
hutool-socket基于Java的NIO和AIO的Socket封装
hutool-jwtJSON Web Token (JWT)封装实现

maven方式安装

pom.xml文件中引入依赖

hutool-all所有的组件都在

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.20</version>
</dependency>

类型转换工具(Convert类)

Convert类可以说是一个工具方法类,里面封装了针对Java常见类型的转换,用于简化类型转换。Convert类中大部分方法为toXXX,参数为Object,可以实现将任意可能的类型转换为指定类型。同时支持第二个参数defaultValue用于在转换失败时返回一个默认值。

转换字符串

int a = 1;
//aStr为"1"
String aStr = Convert.toStr(a);

long[] b = {1,2,3,4,5};
//bStr为:"[1, 2, 3, 4, 5]"
String bStr = Convert.toStr(b);

转日期

String a = "2017-05-06";
Date value = Convert.toDate(a);

数组转集合

String[] a = {"a", "你", "好"};
List<String> list = Convert.toList(a);

其他类型转换

标准类型

通过Convert.convert(Class, Object)方法可以将任意类型转换为指定类型,Hutool中预定义了许多类型转换,例如转换为URI、URL、Calendar等等,这些类型的转换都依托于ConverterRegistry类。通过这个类和Converter接口,我们可以自定义一些类型转换。

泛型类型

通过convert(TypeReference reference, Object value)方法,自行new一个TypeReference对象可以对嵌套泛型进行类型转换。例如,我们想转换一个对象为List类型,此时传入的标准Class就无法满足要求,此时我们可以这样:

Object[] a = { "a", "你", "好", "", 1 };
List<String> list = Convert.convert(new TypeReference<List<String>>() {}, a);

Date日期工具

获取当前时间

//当前时间
Date date = DateUtil.date();
//当前时间
Date date2 = DateUtil.date(Calendar.getInstance());
//当前时间
Date date3 = DateUtil.date(System.currentTimeMillis());
//当前时间字符串,格式:yyyy-MM-dd HH:mm:ss
String now = DateUtil.now();
//当前日期字符串,格式:yyyy-MM-dd
String today= DateUtil.today();

字符串转日期

DateUtil.parse方法会自动识别一些常用格式

// 自动识别的转换
String dateStr = "2017-03-01";
Date date = DateUtil.parse(dateStr);

// 自定义日期格式化
String dateStr = "2017-03-01";
Date date = DateUtil.parse(dateStr, "yyyy-MM-dd");

格式化日期输出

String dateStr = "2017-03-01";
Date date = DateUtil.parse(dateStr);

//结果 2017/03/01
String format = DateUtil.format(date, "yyyy/MM/dd");

//常用格式的格式化,结果:2017-03-01
String formatDate = DateUtil.formatDate(date);

//结果:2017-03-01 00:00:00
String formatDateTime = DateUtil.formatDateTime(date);

//结果:00:00:00
String formatTime = DateUtil.formatTime(date);

获取Date对象某部分

Date date = DateUtil.date();
//获得年的部分
DateUtil.year(date);
//获得月份,从0开始计数 0~11
DateUtil.month(date);
//获得月份枚举
DateUtil.monthEnum(date);

获取开始和结束时间

String dateStr = "2017-03-01 22:33:23";
Date date = DateUtil.parse(dateStr);

//一天的开始,结果:2017-03-01 00:00:00
Date beginOfDay = DateUtil.beginOfDay(date);

//一天的结束,结果:2017-03-01 23:59:59
Date endOfDay = DateUtil.endOfDay(date);
......

日期时间偏移

String dateStr = "2017-03-01 22:33:23";
Date date = DateUtil.parse(dateStr);

//结果:2017-03-03 22:33:23
Date newDate = DateUtil.offset(date, DateField.DAY_OF_MONTH, 2);

//常用偏移,结果:2017-03-04 22:33:23
DateTime newDate2 = DateUtil.offsetDay(date, 3);

//常用偏移,结果:2017-03-01 19:33:23
DateTime newDate3 = DateUtil.offsetHour(date, -3);

简化的偏移方法(例如昨天、上周、上个月等):

//昨天
DateUtil.yesterday()
//明天
DateUtil.tomorrow()
//上周
DateUtil.lastWeek()
//下周
DateUtil.nextWeek()
//上个月
DateUtil.lastMonth()
//下个月
DateUtil.nextMonth()

其他

//年龄
DateUtil.ageOfNow("1990-01-30");

//是否闰年
DateUtil.isLeapYear(2017);

IO流相关

IO工具类-IoUtil

拷贝文件

BufferedInputStream in = FileUtil.getInputStream("d:/test.txt");
BufferedOutputStream out = FileUtil.getOutputStream("d:/test2.txt");

long copySize = IoUtil.copy(in, out, IoUtil.DEFAULT_BUFFER_SIZE);

流转Reader、Writer

// IoUtil.getReader:将InputStream转为BufferedReader用于读取字符流,它是部分readXXX方法的基础。
BufferedInputStream in = FileUtil.getInputStream("d:/test.txt");
BufferedReader reader = IoUtil.getReader(in, Charsets.UTF_8);

// IoUtil.getWriter:将OutputStream转为OutputStreamWriter用于写入字符流,它是部分writeXXX的基础
BufferedOutputStream out = FileUtil.getOutputStream("d:/test2.txt");
OutputStreamWriter writer = IoUtil.getWriter(out, Charsets.UTF_8);

读取流中的数据

读取流中的内容总结下来,可以分为read方法和readXXX方法。

read方法

read方法有诸多的重载方法,根据参数不同,可以读取不同对象中的内容,这包括:

  • InputStream
  • Reader

这三个重载大部分返回String字符串,为字符流读取提供极大便利。

InputStream示例
BufferedInputStream in = FileUtil.getInputStream("d:/test.txt");
String read = IoUtil.read(in, Charsets.UTF_8);
System.out.println(read);
Reader示例

以下写法过于复杂,只是为了演示效果

BufferedInputStream in = FileUtil.getInputStream("d:/test.txt");
BufferedReader reader = IoUtil.getReader(in, Charsets.UTF_8);
String read = IoUtil.read(reader, true);
System.out.println(read);

控制台输出

this is a file !
世界
hello world
readXXX其他方法

readXXX方法主要针对返回值做一些处理,例如:

  • readBytes 返回byte数组(读取图片等)
  • readHex 读取16进制字符串
  • readObj 读取序列化对象(反序列化)
  • readLines 按行读取
readBytes示例

返回byte数组

// 功能示例,拷贝文件(只为演示效果)
BufferedInputStream inputStream = FileUtil.getInputStream("E:/下载/a.jpg");
byte[] bytes = IoUtil.readBytes(inputStream);

BufferedOutputStream stream = FileUtil.getOutputStream("D:/a.jpg");
IoUtil.write(stream, true, bytes);
readLines按行读取

readLines后返回一个集合,每一行数据是集合中一个元素

BufferedInputStream inputStream = FileUtil.getInputStream("d:/test.txt");
ArrayList<String> strings = IoUtil.readLines(inputStream, Charsets.UTF_8, new ArrayList<>());
System.out.println(strings);
toStream方法

toStream方法则是将某些对象转换为流对象

  • String 转换为ByteArrayInputStream
  • File 转换为FileInputStream

文件工具类-FileUtil

  • ls 列出目录和文件
  • touch 创建文件,如果父目录不存在也自动创建
  • mkdir 创建目录,会递归创建每层目录
  • del 删除文件或目录(递归删除,不判断是否为空),这个方法相当于Linux的delete命令
  • copy 拷贝文件或目录

touch创建文件

// 创建文件,如果父目录不存在也自动创建
File touch = FileUtil.touch("D:/file2/a.txt");
System.out.println(touch.getAbsolutePath());

mkdir创建目录,递归创建

File mkdir = FileUtil.mkdir("D:/file2");
System.out.println(mkdir.getAbsolutePath());

copy文件

copy文件,源文件或目标文件不存在时,会自动创建文件

// param1: 源文件  param2: 目标文件  param3: 是否复写
File copy = FileUtil.copy("D:/test.txt", "D:/file2/test2.txt", true);
System.out.println(copy.getAbsolutePath());

文件读取类-FileReader

在JDK中,同样有一个FileReader类,但是并不如想象中的那样好用,于是Hutool便提供了更加便捷FileReader类。

FileReader提供了以下方法来快速读取文件内容:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vPCgo9ql-1645175298671)(E:\截图3\Snipaste_2022-02-17_12-48-22.png)]

  • readBytes返回字节数组
  • readString返回字符串
//默认UTF-8编码,可以在构造中传入第二个参数做为编码
FileReader reader = new FileReader("D:/test.txt", Charsets.UTF_8);
String result = fileReader.readString();
  • readLines返回字符串集合
FileReader reader = new FileReader("D:/test.txt", Charsets.UTF_8);
List<String> s = reader.readLines();

同时,此类还提供了以下方法用于转换为流或者BufferedReader:

  • getReader
FileReader reader = new FileReader("D:/test.txt", Charsets.UTF_8);
BufferedReader bfReader = reader.getReader();
  • getInputStream
FileReader reader = new FileReader("D:/test.txt", Charsets.UTF_8);
BufferedInputStream stream = reader.getInputStream();

文件写入类-FileWrite

FileWriter writer = new FileWriter("D:/test.txt");
writer.write("test");

写入文件分为追加模式和覆盖模式两类,追加模式可以用append方法,覆盖模式可以用write方法,同时也提供了一个write方法,第二个参数是可选覆盖模式。

追加模式

FileWriter writer = new FileWriter("D:/test.txt", Charsets.UTF_8);
writer.write("test", true);

// 或者
writer.append("aaabbb");

同样,此类提供了:

  • getOutputStream
  • getWriter
  • getPrintWriter

字符串工具类-StrUtil

hasBlank、hasEmpty

就是给定一些字符串,如果一旦有空的就返回true,常用于判断好多字段是否有空的(例如web表单数据)。

这两个方法的区别是hasEmpty只判断是否为null或者空字符串(""),hasBlank则会把不可见字符也算做空,isEmptyisBlank同理。

在这里插入图片描述

boolean aa = StrUtil.hasEmpty("", "aa");
System.out.println(aa);		// true

removePrefix、removeSuffix

这两个是去掉字符串的前缀后缀的,例如去个文件名的扩展名啥。

去掉前缀就是把最前面符合的字符去掉

String abc = StrUtil.removePrefix("abc.abc.jpg", "abc.");
System.out.println(abc);	// abc.jpg

去掉后缀同理就是把最后面符合的字符去掉

String abc = StrUtil.removeSuffix("afdsfs.jpg.jpg", ".jpg");
System.out.println(abc);	// afdsfs.jpg

还有忽略大小写的removePrefixIgnoreCaseremoveSuffixIgnoreCase都比较实用

format方法

对用过slf4j的应该很友好0.0

String template = "hell{} worl{}";
String str = StrUtil.format(template, "o", "d"); //str -> hello world

数组工具-ArrayUtil

判空

// 判断空
int[] a = {};
int[] b = null;
ArrayUtil.isEmpty(a);
ArrayUtil.isEmpty(b);

// 判断非空
int[] a = {1,2};
ArrayUtil.isNotEmpty(a);

唯一工具-IdUtil

UUID

UUID全称通用唯一识别码(universally unique identifier),JDK通过java.util.UUID提供了 Leach-Salz 变体的封装。在Hutool中,生成一个UUID字符串方法如下:

//生成的UUID是带-的字符串,类似于:a5c8a5e8-df2b-4706-bea4-08d0939410e3
String uuid = IdUtil.randomUUID();

//生成的是不带-的字符串,类似于:b17f24ff026d40949c85a24f4f375d42
String simpleUUID = IdUtil.simpleUUID();

压缩工具-ZipUtil

ZipUtil就是针对java.util.zip做工具化封装,使压缩解压操作可以一个方法搞定,并且自动处理文件和目录的问题,不再需要用户判断,压缩后的文件也会自动创建文件,自动创建父目录,大大简化的压缩解压的复杂度。

Zip

压缩

ZipUtil.zip 方法提供一系列的重载方法

  • 打包到当前目录(可以打包文件,也可以打包文件夹,根据路径自动判断)

文件或目录必须存在,否则异常

//将test目录下的所有文件目录打包到d:/test.zip
ZipUtil.zip("d:/test");
  • 指定打包后保存的目的地,自动判断目标是文件还是文件夹

源文件或目录必须 存在,否则异常

//将aaa目录下的所有文件目录打包到d:/bbb/目录下的aaa.zip文件中
// 此处第二个参数必须为文件,不能为目录
ZipUtil.zip("d:/aaa", "d:/bbb/aaa.zip");
  • 可选是否包含被打包的目录。比如我们打包一个照片的目录,打开这个压缩包有可能是带目录的,也有可能是打开压缩包直接看到的是文件。zip方法增加一个boolean参数可选这两种模式,以应对众多需求。

源文件或目录必须存在

//将aaa目录以及其目录下的所有文件目录打包到d:/bbb/目录下的ccc.zip文件中
// true: 带目录
// false: 不带目录 (默认值)
ZipUtil.zip("d:/aaa", "d:/bbb/ccc.zip", true);
  • 多文件或目录压缩。可以选择多个文件或目录一起打成zip包。
ZipUtil.zip(FileUtil.file("d:/ccc/ccc.zip"), false,
            FileUtil.file("d:/aaa"),
            FileUtil.file("d:/bbb")
);

注意点:

假如上面代码块中,aaa和bbb目录下的文件重名了,并且压缩时选择了false(不带目录),由于文件重名会导致报错,同样的会抛出异常;但是压缩文件还是会生成,只是压缩包中只存在一个文件

解压

ZipUtil.unzip 解压。同样有几个重载,满足不同需求。

源文件或目录必须存在,否则异常

//将test.zip解压到e:\\aaa目录下,返回解压到的目录
File unzip = ZipUtil.unzip("E:/aaa/test.zip", "e:/aaa");

解压报错

  • 解压时报java.lang.IllegalArgumentException:MALFORMED错误

基本是因为编码问题,Hutool默认使用UTF-8编码,自定义为其他编码即可(一般为GBK)。

File unzip = ZipUtil.unzip("E:/aaa/test.zip", "e:/aaa", CharsetUtil.CHARSET_GBK);

Http客户端(Hutool-http)

Hutool-http的核心集中在两个类:

  • HttpRequest
  • HttpResponse

Hutool-http优点

  1. 根据URL自动判断是请求HTTP还是HTTPS,不需要单独写多余的代码。
  2. 表单数据中有File对象时自动转为multipart/form-data表单,不必单做做操作。
  3. 默认情况下Cookie自动记录,比如可以实现模拟登录,即第一次访问登录URL后后续请求就是登录状态。
  4. 自动识别304跳转并二次请求
  5. 自动识别页面编码,即根据header信息或者页面中的相关标签信息自动识别编码,最大可能避免乱码。
  6. 自动识别并解压Gzip格式返回内容

HttpUtil快速请求普通页面

针对最为常用的GET和POST请求,HttpUtil封装了两个方法,

  • HttpUtil.get
  • HttpUtil.post

这两个方法用于请求普通页面,然后返回页面内容的字符串,同时提供一些重载方法用于指定请求参数(指定参数支持File对象,可实现文件上传,当然仅仅针对POST请求)。

get请求

// 最简单的HTTP请求,可以自动通过header等信息判断编码,不区分HTTP和HTTPS
String result1 = HttpUtil.get("https://www.baidu.com");

// 当无法识别页面编码的时候,可以自定义请求页面的编码
String result2 = HttpUtil.get("https://www.baidu.com", CharsetUtil.CHARSET_UTF_8);

//可以单独传入http参数,这样参数会自动做URL编码,拼接在URL中
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("city", "北京");

String result3 = HttpUtil.get("https://www.baidu.com", paramMap);

post请求

//POST请求
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("city", "北京");

String result = HttpUtil.post(url, paramMap);

文件上传

HashMap<String, Object> paramMap = new HashMap<>();
//文件上传只需将参数中的键指定(默认file),值设为文件对象即可,对于使用者来说,文件上传与普通表单提交并无区别
paramMap.put("file", FileUtil.file("D:/face.jpg"));

String result= HttpUtil.post("https://www.baidu.com", paramMap);

文件下载

下载文件到指定目录下

HttpUtil.downloadFile方法

String fileUrl = "http://xxxisos/x86_64/CentOS-8.4.2105-x86_64-dvd1.iso";

//将文件下载后保存在E盘,返回结果为下载文件大小
long size = HttpUtil.downloadFile(fileUrl, FileUtil.file("e:/"));
System.out.println("Download size: " + size);
下载文件到流

HttpUtil.download方法

String fileUrl = "http://xxx/isos/x86_64/CentOS-8.4.2105-x86_64-dvd1.iso";
long size = HttpUtil.download(fileUrl, response.getOutputStream(), true);
System.out.println("Download size: " + size);

HttpRequest

普通表单

//链式构建请求
String result2 = HttpRequest.post(url)
    .header(Header.USER_AGENT, "Hutool http")//头信息,多个头信息多次调用此方法即可
    .form(paramMap)//表单内容
    .timeout(20000)//超时,毫秒
    .execute().body();

通过链式构建请求,我们可以很方便的指定Http头信息和表单信息,最后调用execute方法即可执行请求,返回HttpResponse对象。HttpResponse包含了服务器响应的一些信息,包括响应的内容和响应的头信息。通过调用body方法即可获取响应内容

Restful请求

String json = "......";
// 将json参数放入请求体中
String result2 = HttpRequest.post(url)
    .body(json)
    .execute().body();

创建其他请求方式

HttpRequest request = HttpUtil.createRequest(Method.GET, "http://xxx/xxxxxx");
HttpRequest request = HttpUtil.createRequest(Method.DELETE, "http://xxx/xxxxxx");
HttpRequest request = HttpUtil.createRequest(Method.POST, "http://xxx/xxxxxx");

二维码工具-QrCodeUtil

引入zxing依赖

<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.3.3</version>
</dependency>

生成二维码

// 生成指定url对应的二维码到文件,宽和高都是300像素
QrCodeUtil.generate("https://hutool.cn/", 300, 300, FileUtil.file("d:/qrcode.jpg"));

在这里插入图片描述

自定义参数

基本参数

通过QrConfig可以自定义二维码的生成参数,例如长、宽、二维码的颜色、背景颜色、边距等参数,使用方法如下:

QrConfig config = new QrConfig(300, 300);
// 设置边距,既二维码和背景之间的边距
config.setMargin(2);
// 设置前景色,既二维码颜色(青色)
config.setForeColor(Color.blue);
// 设置背景色(灰色)
config.setBackColor(Color.lightGray);
// 生成二维码到文件,也可以到流
QrCodeUtil.generate("http://hutool.cn/", config, FileUtil.file("d:/qrcode.jpg"));

在这里插入图片描述

带logo图标

QrConfig config = new QrConfig(300, 300);
// 设置边距,既二维码和背景之间的边距
config.setMargin(2);
// 设置前景色,既二维码颜色(青色)
config.setForeColor(Color.blue);
// 设置背景色(灰色)
config.setBackColor(Color.lightGray);
// 设置logo
config.setImg("E:/下载/java.jpg");
QrCodeUtil.generate(
    "http://hutool.cn/", //二维码内容
    config,
    FileUtil.file("D:/qrcodeWithLogo.jpg")//写出到的文件,或者写入流
);

在这里插入图片描述

调整纠错级别

很多时候,二维码无法识别,这时就要调整纠错级别。纠错级别使用zxing的ErrorCorrectionLevel枚举封装,包括:L、M、Q、H几个参数,由低到高。低级别的像素块更大,可以远距离识别,但是遮挡就会造成无法识别。高级别则相反,像素块小,允许遮挡一定范围,但是像素块更密集

QrConfig config = new QrConfig();
// 高纠错级别
config.setErrorCorrection(ErrorCorrectionLevel.H);
QrCodeUtil.generate("https://hutool.cn/", config, FileUtil.file("e:/qrcodeCustom.jpg"));

在这里插入图片描述

识别二维码

// decode -> "http://hutool.cn/" 获取到url
String decode = QrCodeUtil.decode(FileUtil.file("d:/qrcode.jpg"));
举报

相关推荐

0 条评论