個人公衆号(小程式同名): 遇見0和1
Hexo部落格: http://vogos.cn
文章目錄
-
- 前言
- 1、模拟HTTP請求
- 2、JSONUtil 序列化
- 3、BeanUtil Map與javaBean的轉換
- 4、CaptchaUtil 生成圖形驗證碼
- 5、UserAgentUtil
- 6、FileUtil
- 7、搬磚中...
前言
官方介紹: Hutool是一個Java工具包,也隻是一個工具包,它幫助我們簡化每一行代碼,減少每一個方法,讓Java語言也可以“甜甜的”。Hutool最初是我項目中“util”包的一個整理,後來慢慢積累并加入更多非業務相關功能,并廣泛學習其它開源項目精髓,經過自己整理修改,最終形成豐富的開源工具集。Hutool是Hu + tool的自造詞,前者緻敬我的“前任公司”,後者為工具之意,諧音“糊塗”,寓意追求“萬事都作糊塗觀,無所謂失,無所謂得”的境界。
個人看法: 網上對它的看法有好有壞,搜尋hutool就能看到如下他的生态,那些不推薦的原因我就不在這介紹了(畢竟本人是一個菜🐔,沒有這種資格)對于我目前的個人能力來說,它還是非常适合我的,開發時懶得自己寫一些工具類或算法加密什麼的,hutool也可以幫我減少 util 包中的大量工具類,這裡隻記錄個人常用到的一些工具類,它的浩瀚可自行去官方開拓,目前記錄時官方最新版本為v5.6.6
Hutool官網:https://www.hutool.cn
官方文檔:https://apidoc.gitee.com/dromara/hutool
添加Hutool的所有依賴
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.3</version>
</dependency>
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"));
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");
Map<String, Object> map = BeanUtil.beanToMap(user);
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);
}
}