本文主要是介绍工具篇之Hutool,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、概述
1.1介绍
Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。
Hutool中的工具方法来自于每个用户的精雕细琢,它涵盖了Java开发底层代码中的方方面面,它既是大型项目开发中解决小问题的利器,也是小型项目中的效率担当;
Hutool是项目中“util”包友好的替代,它节省了开发人员对项目中公用类和公用工具方法的封装时间,使开发专注于业务,同时可以最大限度的避免封装不完善带来的bug。
1.2Hutool名称的由来
Hutool = Hu + tool,是原公司项目底层代码剥离后的开源库,“Hu”是公司名称的表示,tool表示工具。Hutool谐音“糊涂”,一方面简洁易懂,一方面寓意“难得糊
Hutool的目标是使用一个工具方法代替一段复杂代码,从而最大限度的避免“复制粘贴”代码的问题,彻底改变我们写代码的方式。
以计算MD5为例:
- 【以前】打开搜索引擎 -> 搜“Java MD5加密” -> 打开某篇博客-> 复制粘贴 -> 改改好用
- 【现在】引入Hutool -> SecureUtil.md5()
Hutool的存在就是为了减少代码搜索成本,避免网络上参差不齐的代码出现导致的bug。
1.3包含组件(核心)
一个Java基础工具类,对文件、流、加密解密、转码、正则、线程、XML等JDK方法进行封装,组成各种Util工具类,同时提供以下组件:
模块 | 介绍 |
---|---|
hutool-aop | JDK动态代理封装,提供非IOC下的切面支持 |
hutool-bloomFilter | 布隆过滤,提供一些Hash算法的布隆过滤 |
hutool-cache | 简单缓存实现 |
hutool-core | 核心,包括Bean操作、日期、各种Util等 |
hutool-cron | 定时任务模块,提供类Crontab表达式的定时任务 |
hutool-crypto | 加密解密模块,提供对称、非对称和摘要算法封装 |
hutool-db | JDBC封装后的数据操作,基于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-json | JSON实现 |
hutool-captcha | 图片验证码实现 |
hutool-poi | 针对POI中Excel和Word的封装 |
hutool-socket | 基于Java的NIO和AIO的Socket封装 |
hutool-jwt | JSON Web Token (JWT)封装实现 |
1.4官方文档
官网:Hutool — 🍬A set of tools that keep Java sweet.
参考文档:简介 | Hutool
API文档:Document
1.5导入HuTool
HuTool使用非常简单直接在项目中引入如下依赖即可:
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.3.7</version>
</dependency>
二、常用工具类
2.1Convert
问题
在Java开发中我们要面对各种各样的类型转换问题,尤其是从命令行获取的用户参数、从HttpRequest获取的Parameter等等,这些参数类型多种多样,我们怎么去转换他们呢?常用的办法是先整成String,然后调用XXX.parseXXX方法,还要承受转换失败的风险,不得不加一层try catch,这个小小的过程混迹在业务代码中会显得非常难看和臃肿。
类型转换工具类,用于各种类型数据的转换。
Convert类可以说是一个工具方法类,里面封装了针对Java常见类型的转换,用于简化类型转换。**Convert**类中大部分方法为toXXX,参数为Object,可以实现将任意可能的类型转换为指定类型。同时支持第二个参数defaultValue用于在转换失败时返回一个默认值。
package com.yanyu.redisjedistest.demo;import cn.hutool.core.convert.Convert;
import lombok.extern.slf4j.Slf4j;import java.util.Date;
import java.util.List;@Slf4j
public class hutool1 {public void covert() {//转换为字符串int a = 1;String aStr = Convert.toStr(a);log.info(aStr);//转换为指定类型数组String[] b = {"1", "2", "3", "4"};Integer[] bArr = Convert.toIntArray(b);log.info(bArr.toString());//转换为日期对象String dateStr = "2020-09-17";Date date = Convert.toDate(dateStr);log.info(date.toString());//转换为列表String[] strArr = {"a", "b", "c", "d"};List<String> strList = Convert.toList(String.class, strArr);log.info(strList.toString());}public static void main(String[] args) {hutool1 hutool1 = new hutool1();hutool1.covert();}
}
2.2DateUtil
日期时间工具类,定义了一些常用的日期时间操作方法。
public void dateUtil() {//Date、long、Calendar之间的相互转换//当前时间Date date = DateUtil.date();log.info(date.toString());//Calendar转Datedate = DateUtil.date(Calendar.getInstance());//时间戳转Datedate = DateUtil.date(System.currentTimeMillis());//自动识别格式转换String dateStr = "2020-09-17";date = DateUtil.parse(dateStr);//自定义格式化转换date = DateUtil.parse(dateStr, "yyyy-MM-dd");//格式化输出日期String format = DateUtil.format(date, "yyyy-MM-dd");log.info(format.toString());//获得年的部分int year = DateUtil.year(date);//获得月份,从0开始计数int month = DateUtil.month(date);//获取某天的开始、结束时间Date beginOfDay = DateUtil.beginOfDay(date);Date endOfDay = DateUtil.endOfDay(date);//计算偏移后的日期时间Date newDate = DateUtil.offset(date, DateField.DAY_OF_MONTH, 2);//计算日期时间之间的偏移量long betweenDay = DateUtil.between(date, newDate, DateUnit.DAY);}
2.3ReflectUtil
Java反射工具类,可用于反射获取类的方法及创建对象。
public void reflectUtil() {//获取某个类的所有方法Method[] methods = ReflectUtil.getMethods(Dog.class);//获取某个类的指定方法Method method = ReflectUtil.getMethod(Dog.class, "getName");//使用反射来创建对象Dog dog = ReflectUtil.newInstance(Dog.class);//反射执行对象的方法ReflectUtil.invoke(dog, "setName","大黄");log.info(dog.getName());
}
Dog
Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Dog {private String name;private Float weight;
}
2.4NumberUtil
public void numberUtil() {double n1 = 1.234;double n2 = 1.234;double result;//对float、double、BigDecimal做加减乘除操作result = NumberUtil.add(n1, n2);log.info(String.valueOf(result));result = NumberUtil.sub(n1, n2);log.info(String.valueOf(result));result = NumberUtil.mul(n1, n2);log.info(String.valueOf(result));result = NumberUtil.div(n1, n2);log.info(String.valueOf(result));//保留两位小数BigDecimal roundNum = NumberUtil.round(n1, 2);log.info(roundNum.toString());String n3 = "1.234";//判断是否为数字、整数、浮点数NumberUtil.isNumber(n3);NumberUtil.isInteger(n3);NumberUtil.isDouble(n3);}
2.5CollUtil
集合操作的工具类,定义了一些常用的集合操作。
public void collUtil() {//数组转换为列表String[] array = new String[]{"a", "b", "c", "d", "e"};List<String> list = CollUtil.newArrayList(array);//join:数组转字符串时添加连接符号String joinStr = CollUtil.join(list, ",");log.info("collUtil join:{}", joinStr);//将以连接符号分隔的字符串再转换为列表List<String> splitList = StrUtil.split(joinStr, ',');log.info("collUtil split:{}", splitList);//创建新的Map、Set、ListHashMap<Object, Object> newMap = CollUtil.newHashMap();HashSet<Object> newHashSet = CollUtil.newHashSet();ArrayList<Object> newList = CollUtil.newArrayList();//判断列表是否为空CollUtil.isEmpty(list);CollUtil.isNotEmpty(list);}
2.6SecureUtil
public void secureUtil() {// 加密String str = "123456";String key = "secretKey";byte[] keyBytes = Arrays.copyOf(key.getBytes(), 16);String encryptedStr = SecureUtil.aes(keyBytes).encryptBase64(str);log.info("Encrypted string: {}", encryptedStr);// 解密String decryptedStr = SecureUtil.aes(keyBytes).decryptStr(encryptedStr);log.info("Decrypted string: {}", decryptedStr);}
2.7JSONUtil
JSON 解析工具类,针对 JSONObject 和 JSONArray 的静态快捷方法集合。
public void jsonUtil() {Dog dog = new Dog();dog.setName("大黄");dog.setWeight(5.14f);//对象转化为JSON字符串String jsonStr = JSONUtil.parse(dog).toString();log.info("jsonUtil parse:{}", jsonStr);//JSON字符串转化为对象Dog dogBean = JSONUtil.toBean(jsonStr, Dog.class);log.info("jsonUtil toBean:{}", dogBean);List<Dog> dogList = new ArrayList<>();dogList.add(dog);String jsonListStr = JSONUtil.parse(dogList).toString();//JSON字符串转化为列表dogList = JSONUtil.toList(new JSONArray(jsonListStr), Dog.class);log.info("jsonUtil toList:{}", dogList);
}
2.8RandomUtil
随机工具类,RandomUtil 主要针对 JDK 中 Random 对象做封装。
@Test(description = "RandomUtil使用:随机工具类")
public void randomUtil() {int result;String uuid;//获得指定范围内的随机数result = RandomUtil.randomInt(1, 100);log.info("randomInt:{}",StrUtil.toString(result));//获得随机UUIDuuid = RandomUtil.randomUUID();log.info("randomUUID:{}", uuid);
}
三、实战exexcel开发
数据库
create table cf_group_user
(id int unsigned auto_increment comment 'id'primary key,group_id int unsigned not null comment '组织id',nickname char(30) not null comment '姓名',sex tinyint unsigned not null comment '性别(1:男,2:女)',born_time datetime not null comment '出生日期',photo varchar(255) not null comment '形象照片',home_address varchar(255) not null comment '家庭地址',mobile int not null comment '联系电话',post varchar(255) not null comment '职务信息'
)comment '组织用户信息表' collate = utf8_unicode_ci;create index auth_idon cf_group_user (auth_id);create index group_idon cf_group_user (group_id);create index mobileon cf_group_user (mobile);
实体类
/*** 组织用户信息表* @TableName cf_group_user*/
@TableName(value ="cf_group_user")
@Data
public class GroupUser implements Serializable {/*** id*/@TableId(type = IdType.AUTO)private Integer id;/*** 组织id*/private Integer groupId;/*** 姓名*/@NotBlank(message = "姓名不可为空")private String nickname;/*** 性别(0:默认,1:男,2:女)*/@NotBlank(message = "性别不可为空")private Integer sex;/*** 出生日期*/@NotBlank(message = "出生日期不可为空")private Date bornTime;/*** 形象照片*/@NotBlank(message = "形象照片不可为空")private String photo;/*** 家庭地址*/@NotBlank(message = "家庭地址不可为空")private String homeAddress;/*** 联系电话*/@NotBlank(message = "联系电话不可为空")private Integer mobile;/*** 实名信息*/private String authId;/*** 职务信息*/@NotNull(message = "职务不可为空")private String post;
}
在工程中先确定使用的字段构建模板,根据字段构建excel 的模板。这里的示例如下:
//controller层
//返回模板@RequestMapping("/getExcelTemplate")public void getExcelTemplate(HttpServletResponse response) {groupUserService.getExcelTemplate(response);}//sevice层
void getExcelTemplate(HttpServletResponse response);//impl
@Overridepublic void getExcelTemplate(HttpServletResponse response) {try {// 1 读取对象final ExcelReader reader = ExcelUtil.getReader(ResourceUtil.getStream("templates/group.xlsx"));List<List<Object>> lists = reader.read();ExcelWriter writer = ExcelUtil.getWriter(true);writer.write(lists);response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("group.xlsx", "UTF-8"));response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");// 2 写出对象ServletOutputStream outputStream = response.getOutputStream();// 通过IO写出我们的表格对象writer.flush(outputStream, true);writer.close();IoUtil.close(outputStream);} catch (IOException e) {log.error("EducationServiceImpl [export] 输出到响应流失败", e);throw new APIException("导出Excel异常");}}
这里我使用的是三层构建,在controller 层中暴露接口,进行调用,所有的具体实现进行抽象。
//导入信息@RequestMapping("/importStudent")public R importStudent(@RequestParam MultipartFile file) {try {boolean userInfo = groupUserService.getUserInfo(file);if(userInfo) return R.success();} catch (IOException e) {log.error("EducationController [getEducation] 获取输入流失败", e);throw new APIException("获取输入流失败");}return R.error();}//导出信息@RequestMapping("/export")public void export(@RequestBody PageVo pageVo, HttpServletResponse response) {groupUserService.export(pageVo, response);}
void export(PageVo pageVo, HttpServletResponse response);boolean getUserInfo(MultipartFile file) throws IOException;@Overridepublic void export(PageVo pageVo, HttpServletResponse response) {// 从数据库查出数据对象封装成mapfinal List<Map<String, Object>> educationList = this.page(new Page<>(pageVo.getPage(), pageVo.getLimit()), Wrappers.lambdaQuery()).getRecords().stream()// 封装成 Map 并且放入 List.map(item -> {final Map<String, Object> map = new LinkedHashMap<>();// 错误,这里需要根据表中字段名称进行命名map.put("nickname", item.getNickname());map.put("sex", item.getSex());map.put("mobile", item.getMobile());map.put("bornTime", item.getBornTime());map.put("homeAddress", item.getHomeAddress());map.put("post", item.getPost());return map;}).collect(Collectors.toList());// 准备将数据集合封装成Excel对象ExcelWriter writer = ExcelUtil.getWriter(true);// 通过工具类创建writer并且进行别名writer.addHeaderAlias("nickname", "姓名");writer.addHeaderAlias("sex", "性别( 0 表示男 , 1 表示 女)");writer.addHeaderAlias("mobile", "电话");writer.addHeaderAlias("bornTime", "出生日期");writer.addHeaderAlias("homeAddress", "家庭地址");writer.addHeaderAlias("post", "职位");// 准备将对象写入我们的 Listwriter.write(educationList, true);try {// 获取我们的输出流final OutputStream output = response.getOutputStream();response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("group.xlsx", "UTF-8"));response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");writer.flush(output, true);writer.close();// 这里可以自行关闭资源或者写一个关闭资源的工具类IoUtil.close(output);} catch (IOException e) {log.error("EducationServiceImpl [export] 输出到响应流失败", e);throw new APIException("导出Excel异常");}}@Overridepublic boolean getUserInfo(MultipartFile file) throws IOException {ExcelReader reader = ExcelUtil.getReader(file.getInputStream());HashMap<String, String> head = new HashMap<>(6);head.put("姓名","nickname");head.put("性别( 0 表示男 , 1 表示 女)","sex");head.put("电话","mobile");head.put("出生日期", "bornTime");head.put("家庭地址","homeAddress");head.put("职位","post");reader.setHeaderAlias(head);List<GroupUser> read = reader.read(0, 1, GroupUser.class);Group group = groupService.getOne(new QueryWrapper<Group>().eq("uid", UserConstant.USER_ID));for (GroupUser user : read) {user.setGroupId(group.getId());//TODO 默认图片user.setPhoto("https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png");user.setStatus(1);user.setCreateTime(new DateTime());if(!this.save(user))return false;}return true;}
这篇关于工具篇之Hutool的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!