- 新增 CmsWebsiteVO 和 CmsNavigationVO 类用于前端展示 - 重构 getSiteInfo 方法,优化缓存逻辑和数据处理 - 新增 clearSiteInfoCache 方法用于清除缓存 - 优化网站状态、配置和导航信息的处理逻辑
183 lines
4.8 KiB
Markdown
183 lines
4.8 KiB
Markdown
# 直接解决方案:手动序列化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 序列化问题!
|