Java項(xiàng)目中如何引入Hutool工具類并正確使用它
1. 項(xiàng)目中如何引入 Hutool
1.1. import 方式引入 Hutool
如果你想像Spring-Boot一樣引入Hutool,再由子模塊決定用到哪些模塊,你可以在父模塊中加入:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-bom</artifactId>
<version>${hutool.version}</version>
<type>pom</type>
<!-- 注意這里是import -->
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在子模塊中就可以引入自己需要的模塊了:
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
</dependency>
</dependencies>
使用 import 的方式,只會(huì)引入hutool-bom內(nèi)的dependencyManagement的配置,其它配置在這個(gè)引用方式下完全不起作用。
1.2. exclude 方式引入 Hutool
如果你引入的模塊比較多,但是某幾個(gè)模塊沒用,你可以:
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-bom</artifactId>
<version>${hutool.version}</version>
<!-- 加不加這句都能跑,區(qū)別只有是否告警 -->
<type>pom</type>
<exclusions>
<exclusion>
<groupId>cn.hutool</groupId>
<artifactId>hutool-system</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
這個(gè)配置會(huì)傳遞依賴hutool-bom內(nèi)所有dependencies的內(nèi)容,當(dāng)前hutool-bom內(nèi)的dependencies全部設(shè)置了version,就意味著在maven resolve的時(shí)候hutool-bom內(nèi)就算存在dependencyManagement也不會(huì)產(chǎn)生任何作用。
2. 以 SpringBoot 項(xiàng)目為例如何使用它
在Spring Boot項(xiàng)目中使用Hutool,您可以按照以下步驟進(jìn)行操作:
- 添加Hutool依賴:在您的項(xiàng)目的構(gòu)建文件(如pom.xml)中添加Hutool的依賴項(xiàng)。您可以在Maven中添加以下依賴:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.6</version>
</dependency>
- 在Spring Boot應(yīng)用程序中使用Hutool:在您的Spring Boot應(yīng)用程序中,您可以直接使用Hutool提供的工具類和方法。例如,在您的Controller類中,您可以使用Hutool的字符串工具類:
import cn.hutool.core.util.StrUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@GetMapping("/hello")
public String hello() {
String str = "Hello, Hutool!";
String reversedStr = StrUtil.reverse(str);
return reversedStr;
}
}
- 運(yùn)行應(yīng)用程序:?jiǎn)?dòng)您的Spring Boot應(yīng)用程序,并訪問
/hello端點(diǎn),您將看到使用Hutool進(jìn)行字符串翻轉(zhuǎn)后的結(jié)果。
3. Hutool 的編譯安裝
如果想對(duì) Hutool 的源碼進(jìn)行編譯安裝,可以訪問Hutool的Gitee主頁(yè):https://gitee.com/dromara/hutool (opens new window)下載整個(gè)項(xiàng)目源碼(v5-master或v5-dev分支都可)然后進(jìn)入Hutool項(xiàng)目目錄執(zhí)行:
./hutool.sh install
然后就可以使用Maven引入了。
4. Hutool 的源碼分支說明
Hutool的源碼分為兩個(gè)分支,功能如下:
| 分支 | 作用 |
|---|---|
| v5-master | 主分支,release版本使用的分支,與中央庫(kù)提交的jar一致,不接收任何pr或修改 |
| v5-dev | 開發(fā)分支,默認(rèn)為下個(gè)版本的SNAPSHOT版本,接受修改或pr |
5. 給 Hutool 提供bug反饋或建議
提交問題反饋請(qǐng)說明正在使用的JDK版本呢、Hutool版本和相關(guān)依賴庫(kù)版本。
6. 給 Hutool 貢獻(xiàn)代碼的步驟
- 在Gitee或者Github上fork項(xiàng)目到自己的repo
- 把fork過去的項(xiàng)目也就是你的項(xiàng)目clone到你的本地
- 修改代碼(記得一定要修改v5-dev分支)
- commit后push到自己的庫(kù)(v5-dev分支)
- 登錄Gitee或Github在你首頁(yè)可以看到一個(gè) pull request 按鈕,點(diǎn)擊它,填寫一些說明信息,然后提交即可。
- 等待維護(hù)者合并
7. PR遵照的原則
Hutool歡迎任何人為Hutool添磚加瓦,貢獻(xiàn)代碼,不過維護(hù)者是一個(gè)強(qiáng)迫癥患者,為了照顧病人,需要提交的pr(pull request)符合一些規(guī)范,規(guī)范如下:
- 注釋完備,尤其每個(gè)新增的方法應(yīng)按照J(rèn)ava文檔規(guī)范標(biāo)明方法說明、參數(shù)說明、返回值說明等信息,必要時(shí)請(qǐng)?zhí)砑訂卧獪y(cè)試,如果愿意,也可以加上你的大名。
- Hutool的縮進(jìn)按照Eclipse(不要跟我說IDEA多好用,維護(hù)者非常懶,學(xué)不會(huì) ,IDEA真香,改了Eclipse快捷鍵后舒服多了)默認(rèn)(tab)縮進(jìn),所以請(qǐng)遵守(不要和我爭(zhēng)執(zhí)空格與tab的問題,這是一個(gè)病人的習(xí)慣)。
- 新加的方法不要使用第三方庫(kù)的方法,Hutool遵循無依賴原則(除非在extra模塊中加方法工具)。
- 請(qǐng)pull request到v5-dev分支。Hutool在5.x版本后使用了新的分支:v5-master是主分支,表示已經(jīng)發(fā)布中央庫(kù)的版本,這個(gè)分支不允許pr,也不允許修改。
- 我們?nèi)绻P(guān)閉了你的issue或pr,請(qǐng)不要詫異,這是我們保持問題處理整潔的一種方式,你依舊可以繼續(xù)討論,當(dāng)有討論結(jié)果時(shí)我們會(huì)重新打開。
補(bǔ)充:基于Hutool的excel開發(fā)
引入依賴
excel 包完全依賴于hutool 工具包,不需要額外的引入,hutool all中已經(jīng)包含了hutool 的全部工具包
<!-- hutool工具類 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.22</version>
</dependency>
開發(fā)
首先確定我們要對(duì)那些表進(jìn)行數(shù)據(jù)的導(dǎo)入導(dǎo)出,這里的建議是對(duì)數(shù)據(jù)更改不頻繁的表進(jìn)行數(shù)據(jù)的導(dǎo)入導(dǎo)出,而且對(duì)于數(shù)據(jù)的唯一性要求不高,否則在進(jìn)行數(shù)據(jù)導(dǎo)入的過程中,需要進(jìn)行復(fù)雜的邏輯處理。這里我使用的是組織的用戶信息表,該表的數(shù)據(jù)只有組織自己進(jìn)行維護(hù),就可以使用標(biāo)準(zhǔn)導(dǎo)入。
/**
* 組織用戶信息表
* @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:默認(rèn),1:男,2:女)
*/
@NotBlank(message = "性別不可為空")
private Integer sex;
/**
* 出生日期
*/
@NotBlank(message = "出生日期不可為空")
private Date bornTime;
/**
* 形象照片
*/
@NotBlank(message = "形象照片不可為空")
private String photo;
/**
* 家庭地址
*/
@NotBlank(message = "家庭地址不可為空")
private String homeAddress;
/**
* 聯(lián)系電話
*/
@NotBlank(message = "聯(lián)系電話不可為空")
private Integer mobile;
/**
* 實(shí)名信息
*/
private String authId;
/**
* 職務(wù)信息
*/
@NotNull(message = "職務(wù)不可為空")
private String post;
}
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 '聯(lián)系電話',
post varchar(255) not null comment '職務(wù)信息'
)
comment '組織用戶信息表' collate = utf8_unicode_ci;
create index auth_id
on cf_group_user (auth_id);
create index group_id
on cf_group_user (group_id);
create index mobile
on cf_group_user (mobile);
在確定表后,我們需要選取那些字段是我們需要使用的,在excel 表中進(jìn)行展示,需要用戶填入,根據(jù)字段構(gòu)建反射。
實(shí)現(xiàn)
在工程中先確定使用的字段構(gòu)建模板,根據(jù)字段構(gòu)建excel 的模板。這里的示例如下:
//controller層
//返回模板
@RequestMapping("/getExcelTemplate")
public void getExcelTemplate(HttpServletResponse response) {
groupUserService.getExcelTemplate(response);
}
//sevice層
void getExcelTemplate(HttpServletResponse response);
//impl
@Override
public void getExcelTemplate(HttpServletResponse response) {
try {
// 1 讀取對(duì)象
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 寫出對(duì)象
ServletOutputStream outputStream = response.getOutputStream();
// 通過IO寫出我們的表格對(duì)象
writer.flush(outputStream, true);
writer.close();
IoUtil.close(outputStream);
} catch (IOException e) {
log.error("EducationServiceImpl [export] 輸出到響應(yīng)流失敗", e);
throw new APIException("導(dǎo)出Excel異常");
}
}
這里我使用的是三層構(gòu)建,在controller 層中暴露接口,進(jìn)行調(diào)用,所有的具體實(shí)現(xiàn)進(jìn)行抽象。
//導(dǎo)入信息
@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();
}
//導(dǎo)出信息
@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;
@Override
public void export(PageVo pageVo, HttpServletResponse response) {
// 從數(shù)據(jù)庫(kù)查出數(shù)據(jù)對(duì)象封裝成map
final 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<>();
// 錯(cuò)誤,這里需要根據(jù)表中字段名稱進(jìn)行命名
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());
// 準(zhǔn)備將數(shù)據(jù)集合封裝成Excel對(duì)象
ExcelWriter writer = ExcelUtil.getWriter(true);
// 通過工具類創(chuàng)建writer并且進(jìn)行別名
writer.addHeaderAlias("nickname", "姓名");
writer.addHeaderAlias("sex", "性別( 0 表示男 , 1 表示 女)");
writer.addHeaderAlias("mobile", "電話");
writer.addHeaderAlias("bornTime", "出生日期");
writer.addHeaderAlias("homeAddress", "家庭地址");
writer.addHeaderAlias("post", "職位");
// 準(zhǔn)備將對(duì)象寫入我們的 List
writer.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();
// 這里可以自行關(guān)閉資源或者寫一個(gè)關(guān)閉資源的工具類
IoUtil.close(output);
} catch (IOException e) {
log.error("EducationServiceImpl [export] 輸出到響應(yīng)流失敗", e);
throw new APIException("導(dǎo)出Excel異常");
}
}
@Override
public 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 默認(rèn)圖片
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 進(jìn)行excel 處理的時(shí)候,需要自己定義字段與excel 表頭見的映射關(guān)系,這一點(diǎn)是比較麻煩的。但相比于其他excel的使用方式,這是一種非常簡(jiǎn)單的實(shí)現(xiàn)。
總結(jié)
到此這篇關(guān)于Java項(xiàng)目中如何引入Hutool工具類并正確使用它的文章就介紹到這了,更多相關(guān)Java引入Hutool并使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring 定時(shí)任務(wù)@Scheduled 注解四大參數(shù)用法解析
本文詳細(xì)介紹了Spring框架中使用@Scheduled注解實(shí)現(xiàn)定時(shí)任務(wù)的方法,重點(diǎn)講解了fixedRate、fixedDelay、cron和initialDelay這四個(gè)參數(shù)的用法,并通過實(shí)例代碼進(jìn)行了詳細(xì)說明,感興趣的朋友一起看看吧2025-01-01
Spring?Boot統(tǒng)一處理全局異常的實(shí)戰(zhàn)教程
最近在做項(xiàng)目時(shí)需要對(duì)異常進(jìn)行全局統(tǒng)一處理,所以下面這篇文章主要給大家介紹了關(guān)于Spring?Boot統(tǒng)一處理全局異常的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12
Java內(nèi)存模型(JMM)及happens-before原理
這篇文章主要介紹了java內(nèi)存模型(JMM)及happens-before原理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
Java中數(shù)組的創(chuàng)建與傳參方法(學(xué)習(xí)小結(jié))
這篇文章主要介紹了Java中數(shù)組的創(chuàng)建與傳參方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09
SpringBoot使用CommandLineRunner接口完成資源初始化方式
這篇文章主要介紹了SpringBoot使用CommandLineRunner接口完成資源初始化方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
Springboot實(shí)現(xiàn)Shiro整合JWT的示例代碼
這篇文章主要介紹了Springboot實(shí)現(xiàn)Shiro整合JWT的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
java 多態(tài)性詳解及簡(jiǎn)單實(shí)例
這篇文章主要介紹了java 多態(tài)性詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-02-02

