在Java开发领域,文件批量处理和安全认证是两大高频需求场景。Hutool作为国内流行的Java工具库,其文件操作模块简化了Excel/CSV等格式的导入导出流程;而JWT(JSON Web Token)则是现代分布式系统中身份验证的黄金标准。这两个技术点的组合,恰好覆盖了企业级应用开发中最常见的业务场景和技术挑战。
我曾在多个电商后台系统中深度应用这套技术组合。比如一个日均处理10万+订单的供应链系统,既要高效导入供应商报价单,又要确保每个API调用都经过严格的JWT鉴权。本文将分享如何用Hutool实现高性能文件批处理,并结合JWT实现安全控制,最后解析面试中最常被问到的12个核心问题。
首先在项目中引入Hutool的Maven依赖(以5.8.12版本为例):
xml复制<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.12</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
注意:虽然Hutool内置了POI的简化封装,但建议显式声明POI版本以避免依赖冲突。我曾遇到过因版本不匹配导致的"Invalid header signature"异常。
常规的Excel导出代码:
java复制List<User> userList = getUserList();
ExcelWriter writer = ExcelUtil.getWriter("d:/user.xlsx");
writer.write(userList, true);
writer.close();
当数据量超过1万行时,需要启用大数据模式:
java复制// 启用SXSSF模式(基于临时文件的分段存储)
ExcelWriter writer = ExcelUtil.getBigWriter("d:/big_user.xlsx");
// 设置内存中保留的行数(默认100)
writer.setRowAccessWindowSize(500);
实测数据:
处理包含多Sheet、数据校验的导入场景:
java复制ExcelReader reader = ExcelUtil.getReader("d:/order.xlsx");
// 读取第二个Sheet(下标从0开始)
List<Order> orders = reader.read(1, Order.class);
// 自定义校验
orders = orders.stream().filter(order -> {
if(order.getAmount() <= 0) {
log.warn("订单金额异常:{}", order.getOrderNo());
return false;
}
return true;
}).collect(Collectors.toList());
避坑指南:Hutool默认会将空单元格转为null,建议在实体类字段上添加
@ExcelIgnoreNull注解避免NPE。
推荐使用Java JWT(JJWT)库:
xml复制<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
生成JWT的典型配置:
java复制// HS256算法密钥(实际项目应从配置中心获取)
String secret = "your-256-bit-secret-your-256-bit-secret";
String jwt = Jwts.builder()
.setSubject("user123")
.claim("roles", Arrays.asList("admin", "operator"))
.setIssuedAt(new Date())
.setExpiration(DateUtil.offsetHour(new Date(), 2))
.signWith(Keys.hmacShaKeyFor(secret.getBytes()))
.compact();
| 算法类型 | 密钥长度 | 性能 | 安全性 | 适用场景 |
|---|---|---|---|---|
| HS256 | 256bit | 高 | 中 | 内部系统 |
| RS256 | 2048bit | 中 | 高 | 开放平台 |
| ES256 | 256bit | 低 | 极高 | 金融系统 |
经验之谈:中小型项目用HS256足够,但切记密钥长度必须≥256bit。曾见过用"123456"作密钥导致的安全事故。
双令牌机制实现:
java复制// 生成访问令牌(有效期30分钟)
String accessToken = Jwts.builder()
.setExpiration(DateUtil.offsetMinute(new Date(), 30))
// ...其他声明
.compact();
// 生成刷新令牌(有效期7天)
String refreshToken = Jwts.builder()
.setExpiration(DateUtil.offsetDay(new Date(), 7))
.claim("type", "refresh")
.compact();
刷新逻辑:
java复制public String refreshToken(String refreshToken) {
Claims claims = Jwts.parserBuilder()
.setSigningKey(secret)
.build()
.parseClaimsJws(refreshToken)
.getBody();
if(!"refresh".equals(claims.get("type"))) {
throw new IllegalStateException("非法的刷新令牌");
}
return generateNewAccessToken(claims.getSubject());
}
Q1:Hutool的Excel导出和原生POI有什么区别?
本质都是基于Apache POI的封装,但Hutool做了这些优化:
Q2:大文件导出时内存溢出怎么解决?
三级解决方案:
getBigWriter的SXSSF模式Q3:JWT相比Session有哪些优缺点?
优势:
劣势:
Q4:如何防止JWT被篡改?
五重防护策略:
乱码问题:
CharsetUtil.CHARSET_GBKFileWriter.create(file, CharsetUtil.CHARSET_UTF_8)内存泄漏:
java复制// 错误示例:未关闭资源
ExcelWriter writer = ExcelUtil.getWriter();
writer.write(data);
// 正确写法:try-with-resources
try (ExcelWriter writer = ExcelUtil.getWriter()) {
writer.write(data);
}
密钥管理:
令牌注销:
虽然JWT本身无状态,但可以通过这些方式实现类似Session注销的效果:
在4核8G的测试环境中:
| 操作类型 | 数据量 | Hutool耗时 | 原生POI耗时 |
|---|---|---|---|
| Excel导出 | 1万行 | 1.2s | 1.8s |
| Excel导入 | 1万行 | 0.9s | 1.5s |
| CSV导出 | 10万行 | 2.1s | 需自行实现 |
| JWT生成 | 1000次 | 0.3s | - |
优化建议: