Backend Development 18 min read

Is Hutool Worth Using? A Deep Dive into Java’s Popular Utility Library

This article examines the popular Chinese Java utility library Hutool, discussing its features, recent updates, pros and cons, and provides practical code examples for integration, covering dependency setup, type conversion, email, ID generation, HTTP requests, caching, encryption, threading, and more.

macrozheng
macrozheng
macrozheng
Is Hutool Worth Using? A Deep Dive into Java’s Popular Utility Library

Is Hutool Worth Using?

The discussion about whether Hutool is worth using is hot on Zhihu; some argue its code quality is lacking, while others claim it greatly improves development efficiency because writing similar utility classes or using AI is more cumbersome.

What do you think?

Below is an answer from a senior engineer that I find practical and realistic.

For personal projects, just use it without much consideration.

For enterprise projects, consider stability and compatibility; Apache or Guava can be alternatives, but if functionality is the priority, Hutool is recommended.

Hutool Introduction

Hutool is a comprehensive Chinese Java utility library that wraps JDK methods for files, streams, encryption/decryption, encoding, regex, threading, XML, and more, providing out‑of‑the‑box functionality.

You can import the whole library with

hutool-all

, but it is recommended to include only the modules you actually need.

Many functions in Hutool are simple implementations (e.g., image captcha, Excel utilities) that may not satisfy complex project requirements; in such cases, consider specialized libraries like MyExcel, EasyExcel, or Imglib.

Hutool Practical Use

Adding Dependencies

Maven repository: https://mvnrepository.com/artifact/cn.hutool

<code>&lt;dependency&gt;
    &lt;groupId&gt;cn.hutool&lt;/groupId&gt;
    &lt;artifactId&gt;hutool-all&lt;/artifactId&gt;
    &lt;version&gt;5.8.16&lt;/version&gt;
&lt;/dependency&gt;
</code>

Gradle:

<code>implementation 'cn.hutool:hutool-all:5.8.16'
</code>

For a more elegant approach, use the

hutool-bom

module:

<code>&lt;dependencyManagement&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;cn.hutool&lt;/groupId&gt;
            &lt;artifactId&gt;hutool-bom&lt;/artifactId&gt;
            &lt;version&gt;${hutool.version}&lt;/version&gt;
            &lt;type&gt;pom&lt;/type&gt;
            &lt;scope&gt;import&lt;/scope&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
&lt;/dependencyManagement&gt;
</code>

In sub‑modules, import only the needed modules:

<code>&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;cn.hutool&lt;/groupId&gt;
        &lt;artifactId&gt;hutool-http&lt;/artifactId&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;
</code>

Feature Demonstrations

Type Conversion

The

Convert

class encapsulates common Java type conversions.

<code>long[] b = {1,2,3,4,5};
String bStr = Convert.toStr(b); // "[1, 2, 3, 4, 5]"

long a = 4535345L;
long minutes = Convert.convertTime(a, TimeUnit.MILLISECONDS, TimeUnit.MINUTES); // 75

double d = 67556.32;
String digitUppercase = Convert.digitToChinese(d); // "陆万柒仟伍佰伍拾陆元叁角贰分"
</code>

Email

Hutool wraps

javax.mail

to simplify email sending.

Configuration file

mail.setting

(placed in

src/main/resources

):

<code># SMTP host, default smtp.<sender domain>
host = smtp.yeah.net
# SMTP port, default 25
port = 25
# Sender address (must be correct)
from = [email protected]
# Username (default is the part before @)
user = hutool
# Password or SMTP authorization code
pass = q1w2e3
</code>

Send a simple email:

<code>MailUtil.send("[email protected]", "Test", "Email sent by Hutool test", false);
</code>

Send to multiple recipients:

<code>ArrayList<String> tos = CollUtil.newArrayList(
    "[email protected]",
    "[email protected]",
    "[email protected]",
    "[email protected]"
);
MailUtil.send(tos, "Test", "Batch email sent by Hutool", false);
</code>

Send with attachment:

<code>MailUtil.send("[email protected]", "Test", "<h1>Email from Hutool</h1>", true, FileUtil.file("d:/aaa.xml"));
</code>

Alternatively, use a

MailAccount

object for custom server settings:

<code>MailAccount account = new MailAccount();
account.setHost("smtp.yeah.net");
account.setPort("25");
account.setAuth(true);
account.setFrom("[email protected]");
account.setUser("hutool");
account.setPass("q1w2e3");
MailUtil.send(account, CollUtil.newArrayList("[email protected]"), "Test", "Email from Hutool", false);
</code>

Unique ID

Hutool provides utilities for generating UUID, ObjectId, and Snowflake IDs.

UUID

ObjectId (MongoDB)

Snowflake (Twitter)

UUID example:

<code>String uuid = IdUtil.randomUUID(); // with hyphens
String simpleUUID = IdUtil.simpleUUID(); // without hyphens
</code>

ObjectId example:

<code>String id = ObjectId.next(); // e.g., 5b9e306a4df4f8c54a39fb0c
String id2 = IdUtil.objectId();
</code>

Snowflake example:

<code>long id = IdUtil.getSnowflakeNextId();
String idStr = IdUtil.getSnowflakeNextIdStr();
</code>

HTTP Request Utilities

Hutool’s

HttpUtil

simplifies GET and POST requests.

GET request examples:

<code>String result1 = HttpUtil.get("https://www.baidu.com");
String result2 = HttpUtil.get("https://www.baidu.com", CharsetUtil.CHARSET_UTF_8);
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("city", "北京");
String result3 = HttpUtil.get("https://www.baidu.com", paramMap);
</code>

POST request example:

<code>HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("city", "北京");
String result = HttpUtil.post("https://www.baidu.com", paramMap);
</code>

File upload example:

<code>HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("file", FileUtil.file("D:\\face.jpg"));
String result = HttpUtil.post("https://www.baidu.com", paramMap);
</code>

Cache

Hutool implements several cache strategies:

FIFO (first in first out)

LFU (least frequently used)

LRU (least recently used)

Timed

Weak

FIFO cache example:

<code>Cache<String,String> fifoCache = CacheUtil.newFIFOCache(3);
fifoCache.put("key1", "value1", DateUnit.SECOND.getMillis()*3);
fifoCache.put("key2", "value2", DateUnit.SECOND.getMillis()*3);
fifoCache.put("key3", "value3", DateUnit.SECOND.getMillis()*3);
// Adding a fourth entry evicts the oldest (key1)
fifoCache.put("key4", "value4", DateUnit.SECOND.getMillis()*3);
String value1 = fifoCache.get("key1"); // null
</code>

Console Logging

Hutool’s

Console

offers a Java‑style

console.log()

API.

<code>String[] a = {"java", "c++", "c"};
Console.log(a); // [java, c++, c]
Console.log("This is Console log for {}.", "test"); // This is Console log for test.
</code>
The Console object works similarly to JavaScript’s console.log() , providing a familiar syntax for developers.

Bloom Filter

<code>BitMapBloomFilter filter = new BitMapBloomFilter(10);
filter.add("123");
filter.add("abc");
filter.add("ddd");
boolean contains = filter.contains("abc");
</code>

Encryption/Decryption

Hutool supports symmetric, asymmetric, digest, MAC algorithms, and Chinese national standards (SM2/SM3/SM4) via Bouncy Castle.

SM2 encryption/decryption example:

<code>String text = "JavaGuide: a comprehensive guide for Java developers.";
KeyPair pair = SecureUtil.generateKeyPair("SM2");
byte[] privateKey = pair.getPrivate().getEncoded();
byte[] publicKey = pair.getPublic().getEncoded();
SM2 sm2 = SmUtil.sm2(privateKey, publicKey);
String encryptStr = sm2.encryptBcd(text, KeyType.PublicKey);
String decryptStr = StrUtil.utf8Str(sm2.decryptFromBcd(encryptStr, KeyType.PrivateKey));
</code>

SM2 signing and verification:

<code>String sign = sm2.signHex(HexUtil.encodeHexStr(text));
boolean verify = sm2.verifyHex(HexUtil.encodeHexStr(text), sign);
</code>

Thread Pool

Hutool provides a builder‑style API for custom thread pools:

<code>private static ExecutorService pool = ExecutorBuilder.create()
    .setCorePoolSize(10)
    .setMaxPoolSize(20)
    .setWorkQueue(new LinkedBlockingQueue<>(100))
    .setThreadFactory(ThreadFactoryBuilder.create().setNamePrefix("IM-Pool-").build())
    .build();
</code>

Hutool also offers a global thread pool; asynchronous methods run in this pool via

ThreadUtil.execute

and

ThreadUtil.execAsync

.

ThreadUtil.execute

: execute a task in the global pool

ThreadUtil.execAsync

: run a method asynchronously

Example of initializing a sensitive‑word filter asynchronously:

<code>public static void init(final Collection<String> sensitiveWords, boolean isAsync) {
    if (isAsync) {
        ThreadUtil.execAsync(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                init(sensitiveWords);
                return true;
            }
        });
    } else {
        init(sensitiveWords);
    }
}
</code>

Related Links

Project address: https://github.com/dromara/hutool

Official site: https://hutool.cn/

JavaBackend Developmentdependency managementHutoolcode examplesUtility Library
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.