Java項(xiàng)目中如何引入Hutool工具類(lèi)并正確使用它
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è)模塊沒(méi)用,你可以:
<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提供的工具類(lèi)和方法。例如,在您的Controller類(lèi)中,您可以使用Hutool的字符串工具類(lèi):
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)用程序,并訪問(wèn)
/hello
端點(diǎn),您將看到使用Hutool進(jìn)行字符串翻轉(zhuǎn)后的結(jié)果。
3. Hutool 的編譯安裝
如果想對(duì) Hutool 的源碼進(jìn)行編譯安裝,可以訪問(wè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 的源碼分支說(shuō)明
Hutool的源碼分為兩個(gè)分支,功能如下:
分支 | 作用 |
---|---|
v5-master | 主分支,release版本使用的分支,與中央庫(kù)提交的jar一致,不接收任何pr或修改 |
v5-dev | 開(kāi)發(fā)分支,默認(rèn)為下個(gè)版本的SNAPSHOT版本,接受修改或pr |
5. 給 Hutool 提供bug反饋或建議
提交問(wèn)題反饋請(qǐng)說(shuō)明正在使用的JDK版本呢、Hutool版本和相關(guān)依賴庫(kù)版本。
6. 給 Hutool 貢獻(xiàn)代碼的步驟
- 在Gitee或者Github上fork項(xiàng)目到自己的repo
- 把fork過(guò)去的項(xiàng)目也就是你的項(xiàng)目clone到你的本地
- 修改代碼(記得一定要修改v5-dev分支)
- commit后push到自己的庫(kù)(v5-dev分支)
- 登錄Gitee或Github在你首頁(yè)可以看到一個(gè) pull request 按鈕,點(diǎn)擊它,填寫(xiě)一些說(shuō)明信息,然后提交即可。
- 等待維護(hù)者合并
7. PR遵照的原則
Hutool歡迎任何人為Hutool添磚加瓦,貢獻(xiàn)代碼,不過(guò)維護(hù)者是一個(gè)強(qiáng)迫癥患者,為了照顧病人,需要提交的pr(pull request)符合一些規(guī)范,規(guī)范如下:
- 注釋完備,尤其每個(gè)新增的方法應(yīng)按照J(rèn)ava文檔規(guī)范標(biāo)明方法說(shuō)明、參數(shù)說(shuō)明、返回值說(shuō)明等信息,必要時(shí)請(qǐng)?zhí)砑訂卧獪y(cè)試,如果愿意,也可以加上你的大名。
- Hutool的縮進(jìn)按照Eclipse(不要跟我說(shuō)IDEA多好用,維護(hù)者非常懶,學(xué)不會(huì) ,IDEA真香,改了Eclipse快捷鍵后舒服多了)默認(rèn)(tab)縮進(jìn),所以請(qǐng)遵守(不要和我爭(zhēng)執(zhí)空格與tab的問(wèn)題,這是一個(gè)病人的習(xí)慣)。
- 新加的方法不要使用第三方庫(kù)的方法,Hutool遵循無(wú)依賴原則(除非在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)不要詫異,這是我們保持問(wèn)題處理整潔的一種方式,你依舊可以繼續(xù)討論,當(dāng)有討論結(jié)果時(shí)我們會(huì)重新打開(kāi)。
補(bǔ)充:基于Hutool的excel開(kāi)發(fā)
引入依賴
excel 包完全依賴于hutool 工具包,不需要額外的引入,hutool all中已經(jīng)包含了hutool 的全部工具包
<!-- hutool工具類(lèi) --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.22</version> </dependency>
開(kāi)發(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)入的過(guò)程中,需要進(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 寫(xiě)出對(duì)象 ServletOutputStream outputStream = response.getOutputStream(); // 通過(guò)IO寫(xiě)出我們的表格對(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); // 通過(guò)工具類(lèi)創(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ì)象寫(xiě)入我們的 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)閉資源或者寫(xiě)一個(gè)關(guān)閉資源的工具類(lèi) 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 表頭見(jiàn)的映射關(guān)系,這一點(diǎn)是比較麻煩的。但相比于其他excel的使用方式,這是一種非常簡(jiǎn)單的實(shí)現(xiàn)。
總結(jié)
到此這篇關(guān)于Java項(xiàng)目中如何引入Hutool工具類(lèi)并正確使用它的文章就介紹到這了,更多相關(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ù)的用法,并通過(guò)實(shí)例代碼進(jìn)行了詳細(xì)說(shuō)明,感興趣的朋友一起看看吧2025-01-01Spring?Boot統(tǒng)一處理全局異常的實(shí)戰(zhàn)教程
最近在做項(xiàng)目時(shí)需要對(duì)異常進(jìn)行全局統(tǒng)一處理,所以下面這篇文章主要給大家介紹了關(guān)于Spring?Boot統(tǒng)一處理全局異常的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12Java 八種基本類(lèi)型和基本類(lèi)型封裝類(lèi)
八種基本數(shù)據(jù)類(lèi)型分別是:int、short、float、double、long、boolean、byte、char;下面跟隨腳本之家小編一起學(xué)習(xí)java八種基本類(lèi)型和基本類(lèi)型封裝類(lèi)2017-09-09Java內(nèi)存模型(JMM)及happens-before原理
這篇文章主要介紹了java內(nèi)存模型(JMM)及happens-before原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Java中數(shù)組的創(chuàng)建與傳參方法(學(xué)習(xí)小結(jié))
這篇文章主要介紹了Java中數(shù)組的創(chuàng)建與傳參方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09SpringBoot使用CommandLineRunner接口完成資源初始化方式
這篇文章主要介紹了SpringBoot使用CommandLineRunner接口完成資源初始化方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02idea無(wú)法切換分支報(bào)錯(cuò)問(wèn)題及解決
這篇文章主要介紹了idea無(wú)法切換分支報(bào)錯(cuò)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03Springboot實(shí)現(xiàn)Shiro整合JWT的示例代碼
這篇文章主要介紹了Springboot實(shí)現(xiàn)Shiro整合JWT的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12java 多態(tài)性詳解及簡(jiǎn)單實(shí)例
這篇文章主要介紹了java 多態(tài)性詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-02-02