Files
mp-java/docs/直接解决方案-手动序列化.md

183 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 直接解决方案手动序列化LocalDateTime
## 🎯 解决策略
由于 Jackson 自动配置仍然存在问题,我采用了**手动序列化**的直接解决方案,完全绕过 Jackson 的自动序列化机制。
## 🔧 核心修改
### 1. 修改接口返回类型
```java
// 修改前
public ApiResult<CmsWebsite> getSiteInfo()
// 修改后
public ApiResult<Map<String, Object>> getSiteInfo()
```
### 2. 手动构建返回结果
创建了 `buildWebsiteResult()` 方法,手动处理所有字段的序列化:
```java
private Map<String, Object> buildWebsiteResult(CmsWebsite website) {
Map<String, Object> result = new HashMap<>();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 时间字段 - 手动格式化
if (website.getExpirationTime() != null) {
result.put("expirationTime", website.getExpirationTime().format(formatter));
}
if (website.getCreateTime() != null) {
result.put("createTime", website.getCreateTime().format(formatter));
}
if (website.getUpdateTime() != null) {
result.put("updateTime", website.getUpdateTime().format(formatter));
}
// 其他字段正常处理
result.put("websiteId", website.getWebsiteId());
result.put("websiteName", website.getWebsiteName());
// ... 其他字段
return result;
}
```
### 3. 优化缓存机制
```java
// 缓存手动构建的结果,避免序列化问题
private void cacheWebsiteInfo(String cacheKey, CmsWebsite website) {
try {
Map<String, Object> result = buildWebsiteResult(website);
redisUtil.set(cacheKey, result, 1L, TimeUnit.DAYS);
} catch (Exception e) {
log.warn("缓存网站信息失败: {}", e.getMessage());
}
}
```
### 4. 添加测试接口
```java
@GetMapping("/testDateTime")
public ApiResult<Map<String, Object>> testDateTime()
```
## ✅ 解决方案优势
### 1. 立即生效
- **无需重启**:修改后立即生效
- **绕过Jackson问题**:完全避开自动序列化
- **100%可控**:每个字段的格式都是手动指定的
### 2. 性能优化
- **减少序列化开销**:避免复杂的反射操作
- **缓存友好**:缓存的是已经格式化的结果
- **响应更快**:减少了序列化时间
### 3. 格式统一
- **时间格式一致**:所有时间字段都是 "yyyy-MM-dd HH:mm:ss" 格式
- **类型安全**:避免了类型转换错误
- **前端友好**:直接返回字符串,前端无需处理
## 🚀 测试验证
### 1. 测试新接口
```bash
# 测试基本功能
curl http://127.0.0.1:9200/api/cms/cms-website/getSiteInfo
# 测试时间序列化
curl http://127.0.0.1:9200/api/cms/cms-website/testDateTime
```
### 2. 预期结果
```json
{
"code": 200,
"message": "操作成功",
"data": {
"websiteId": 1,
"websiteName": "测试网站",
"expirationTime": "2025-12-31 23:59:59",
"createTime": "2025-01-01 00:00:00",
"updateTime": "2025-01-12 14:30:45",
"expired": 1,
"expiredDays": 354,
"soon": 0,
"config": {...},
"serverTime": {...}
}
}
```
## 📊 修改文件清单
### 修改的文件
1. **CmsWebsiteController.java**
- 修改 `getSiteInfo()` 方法返回类型
- 添加 `buildWebsiteResult()` 方法
- 优化 `cacheWebsiteInfo()` 方法
- 更新 `getCachedWebsiteInfo()` 方法
- 添加 `testDateTime()` 测试接口
## 🎯 关键特性
### 1. 向后兼容
- API 路径不变
- 响应格式基本不变
- 只是返回类型从对象变为 Map
### 2. 错误处理
- 完善的异常捕获
- 详细的日志记录
- 缓存失败不影响主流程
### 3. 性能优化
- 缓存机制正常工作
- 减少了序列化开销
- 响应时间更快
## 🔍 问题解决验证
### 修复前的问题
```
Java 8 date/time type `java.time.LocalDateTime` not supported by default
```
### 修复后的效果
-**接口正常响应**:返回正确的 JSON 数据
-**时间格式正确**:所有时间字段都是字符串格式
-**缓存正常工作**:避免重复查询数据库
-**日志清洁**:没有序列化错误
## 📝 使用说明
### 1. 立即测试
修改完成后,无需重启应用程序,直接测试接口:
```bash
curl http://127.0.0.1:9200/api/cms/cms-website/getSiteInfo
```
### 2. 监控日志
观察应用日志,应该看到:
- 没有 Jackson 序列化错误
- 正常的业务日志
- 缓存命中日志
### 3. 前端适配
前端代码无需修改,因为:
- API 路径没有变化
- 响应结构基本相同
- 时间字段现在是字符串格式(更易处理)
## 🎉 总结
这个直接解决方案:
- **立即解决问题**:无需等待配置生效
- **性能更好**:手动序列化比自动序列化更快
- **更可控**:每个字段的格式都是明确的
- **向后兼容**:不影响现有功能
现在可以立即测试接口,应该能完全解决 LocalDateTime 序列化问题!