一、URLUtil
该工具类专门用于处理url。
1、url
通过该方法可以将一个字符串转换为URL对象,代码如下:
//将字符串转换为URL对象
public void urlTest {
URL url = URLUtil.url("http://localhost:8080/name=zhangsan&age=20");
//获取URL中域名部分,只保留URL中的协议
URI uri = URLUtil.getHost(url);
System.out.println(uri);
}
运行结果:
http://localhost
2、getURL
该方法用于获得URL,常用于使用绝对路径时的情况 ,代码如下:
//获得URL,常用于使用绝对路径时的情况
public void getURLTest {
URL url = URLUtil.getURL(FileUtil.file("URLUtilTest.java"));
System.out.println(url.toString);
}
运行结果:
file:/C:/Users/Administrator/Desktop/ideaworkspace/HuTool/out/production/HuTool/URLUtilTest.java
该方法通过文件名就可以获取到该文件的绝对路径,这在使用绝对路径的场景中非常方便。
3、normalize
该方法用于标准化URL链接,代码如下:
//标准化化URL链接
public void normalizeTest {
String url = "www.baidu.com\\example\\test/a";
String newUrl = URLUtil.normalize(url);
System.out.println(newUrl);
}
运行结果:
http://www.baidu.com/example/test/a
该方法会对不带http://头的链接进行自动补全,并统一格式。
4、getPath
该方法用于获取URL链接中的path部分字符串,比如:
//获得path部分
public void getPathTest {
String url = "http://localhost/search?name=abc&age=20";
String pathStr = URLUtil.getPath(url);
System.out.println(pathStr);
}
运行结果:
/search
二、RuntimeUtil
该工具类用于执行命令行命令,在Windows下是cmd,在Linux下是shell。 这里直接贴出代码:
public void RunTimeUtilTest{
String str = RuntimeUtil.execForStr("ipconfig");
System.out.println(str);
}
运行结果:
Windows IP 配置
以太网适配器 以太网:
媒体状态 . . . . . . . . . . . . : 媒体已断开连接
连接特定的 DNS 后缀 . . . . . . . :
无线局域网适配器 本地连接* 1:
媒体状态 . . . . . . . . . . . . : 媒体已断开连接
连接特定的 DNS 后缀 . . . . . . . :
无线局域网适配器 本地连接* 2:
媒体状态 . . . . . . . . . . . . : 媒体已断开连接
连接特定的 DNS 后缀 . . . . . . . :
无线局域网适配器 WLAN:
连接特定的 DNS 后缀 . . . . . . . : www.tendawifi.com
本地链接 IPv6 地址. . . . . . . . : fe80::830:2d92:1427:a434%17
IPv4 地址 . . . . . . . . . . . . : 192.168.0.103
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . : 192.168.0.1
三、IdCardUtil
在日常开发中,我们对身份证的验证主要是正则方式(位数,数字范围等),但是中国身份证,尤其18位身份证每一位都有严格规定,并且最后一位为校验位。而我们在实际应用中,针对身份证的验证理应严格至此。于是IdcardUtil应运而生。 IdcardUtil现在支持大陆15位、18位身份证,港澳台10位身份证。 工具中主要的方法包括:
isValidCard验证身份证是否合法
convert15To18身份证15位转18位
getBirthByIdCard获取生日
getAgeByIdCard获取年龄
getYearByIdCard获取生日年
getMonthByIdCard获取生日月
getDayByIdCard获取生日天
getGenderByIdCard获取性别
getProvinceByIdCard获取省份
使用
String ID_15 = "150102880730303";
String ID_18 = "321083197812162119";
//转换
String convert15To18 = IdcardUtil.convert15To18(ID_15);
System.out.println(ID_15 + " convert15To18 = " + convert15To18);
//是否有效
System.out.println(ID_15 + " is valid: " + IdcardUtil.isValidCard(ID_15));
System.out.println(ID_18 + " is valid: " + IdcardUtil.isValidCard(ID_18));
System.out.println("150102151730303 is valid: " + IdcardUtil.isValidCard("150102151730303"));
//年龄
int age = IdcardUtil.getAgeByIdCard(ID_18);
System.out.println("年龄 = " + age);
DateTime date = DateUtil.parse("1988-12-16");
int age2 = IdcardUtil.getAgeByIdCard(ID_18, date);
System.out.println("2017-04-10年龄 = " + age2);
//生日
String birth = IdcardUtil.getBirthByIdCard(ID_18);
System.out.println("生日 = " + birth);
//省份
String province = IdcardUtil.getProvinceByIdCard(ID_18);
System.out.println("省份 = " + province);
//性别
int gender = IdcardUtil.getGenderByIdCard(ID_18);
System.out.println("性别 = " + gender);
四、打包工具-ZipUtil
在Java中,对文件、文件夹打包,压缩是一件比较繁琐的事情,我们常常引入Zip4j进行此类操作。但是很多时候,JDK中的zip包就可满足我们大部分需求。ZipUtil就是针对java.util.zip做工具化封装,使压缩解压操作可以一个方法搞定,并且自动处理文件和目录的问题,不再需要用户判断,压缩后的文件也会自动创建文件,自动创建父目录,大大简化的压缩解压的复杂度。
1、Zip
public void zipUtilTest{
ZipUtil.zip("C:/Users/Administrator/Desktop/test.txt");
}
压缩成功。 当然了,你也可以指定压缩后的压缩包存放位置,将路径作为第二个参数传入zip方法即可。 多文件或目录压缩。可以选择多个文件或目录一起打成zip包 :
public void zipUtilTest {
ZipUtil.zip(FileUtil.file("d:/bbb/ccc.zip"), false,
FileUtil.file("d:/test1/file1.txt"),
FileUtil.file("d:/test1/file2.txt"),
FileUtil.file("d:/test2/file1.txt"),
FileUtil.file("d:/test2/file2.txt")
);
}
解压方法为unzip
ZipUtil.unzip("C:/Users/Administrator/Desktop/2.zip");
2、GZip
Gzip是网页传输中广泛使用的压缩方式,Hutool同样提供其工具方法简化其过程。 ZipUtil.gzip压缩,可压缩字符串,也可压缩文件ZipUtil.unGzip解压Gzip文件
3、Zlib
ZipUtil.zlib压缩,可压缩字符串,也可压缩文件ZipUtil.unZlib解压zlib文件
五、随机工具——RandomUtil
随机工具的主要方法如下:
RandomUtil.randomInt 获得指定范围内的随机数
RandomUtil.randomEle 随机获得列表中的元素
RandomUtil.randomString 获得一个随机的字符串(只包含数字和字符)
RandomUtil.randomNumbers 获得一个只包含数字的字符串
RandomUtil.randomNumber 获得一个随机数
RandomUtil.randomChar 获得随机字符
这些方法都有一些重载方法,如下表:
randomInt():int //获得一个随机整数
randomInt(int limit):int //获得一个<limit的随机整数
randomInt(int min,int max):int //获得一个随机整数n(min<=n<max)
randomChar():char //获得一个随机字符
randomChar(Strint str):char //从指定字符串中获得一个随机字符
randomNumber():int //获得一个随机数
randomNumbers(int length):String //获得长度为length由数字组成的字符串
randomString(int length):String //获得一个长度为length的字符串,只包含数字和字符
randomString(String str,int length):String //从str中随机产生指定长度的字符串(所有字符来源于str)
randomEle(T array[]):T //从数组中随机获取一个数据
randomEle(List<T> list):T //从List中随机获取一个数据
randomEle(List<T> list,int limit):T //从List的前limit个中随机获取一个数据(limit从1开始)
六、文件工具——FileUtil
总体来说,FileUtil类包含以下几类操作工具: 文件操作:包括文件目录的新建、删除、复制、移动、改名等 文件判断:判断文件或目录是否非空,是否为目录,是否为文件等等。 绝对路径:针对ClassPath中的文件转换为绝对路径文件。 文件名:主文件名,扩展名的获取 读操作:包括类似IoUtil中的getReader、readXXX操作 写操作:包括getWriter和writeXXX操作
1、常用方法
方法都是按照Linux命令来命名的,方便熟悉Linux的用户见名知意,例如:
ls 返回给定目录的所有文件对象列表,路径可以是相对ClassPath路径或者绝对路径,不可以是压缩包里的路径。
listFileNames 则是返回指定目录下的所有文件名,支持jar等压缩包。
touch 创建文件,如果给定路径父目录不存在,也一同创建。
del 删除文件或者目录,目录下有嵌套目录或者文件会一起删除。
mkdir 创建目录,父目录不存在自动创建。
createTempFile 创建临时文件,在程序运行完毕的时候,这个文件会被删除。
copy 复制文件或目录,目标文件对象可以是目录,自动用原文件名,可以选择是否覆盖目标文件。
move 移动文件或目录,原理是先复制,再删除原文件或目录
isExist 文件或者目录是否存在。
这些方法提供了人性化的操作,例如touch方法,在创建文件的情况下会自动创建上层目录),同样mkdir也会创建父目录。
getAbsolutePath 获得绝对路径,如果给定路劲已经是绝对路径,返回原路径,否则根据ClassPath或者给定类的相对位置获得其绝对位置
close 对于实现了Closeable接口的对象,可以直接调用此方法关闭,且是静默关闭,关闭出错将不会有任何调试信息。这个方法也是使用非常频繁的,例如文件流的关闭等等。
equals 比较两个文件是否相同
2、写文件
getBufferedWriter 获得带缓存的写入对象,可以写字符串等。
getPrintWriter 对 getBufferedWriter的包装,可以有println等方法按照行写出。
getOutputStream 会的文件的写出流想对象。
writeString直接写字符串到文件,会覆盖之前的内容。
appendString 追加字符串到文本。
writeLines appendLines 覆盖写入和追加文本列表,每个元素都是一行。
writeBytes 写字节码。
writeStream 写流中的内容到文件里。
3、读文件
getReader 获得带缓存的Reader对象。
readLines 按行读取文件中的数据,返回List,每一个元素都是一行文本。
load 按照给定的ReaderHandler对象读取文件中的数据,ReaderHandler是一个借口,实现后就可以操作Reader对象了,这个方法存在是为了避免用户手动调用close方法。
readString 直接读出文件中的所有文本。
readBytes 读字节码
4、其他
isModifed 文件是否被修改过,需要传入一个时间戳,用来比对最后修改时间。
getExtension 获得文件的扩展名。
七、ClassUtil
该类主要是封装了一些反射的方法,使得调用更加方便。
1、getShortClassName
该方法用于获取类名的短格式,代码如下:
//获取类名的短格式
public void getShortClassNameTest{
String shortClassName = ClassUtil.getShortClassName("com.wwj.hutool.test.ObjectUtilTest");
System.out.println(shortClassName);
}
运行结果:
c.w.h.t.ObjectUtilTest
2、getPackage
获取指定类的包名,代码如下:
//获取指定类的包名
public void getPackageTest{
String packageName = ClassUtil.getPackage(ObjectUtilTest.class);
System.out.println(packageName);
}
运行结果:
com.wwj.hutool.test
3、scanPackage
这个方法是该工具类的核心,这是一个扫描包下资源的方法,在Spring中用于依赖注入,代码如下:
//扫描包下资源
public void scanPackageTest{
Set<Class<?>> classes = ClassUtil.scanPackage("com.wwj.hutool.test");
for (Class<?> aclass : classes) {
System.out.println(aclass.getName);
}
}
运行结果:
com.wwj.hutool.test.URLUtilTest
com.wwj.hutool.test.StrUtilTest
com.wwj.hutool.test.ObjectUtilTest
该方法需要传递一个包名作为参数,然后便会在指定的包下扫描所有的类,你还可以通过传入ClassFilter对象来过滤掉指定的类。
4、getJavaClassPaths
该方法用于获取Java的系统变量定义的ClassPath。
public void scanPackageTest{
String javaClassPaths = ClassUtil.getJavaClassPaths;
for (String javaClassPath : javaClassPaths) {
System.out.println(javaClassPath);
}
}
运行结果:
F:\Tool\IntelliJ IDEA 2018.3\lib\idea_rt.jar
F:\Tool\IntelliJ IDEA 2018.3\plugins\junit\lib\junit-rt.jar
F:\Tool\IntelliJ IDEA 2018.3\plugins\junit\lib\junit5-rt.jar
E:\Java\jdk1.8.0_181\jre\lib\charsets.jar
E:\Java\jdk1.8.0_181\jre\lib\deploy.jar
......
八、Hutool之验证码工具——CaptchaUtil
使用Hutool [生成和验证] 图形验证码
验证码功能位于com.hutool.captcha包中,核心接口为ICaptcha,此接口定义了以下方法:
createCode 创建验证码,实现类需同时生成随机验证码字符串和验证码图片
getCode 获取验证码的文字内容
verify 验证验证码是否正确,建议忽略大小写
write 将验证码写出到目标流中
其中write方法只有一个OutputStream,ICaptcha实现类可以根据这个方法封装写出到文件等方法。
AbstractCaptcha为一个ICaptcha抽象实现类,此类实现了验证码文本生成、非大小写敏感的验证、写出到流和文件等方法,通过继承此抽象类只需实现createImage方法定义图形生成规则即可。
实现类
- LineCaptcha 线段干扰的验证码, 生成效果大致如下:

//定义图形验证码的长和宽
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
//LineCaptcha lineCaptcha = new LineCaptcha(200, 100, 4, 150);
//图形验证码写出,可以写出到文件,也可以写出到流
lineCaptcha.write("d:/line.png");
//验证图形验证码的有效性,返回boolean值
lineCaptcha.verify("1234");
- CircleCaptcha 圆圈干扰验证码

//定义图形验证码的长、宽、验证码字符数、干扰元素个数
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20);
//CircleCaptcha captcha = new CircleCaptcha(200, 100, 4, 20);
//图形验证码写出,可以写出到文件,也可以写出到流
captcha.write("d:/circle.png");
//验证图形验证码的有效性,返回boolean值
captcha.verify("1234");
- ShearCaptcha 扭曲干扰验证码

//定义图形验证码的长、宽、验证码字符数、干扰线宽度
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 100, 4, 4);
//ShearCaptcha captcha = new ShearCaptcha(200, 100, 4, 4);
//图形验证码写出,可以写出到文件,也可以写出到流
captcha.write("d:/shear.png");
//验证图形验证码的有效性,返回boolean值
captcha.verify("1234");
- 写出到浏览器(Servlet输出)
ICaptcha captcha = ...;
captcha.write(response.getOutputStream());
//Servlet的OutputStream记得自行关闭!
- 自定义验证码 有时候标准的验证码不满足要求,比如我们希望使用纯字母的验证码、纯数字的验证码、加减乘除的验证码,此时我们就要自定义CodeGenerator
// 自定义纯数字的验证码(随机4位数字,可重复)
RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
captcha.setGenerator(randomGenerator);
// 重新生成code
captcha.createCode();
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 45, 4, 4);
// 自定义验证码内容为四则运算方式
captcha.setGenerator(new MathGenerator());
// 重新生成code
captcha.createCode();
九、ExcelUtil
读取
读取Excel内容的封装,通过构造ExcelReader对象,指定被读取的Excel文件、流或工作簿,然后调用readXXX方法读取内容为指定格式。
读取Excel中所有行和列,都用列表表示
ExcelReader reader = ExcelUtil.getReader("d:/1.xlsx");
List<List<Object>> readAll = reader.read();
读取为Map列表,默认第一行为标题行,Map中的key为标题,value为标题对应的单元格值。
ExcelReader reader = ExcelUtil.getReader("d:/1.xlsx");
List<Map<String,Object>> readAll = reader.readAll();
读取为Bean列表,Bean中的字段名为标题,字段值为标题对应的单元格值。
ExcelReader reader = ExcelUtil.getReader("d:/1.xlsx");
List<Person> all = reader.readAll(Person.class);
写入
Hutool将Excel写出封装为ExcelWriter,原理为包装了Workbook对象,每次调用merge(合并单元格)或者write(写出数据)方法后只是将数据写入到Workbook,并不写出文件,只有调用flush或者close方法后才会真正写出文件。
由于机制原因,在写出结束后需要关闭ExcelWriter对象,调用close方法即可关闭,此时才会释放Workbook对象资源,否则带有数据的Workbook一直会常驻内存。
使用例子
- 将行列对象写出到Excel 我们先定义一个嵌套的List,List的元素也是一个List,内层的一个List代表一行数据,每行都有4个单元格,最终list对象代表多行数据。
List<String> row1 = CollUtil.newArrayList("aa", "bb", "cc", "dd");
List<String> row2 = CollUtil.newArrayList("aa1", "bb1", "cc1", "dd1");
List<String> row3 = CollUtil.newArrayList("aa2", "bb2", "cc2", "dd2");
List<String> row4 = CollUtil.newArrayList("aa3", "bb3", "cc3", "dd3");
List<String> row5 = CollUtil.newArrayList("aa4", "bb4", "cc4", "dd4");
List<List<String>> rows = CollUtil.newArrayList(row1, row2, row3, row4, row5);
然后我们创建ExcelWriter对象后写出数据:
//通过工具类创建writer
ExcelWriter writer = ExcelUtil.getWriter("d:/writeTest.xlsx");
//通过构造方法创建writer
//ExcelWriter writer = new ExcelWriter("d:/writeTest.xls");
//跳过当前行,既第一行,非必须,在此演示用
writer.passCurrentRow();
//合并单元格后的标题行,使用默认标题样式
writer.merge(row1.size() - 1, "测试标题");
//一次性写出内容,强制输出标题
writer.write(rows, true);
//关闭writer,释放内存
writer.close();
效果: 写出效果图
- 写出Map数据
构造数据:
Map<String, Object> row1 = new LinkedHashMap<>();
row1.put("姓名", "张三");
row1.put("年龄", 23);
row1.put("成绩", 88.32);
row1.put("是否合格", true);
row1.put("考试日期", DateUtil.date());
Map<String, Object> row2 = new LinkedHashMap<>();
row2.put("姓名", "李四");
row2.put("年龄", 33);
row2.put("成绩", 59.50);
row2.put("是否合格", false);
row2.put("考试日期", DateUtil.date());
ArrayList<Map<String, Object>> rows = CollUtil.newArrayList(row1, row2);
写出数据:
// 通过工具类创建writer
ExcelWriter writer = ExcelUtil.getWriter("d:/writeMapTest.xlsx");
// 合并单元格后的标题行,使用默认标题样式
writer.merge(row1.size() - 1, "一班成绩单");
// 一次性写出内容,使用默认样式,强制输出标题
writer.write(rows, true);
// 关闭writer,释放内存
writer.close();
构造数据:
TestBean bean1 = new TestBean();
bean1.setName("张三");
bean1.setAge(22);
bean1.setPass(true);
bean1.setScore(66.30);
bean1.setExamDate(DateUtil.date());
TestBean bean2 = new TestBean();
bean2.setName("李四");
bean2.setAge(28);
bean2.setPass(false);
bean2.setScore(38.50);
bean2.setExamDate(DateUtil.date());
List<TestBean> rows = CollUtil.newArrayList(bean1, bean2);
写出数据:
// 通过工具类创建writer
ExcelWriter writer = ExcelUtil.getWriter("d:/writeBeanTest.xlsx");
// 合并单元格后的标题行,使用默认标题样式
writer.merge(4, "一班成绩单");
// 一次性写出内容,使用默认样式,强制输出标题
writer.write(rows, true);
// 关闭writer,释放内存
writer.close();
- 写出到流
// 通过工具类创建writer,默认创建xls格式
ExcelWriter writer = ExcelUtil.getWriter();
//创建xlsx格式的
//ExcelWriter writer = ExcelUtil.getWriter(true);
// 一次性写出内容,使用默认样式,强制输出标题
writer.write(rows, true);
//out为OutputStream,需要写出到的目标流
writer.flush(out);
// 关闭writer,释放内存
writer.close();
- 写出到客户端下载(写出到Servlet) 写出xls
// 通过工具类创建writer,默认创建xls格式
ExcelWriter writer = ExcelUtil.getWriter();
// 一次性写出内容,使用默认样式,强制输出标题
writer.write(rows, true);
//out为OutputStream,需要写出到的目标流
//response为HttpServletResponse对象
response.setContentType("application/vnd.ms-excel;charset=utf-8");
//test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
response.setHeader("Content-Disposition","attachment;filename=test.xls");
ServletOutputStream out=response.getOutputStream();
writer.flush(out, true);
// 关闭writer,释放内存
writer.close();
//此处记得关闭输出Servlet流
IoUtil.close(out);
Copy to clipboardErrorCopied
写出xlsx
ExcelWriter writer = ExcelUtil.getWriter(true);
writer.write(rows, true);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
response.setHeader("Content-Disposition","attachment;filename=test.xlsx");
writer.flush(out, true);
writer.close();
IoUtil.close(out);
注意 ExcelUtil.getWriter()默认创建xls格式的Excel,因此写出到客户端也需要自定义文件名为XXX.xls,否则会出现文件损坏的提示。 若想生成xlsx格式,请使用ExcelUtil.getWriter(true)创建。
下载提示文件损坏问题解决 有用户反馈按照代码生成的Excel下载后提示文件损坏,无法打开,经过排查,可能是几个问题:
(1)writer和out流没有正确关闭,请在代码末尾的finally块增加关闭。 (2)扩展名不匹配。getWriter默认生成xls,Content-Disposition中也应该是xls,只有getWriter(true)时才可以使用xlsx (3)Maven项目中Excel保存于ClassPath中(src/main/resources下)宏替换导致被破坏,解决办法是添加filtering(参考:blog.csdn.net/qq_42270377… (4)Excel打开提示文件损坏,WPS可以打开。这是Excel的安全性控制导致的,解决办法见:blog.csdn.net/zm9898/arti… 自定义Excel
- 设置单元格背景色
ExcelWriter writer = ...;
// 定义单元格背景色
StyleSet style = writer.getStyleSet();
// 第二个参数表示是否也设置头部单元格背景
style.setBackgroundColor(IndexedColors.RED, false);
- 自定义字体
ExcelWriter writer = ...;
//设置内容字体
Font font = writer.createFont();
font.setBold(true);
font.setColor(Font.COLOR_RED);
font.setItalic(true);
//第二个参数表示是否忽略头部样式
writer.getStyleSet().setFont(font, true);
- 写出多个sheet
//初始化时定义表名
ExcelWriter writer = new ExcelWriter("d:/aaa.xls", "表1");
//切换sheet,此时从第0行开始写
writer.setSheet("表2");
...
writer.setSheet("表3");
...
- 更详细的定义样式 在Excel中,由于样式对象个数有限制,因此Hutool根据样式种类分为4个样式对象,使相同类型的单元格可以共享样式对象。样式按照类别存在于StyleSet中,其中包括:
头部样式 headCellStyle
普通单元格样式 cellStyle
数字单元格样式 cellStyleForNumber
日期单元格样式 cellStyleForDate
其中cellStyleForNumber cellStyleForDate用于控制数字和日期的显示方式。
因此我们可以使用以下方式获取CellStyle对象自定义指定种类的样式:
StyleSet style = writer.getStyleSet();
CellStyle cellStyle = style.getHeadCellStyle();
...