huttoll

news2024/11/13 9:39:40

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。

Hutool是项目中“util”包友好的替代,它节省了开发人员对项目中公用类和公用工具方法的封装时间,使开发专注于业务,同时可以最大限度的避免封装不完善带来的bug。

模块    介绍
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封装


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[] b = { "1", "2", "3", "4" };
//结果为Integer数组
Integer[] intArray = Convert.toIntArray(b);

long[] c = {1,2,3,4,5};
//结果为Integer数组
Integer[] intArray2 = Convert.toIntArray(c);
日期转换 
String str = "2012-12-12";
// 以前这样将字符串转为日期
Date parse = new SimpleDateFormat("yyyy-MM-dd").parse(str);

// 现在这样将字符串转为日期
Date date = Convert.toDate(str);
System.out.println(date);
String str1 = "2012/12/12";
Date date1 = Convert.toDate(str1);
System.out.println(date1);
 集合转换
Object[] a = {"a", "你", "好", "", 1};
List<?> list = Convert.convert(List.class, a);
//从4.1.11开始可以这么用
List<?> lists = Convert.toList(a);

 编码转换

String a = "我不是乱码";
//转换后result为乱码
// 将utf-8编码转为ISO_8859_1编码
String result = Convert.convertCharset(a, CharsetUtil.UTF_8, CharsetUtil.ISO_8859_1);
// 将ISO_8859_1编码转为utf-8编码
String raw = Convert.convertCharset(result, CharsetUtil.ISO_8859_1, "UTF-8");
Assert.assertEquals(raw, a);

时间转换

long a = 4535345;

//结果为:75
// 将毫秒转为秒
long minutes = Convert.convertTime(a, TimeUnit.MILLISECONDS, TimeUnit.MINUTES);

 

 SpringUtil

 在SpringBoot上加注解

@EnableSpringUtil

 

1、模拟HTTP请求

hutool提供了「HttpUtil」 和 「HttpRequest」 两个工具类都可用来模拟发送http请求,这两个用法大同小异这里只拿「HttpRequest」举例 「示例场景:」 在项目开发中Swagger可作为后端接口测试的良方,但在和别人对接,或使用别人提供的接口时常常需要后端自己去模拟请求发送,去校验接口

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

/**
 * @author 遇见0和1
 * @company lingStudy
 * @create 2021-06-03 17:04
 */
@Slf4j
public class HttpTest {

    /**
     * putOnce:一次性Put 键值对,如果key已经存在抛出异常,如果键值中有null值,忽略
     * putOpt:在键和值都为非空的情况下put到JSONObject中
     */
    @Test
    void postTest(){
        JSONObject jsonObject = JSONUtil.createObj();// 或 JSONObject jsonObject = new JSONObject();
        jsonObject.putOnce("customerTel","17563964456");
        jsonObject.putOnce("remarks","备注1:我是HttpRequest测试请求!");

        HttpResponse response = HttpRequest.post("http://127.0.0.1:9001/caiyun-record/saveRecord")
                //设置请求头(可任意加)
                .header("Content-Type", "application/json")
                // 添加token
                .header("Authorization","eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJ7E3NjJ9.9vgMKLpftjcXxmvViSyJDnBcXrO6c3bLlatwD83frAs")
                //请求参数
                .body(jsonObject.toString())
                .execute();
        log.info("请求响应结果:{}",response);
        log.info("响应数据:{}",response.body());
    }

    @Test
    void getTest(){
        HttpResponse response = HttpRequest.get("http://127.0.0.1:9001/caiyun-record/login?paramData=I0CZZJYUBP9JixsyeDkhRnIfFgyXP-NaP1DiJ8_AWoY1eEeZN5BwF_HMSfb4wl6oE")
                .execute();
        log.info("get请求返回:{}",response.body());
    }

}

2、JSONUtil 序列化

将一个对象序列化,也是后端开发中常遇到的,阿里以前挺火的 「fastjson」 「示例场景:」 返回给前端的token中要存对象时可将对象转为字符串,在拦截器中再将该字符串重新转为对象,若在登录后存的是该对象到session中,还可以在拦截器中通过判断session中的值是否为空,来解决「后端重启后session丢失」的问题。

//对象转字符串
String userInfoStr = JSONUtil.toJsonStr(userInfoDTO);
log.info("对象转字符串userInfoStr:{}", userInfoStr);

//生成token
String jwtToken = TokenUtil.createJwtToken(userInfoStr);

//字符串转对象
UserInfoDTO userInfo = JSONUtil.toBean(jti, UserInfoDTO.class);
request.getSession().setAttribute("userInfo",userInfo);
log.info("重设session后:{}",request.getSession().getAttribute("userInfo"));

List< Map >转List< Entity >

// HuTool
List<User> userList = JSONUtil.toList(new JSONArray(userMapList),User.class);
// 同fastjson
List<User> userList = JSON.parseObject(JSON.toJSONString(userMapList),new TypeReference<>() {});

3、BeanUtil:Map与javaBean的转换

「示例场景:」 面对POST或者一些参数较多的GET请求等,懒得新建参数对象,可用Map来接收前端传递的参数

@ApiOperation(value = "新增记录")
@ApiImplicitParams({
         @ApiImplicitParam(paramType = "query", dataType = "String", name = "customerTel", value = "客户号码",required = true),
         @ApiImplicitParam(paramType = "query", dataType = "String", name = "remarks", value = "备注")
 })
 @PostMapping("/saveRecord")
 public ResultVo<Object> saveRecord(@ApiIgnore @RequestBody Map<String, Object> param){
     log.info("新增登记记录 param:{}",param);
     try {
         HecaiyunRecord hecaiyunRecord = new HecaiyunRecord();
         //将map赋值给HecaiyunRecord中与map的key对应的字段
         BeanUtil.fillBeanWithMap(param,hecaiyunRecord,false);
         UserInfoDTO userInfo = (UserInfoDTO) request.getSession().getAttribute("userInfo");
         //用userInfo填充与hecaiyunRecord相同的字段
         BeanUtils.copyProperties(userInfo,hecaiyunRecord);
         //添加系统日志
         sysLogService.saveSysLog(userInfo,request,"add","新增登记");

         return recordService.saveRecord(hecaiyunRecord);
     } catch (Exception e) {
         log.error("新增登记记录失败");
         e.printStackTrace();
         throw new MyException(StatusEnum.ERROR);
     }
 }

「反过来:将 JavaBean 转为 Map」

User user = new User();
user.setAge(3);
user.setName("遇见0和1");
 
 //将 user 转成map
Map<String, Object> map = BeanUtil.beanToMap(user);

//将userInfo对象复制给map,key保留userInfo中属性的驼峰形式不做下划线处理,不忽略userInfo中值为null的属性
BeanUtil.beanToMap(userInfo,map,false,false); //不会清空map (个人常用)

4、CaptchaUtil 生成图形验证码

「示例场景:」 图形验证码在登录时非常常见,Hutool也用几种类型的验证码,这里只举例个人常用的一种。

@ApiOperation(value = "获得图形验证码")
@GetMapping("/getCaptcha")
public void getCaptcha(HttpServletResponse response){
    //生成验证码图片(定义图形的宽和高,验证码的位数,干扰线的条数)
    //CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 25);
    CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(100, 50, 4, 25);
    //告诉浏览器输出内容为jpeg类型的图片
    response.setContentType("image/jpeg");
    //禁止浏览器缓存
    response.setHeader("Pragma","No-cache");
    try {
        ServletOutputStream outputStream = response.getOutputStream();
        //图形验证码写出到流,也可以写出到文件如:circleCaptcha.write(“d:/circle25.jpeg”);
        circleCaptcha.write(outputStream);
        //从图形验证码图片中获取它的字符串验证码(获取字符串验证码要在图形验证码wirte写出后面才行,不然得到的值为null)
        String captcha = circleCaptcha.getCode();
        request.getSession().setAttribute("captcha",captcha);
        log.info("生成的验证码:{}",captcha);
        log.info("session id:{}",request.getSession().getId());
        //关闭流
        outputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
        throw new MyException(StatusEnum.ERROR);
    }
}

5、UserAgentUtil

「示例场景:」 系统操作日志里常常需要判断访问的是什么设备 「UserAgentUtil」 可以获取到服务的浏览器详细信息,也可以判断访问是不是移动设备。

//自己实现
public String isDevice(HttpServletRequest request){
    String requestHeader = request.getHeader("user-agent");
    //定义移动端请求的所有可能类型
    String[] deviceArray = {"android", "iphone","ipod","ipad", "windows phone","mqqbrowser"};
    //将字符串转换为小写
    requestHeader = requestHeader.toLowerCase();
    for (String device : deviceArray) {
        if (requestHeader.contains(device)){
            return "移动端";
        }
    }
    return "PC端";
}

//使用UserAgentUtil
public String isDeviceHuTool(HttpServletRequest request){
    String requestHeader = request.getHeader("user-agent");
    UserAgent userAgent = UserAgentUtil.parse(requestHeader);
    if (userAgent.isMobile()){
        return "移动端";
    }
    return "PC端";
}

访问者的ip地址常常也是需要保存的一个数据,个人暂时没找到hutool对这个的支持,方便后面来抄作业,下面放一个搬来的获取ip的方法

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;

/**
 * @author 遇见0和1
 * @company lingStudy
 * @create 2021-03-30 9:31
 */
@Slf4j
public class IPUtils {

    /**
     * 获取IP地址
     *
     * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
     * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = null;
        try {
            ip = request.getHeader("x-forwarded-for");
            if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (StrUtil.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } catch (Exception e) {
            log.error("IPUtils ERROR:",e);
        }

        //对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
        if(!StrUtil.isEmpty(ip) && ip.length() > 15) {
   if(ip.indexOf(",") > 0) {
    ip = ip.substring(0, ip.indexOf(","));
   }
  }

        return ip;
    }

}

6、FileUtil

「示例场景:」 文件上传下载在项目中也是一个常见并且重要的业务点,Hutool的「FileUtil」类对着方面也做了很好的支持。

@Value("${upload-file.img-path}")
private String imgPath;

@ApiOperation(value = "上传图片")
@PostMapping(value = "/uploadImg",headers = "content-type=multipart/form-data")
public ResultVo<Object> uploadFile(@ApiParam(value = "file") @RequestParam(value = "file" ,required = false) MultipartFile file){

    if (file == null){
        throw new MyException(StatusEnum.BUSINID);
    }
    if (!FileUtil.exist(imgPath)){
        FileUtil.mkdir(imgPath);
    }
    //String fileName = UUID.randomUUID().toString() + "@" + multipartFile.getOriginalFilename();
    log.info("原文件名:{}",file.getOriginalFilename());//包括扩展名
    //文件扩展名
    String suffix = Objects.requireNonNull(file.getOriginalFilename()).substring(file.getOriginalFilename().lastIndexOf(".") + 1);
    String fileName = System.currentTimeMillis() + RandomUtil.randomNumbers(4) + "." +suffix;
    try {
        File file1 = FileUtil.writeBytes(file.getBytes(), imgPath + fileName);
        log.info("file1:{}",file1);
        return ResultVo.success();
    } catch (IOException e) {
        e.printStackTrace();
        throw new MyException(StatusEnum.ERROR);
    }

}

加密解密

加密分为三种:

  • 「对称加密(symmetric)」:例如:AES、DES等
  • 「非对称加密(asymmetric)」:例如:RSA、DSA等
  • 「摘要加密(digest)」:例如:MD5、SHA-1、SHA-256、HMAC等

对常用到的算法,HuTool提供「SecureUtil」工具类用于快速实现加解密

// 对称加密
SecureUtil.aes
SecureUtil.des
// 摘要算法
SecureUtil.md5
SecureUtil.sha1
SecureUtil.hmac
SecureUtil.hmacMd5
SecureUtil.hmacSha1
// 非对称加密
SecureUtil.rsa
SecureUtil.dsa
// UUID
SecureUtil.simpleUUID 方法提供无“-”的UUID
// 密钥生成
SecureUtil.generateKey 针对对称加密生成密钥
SecureUtil.generateKeyPair 生成密钥对(用于非对称加密)
SecureUtil.generateSignature 生成签名(用于非对称加密)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/888651.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【NepCTF2023】复现

文章目录 【NepCTF2023】复现MISC与AI共舞的哈夫曼codesc语言获取环境变量 小叮弹钢琴陌生的语言你也喜欢三月七么Ez_BASIC_IImisc参考 WEBez_java_checkinPost Crad For You独步天下配置环境独步天下-镜花水月环境变量提权 独步天下-破除虚妄总结 独步天下-破除试炼_加冕成王知…

Android岗位技能实训室建设方案

一 、系统概述 Android岗位技能作为新一代信息技术的重点和促进信息消费的核心产业&#xff0c;已成为我国转变信息服务业的发展新热点&#xff1a;成为信息通信领域发展最快、市场潜力最大的业务领域。互联网尤其是移动互联网&#xff0c;以其巨大的信息交换能力和快速渗透能力…

三种MMIC放大器偏置电压顺序

HBT自偏置放大器偏置顺序 1、有两种HBT放大器&#xff0c;自偏置和带电流控制的自偏置&#xff0c;下图是HBT自偏置放大器最简单的偏置。这些放大器只需要接通集电极电压。有一个设置电流的偏置电阻。放大器有一个电流反射镜来控制基极电压。 2、 电阻值的计算 3、打开电源并…

代码审计-java项目-组件漏洞审计

代码审计必备知识点&#xff1a; 1、代码审计开始前准备&#xff1a; 环境搭建使用&#xff0c;工具插件安装使用&#xff0c;掌握各种漏洞原理及利用,代码开发类知识点。 2、代码审计前信息收集&#xff1a; 审计目标的程序名&#xff0c;版本&#xff0c;当前环境(系统,中间件…

QT-Mysql数据库图形化接口

QT sql mysqloper.h qsqlrelationaltablemodelview.h /************************************************************************* 接口描述&#xff1a;Mysql数据库图形化接口 拟制&#xff1a; 接口版本&#xff1a;V1.0 时间&#xff1a;20230727 说明&#xff1a;支…

ipadOS External cameras

必须是USB-C接口&#xff0c;所以在使用的时候需要确认USB video Class(UVC) 好像也可以使用HDMI AVFoundation 用于处理一批视频多媒体数据的创建&#xff0c;编辑&#xff0c;播放和捕获&#xff0c;时音频视频功能的基础库。 有什么功能呢&#xff1a; 1.可以支持多种音频…

RocketMQ(模式详解,安装)及控制台安装

下载 环境 64位操作系统&#xff0c;推荐 Linux/Unix/macOS 64位 JDK 1.8下载地址 https://rocketmq.apache.org/zh/download/ RocketMQ 的安装包分为两种&#xff0c;二进制包和源码包。 二进制包是已经编译完成后可以直接运行的&#xff0c;源码包是需要编译后运行的。 单…

【Android】解决Lint found fatal errors while assembling a release target

报错信息&#xff1a; Android在debug模式下打包没有问题&#xff0c;但是在打包release版本时出现一下问题&#xff1a; 结果图 原因 我项目的原因是因为把正式、测试地址放到代码里了&#xff0c;忘记选中正式环境的地址&#xff0c;导致打正式包有问题&#xff1b;大家如果…

ASEMI肖特基模块MBR400100CT参数规格

编辑-Z MBR400100CT参数描述&#xff1a; 型号&#xff1a;MBR400100CT 反向重复峰值电压(VRRM)&#xff1a;100V 正向直流电流(I0)&#xff1a;400A 正向&#xff08;不重复&#xff09;浪涌电流(IFSM)&#xff1a;3300A 结温 (TJ)&#xff1a;-40 to 175℃ 储存温度(T…

mybatis生命周期和作用域

前言 作用域和生命周期错误使用会导致并发问题。 mybatis执行过程&#xff1a; 1、SqlSessionFactoryBuilder SqlSessionFactoryBuilder 占用XML资源来创建多个 SqlSessionFactory实例&#xff1b; SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域&#xff08;也就…

MBSE项目的全新数据、信息与知识管理方法|数据模型标准化思路

仅供学习使用 An original Data, Information and Knowledge management approach for model-based engineering projects 作者&#xff1a;M. El Alaoui, S. Rabah, V. Chapurlat, V. Richet , R. Plana 来源&#xff1a;https://doi.org/10.1016/j.ifacol.2022.10.135 文章详…

强化学习A3C算法

强化学习A3C算法 效果&#xff1a; a3c.py import matplotlib from matplotlib import pyplot as plt matplotlib.rcParams[font.size] 18 matplotlib.rcParams[figure.titlesize] 18 matplotlib.rcParams[figure.figsize] [9, 7] matplotlib.rcParams[font.family]…

谓语动词(动词不定式(短语)、动名词、分词(短语))作定语

动词不定式(短语)作定语 动名词作定语 分词&#xff08;短语&#xff09;作定语 着重记忆及物动词

剑指offer-2.2字符串

字符串 C/C中每个字符串都以字符"\0"作为结尾&#xff0c;这样我们就能很方便地找到字符串的最后尾部。但由于这个特点&#xff0c;每个字符串中都有一个额外字符的开销&#xff0c;稍不留神就会造成字符串的越界。比如下面的代码&#xff1a; char str [10]; strc…

UWB现场安装通常涉及以下步骤

UWB现场安装通常涉及以下步骤&#xff1a; 1.确定区域需求&#xff1a;首先&#xff0c;确定需要进行UWB定位的区域和目标。这可能是一个室内环境、仓库、工厂或其他特定的工作场所。 2.设计系统布局&#xff1a;根据区域的特点和目标定位需求&#xff0c;设计系统的布局和基…

关于Firmae缺失binwalk模块

问题 david707:~/FirmAE$ sudo ./run.sh -c weyow ./WAM_9900-20.06.03V.trx [*] ./WAM_9900-20.06.03V.trx emulation start!!! Traceback (most recent call last):File "./sources/extractor/extractor.py", line 19, in <module>import binwalk ModuleNot…

红帽8.2版本CSA题库:第十题配置用户帐户

红帽8.2版本CSA题库&#xff1a;第十题配置用户帐户 useradd -u 3533 manalo #传创建用户指定uid为3533 echo flectrag | passwd --stdin manalo #设置密码 tail -1 /etc/passwd #查看

globals()与locals()函数

在Python中&#xff0c;globals()和locals()是两个内置函数&#xff0c;用于获取当前作用域内的全局和局部命名空间中的变量和对象。 一、globals() :这个函数返回一个包含当前全局作用域中所有变量和对象的字典。在函数内部调用globals()将返回全局命名空间中的变量&#xf…

密码湘军,融合创新!麒麟信安参展2023商用密码大会,铸牢数据安全坚固堡垒

2023年8月9日至11日&#xff0c;商用密码大会在郑州国际会展中心正式开幕。本次大会由国家密码管理局指导&#xff0c;中国密码学会支持&#xff0c;郑州市人民政府、河南省密码管理局主办&#xff0c;以“密码赋能美好发展”为主题&#xff0c;旨在推进商用密码创新驱动、前沿…

2023年第四届全国人工智能大赛初赛晋级复赛名单公示

由深圳市科技创新委员会、鹏城实验室共同主办&#xff0c;新一代人工智能产业技术创新战略联盟&#xff08;AITISA&#xff09;承办&#xff0c;华为技术有限公司、中国工商银行股份有限公司深圳市分行、中国农业银行股份有限公司深圳市分行、中国建设银行股份有限公司深圳市分…