From 7bb698c9c032cacca4e4db4455042a9c9806ccec Mon Sep 17 00:00:00 2001 From: xuelijun <977662702@qq.com> Date: Wed, 21 Jan 2026 15:40:03 +0800 Subject: [PATCH] token --- .../bocai/service/impl/LoginServiceImpl.java | 5 + .../com/tem/bocai/util/TokenCacheManager.java | 217 ------------------ .../com/tem/bocai/util/TokenCacheService.java | 92 ++++++++ 3 files changed, 97 insertions(+), 217 deletions(-) delete mode 100644 src/main/java/com/tem/bocai/util/TokenCacheManager.java create mode 100644 src/main/java/com/tem/bocai/util/TokenCacheService.java diff --git a/src/main/java/com/tem/bocai/service/impl/LoginServiceImpl.java b/src/main/java/com/tem/bocai/service/impl/LoginServiceImpl.java index 5dc4fef..6a5bde7 100644 --- a/src/main/java/com/tem/bocai/service/impl/LoginServiceImpl.java +++ b/src/main/java/com/tem/bocai/service/impl/LoginServiceImpl.java @@ -3,6 +3,7 @@ package com.tem.bocai.service.impl; import com.tem.bocai.service.LoginService; import com.tem.bocai.util.LotteryDataPipeline; import com.tem.bocai.util.LotteryWebMagicCrawler; +import com.tem.bocai.util.TokenCacheService; import org.springframework.stereotype.Service; import net.sourceforge.tess4j.Tesseract; import net.sourceforge.tess4j.TesseractException; @@ -38,6 +39,8 @@ public class LoginServiceImpl implements LoginService { private static final int MAX_RETRY = 5; @Autowired private Tesseract tesseract; + @Autowired + private TokenCacheService tokenCacheService; @Override public String loginAutomatic(String username, String password, String loginUrl, Integer winNum, Integer loseNum) { @@ -46,6 +49,7 @@ public class LoginServiceImpl implements LoginService { System.out.println("\n=== 第 " + attempt + " 次尝试 ==="); try { token = attemptLogin(); + tokenCacheService.saveToken(token); if (token != null && !token.isEmpty()) { // 2. 创建爬虫实例,传入token LotteryWebMagicCrawler crawler = new LotteryWebMagicCrawler(token); @@ -88,6 +92,7 @@ public class LoginServiceImpl implements LoginService { System.out.println("\n=== 第 " + attempt + " 次尝试 ==="); try { token = attemptLogin(); + if (token != null && !token.isEmpty()) { return token; } diff --git a/src/main/java/com/tem/bocai/util/TokenCacheManager.java b/src/main/java/com/tem/bocai/util/TokenCacheManager.java deleted file mode 100644 index faeed4f..0000000 --- a/src/main/java/com/tem/bocai/util/TokenCacheManager.java +++ /dev/null @@ -1,217 +0,0 @@ -package com.tem.bocai.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -@Component -public class TokenCacheManager { - - private static final String CACHE_FILE_PATH = "token_cache.json"; - private static final long TOKEN_EXPIRE_TIME = 1140000; // 19分钟过期(毫秒) 1140000 = 19 * 60 * 1000 - - private final ObjectMapper objectMapper = new ObjectMapper(); - - /** - * 保存token到缓存文件 - */ - public void saveToken(String token) { - try { - Map cacheData = new HashMap<>(); - cacheData.put("token", token); - cacheData.put("timestamp", System.currentTimeMillis()); - cacheData.put("expireTime", TOKEN_EXPIRE_TIME); - cacheData.put("expireMinutes", 19); // 记录过期分钟数 - - String json = objectMapper.writeValueAsString(cacheData); - Files.write(Paths.get(CACHE_FILE_PATH), json.getBytes()); - - System.out.println("Token已保存到缓存文件: " + CACHE_FILE_PATH); - System.out.println("Token将在19分钟后过期"); - - } catch (IOException e) { - System.err.println("保存token缓存失败: " + e.getMessage()); - } - } - - /** - * 从缓存文件读取token - */ - public String readToken() { - try { - File cacheFile = new File(CACHE_FILE_PATH); - if (!cacheFile.exists()) { - System.out.println("缓存文件不存在"); - return null; - } - - String json = new String(Files.readAllBytes(Paths.get(CACHE_FILE_PATH))); - Map cacheData = objectMapper.readValue(json, Map.class); - - String token = (String) cacheData.get("token"); - Long timestamp = (Long) cacheData.get("timestamp"); - - if (!StringUtils.hasText(token) || timestamp == null) { - System.out.println("缓存数据不完整"); - return null; - } - - // 检查token是否过期 - long currentTime = System.currentTimeMillis(); - long elapsedTime = currentTime - timestamp; - - if (elapsedTime > TOKEN_EXPIRE_TIME) { - long expiredSeconds = (elapsedTime - TOKEN_EXPIRE_TIME) / 1000; - System.out.println("Token已过期 " + expiredSeconds + " 秒"); - return null; - } - - // 计算剩余时间 - long remainingTime = TOKEN_EXPIRE_TIME - elapsedTime; - long remainingMinutes = remainingTime / 60000; - long remainingSeconds = (remainingTime % 60000) / 1000; - - System.out.println("从缓存读取token,剩余有效时间: " + - remainingMinutes + "分" + remainingSeconds + "秒"); - return token; - - } catch (IOException e) { - System.err.println("读取token缓存失败: " + e.getMessage()); - return null; - } - } - - /** - * 清除token缓存 - */ - public void clearToken() { - try { - File cacheFile = new File(CACHE_FILE_PATH); - if (cacheFile.exists()) { - Files.delete(Paths.get(CACHE_FILE_PATH)); - System.out.println("Token缓存已清除"); - } - } catch (IOException e) { - System.err.println("清除token缓存失败: " + e.getMessage()); - } - } - - /** - * 检查token是否存在且有效 - */ - public boolean hasValidToken() { - return readToken() != null; - } - - /** - * 检查token是否即将过期(例如5分钟内过期) - */ - public boolean isTokenExpiringSoon(int warningMinutes) { - try { - File cacheFile = new File(CACHE_FILE_PATH); - if (!cacheFile.exists()) { - return false; - } - - String json = new String(Files.readAllBytes(Paths.get(CACHE_FILE_PATH))); - Map cacheData = objectMapper.readValue(json, Map.class); - - Long timestamp = (Long) cacheData.get("timestamp"); - if (timestamp == null) { - return false; - } - - long currentTime = System.currentTimeMillis(); - long elapsedTime = currentTime - timestamp; - long remainingTime = TOKEN_EXPIRE_TIME - elapsedTime; - - // 检查是否在指定分钟内过期 - return remainingTime > 0 && remainingTime <= (warningMinutes * 60000); - - } catch (Exception e) { - return false; - } - } - - /** - * 获取token信息(用于调试) - */ - public Map getTokenInfo() { - try { - File cacheFile = new File(CACHE_FILE_PATH); - if (!cacheFile.exists()) { - return null; - } - - String json = new String(Files.readAllBytes(Paths.get(CACHE_FILE_PATH))); - Map cacheData = objectMapper.readValue(json, Map.class); - - Long timestamp = (Long) cacheData.get("timestamp"); - if (timestamp != null) { - long currentTime = System.currentTimeMillis(); - long elapsedTime = currentTime - timestamp; - long remainingTime = TOKEN_EXPIRE_TIME - elapsedTime; - - cacheData.put("savedTime", new Date(timestamp).toString()); - cacheData.put("elapsedTime", formatTime(elapsedTime)); - cacheData.put("remainingTime", formatTime(remainingTime)); - cacheData.put("isValid", remainingTime > 0); - cacheData.put("expireMinutes", 19); - - // 添加过期警告 - if (remainingTime > 0) { - if (remainingTime <= 300000) { // 5分钟内过期 - cacheData.put("warning", "Token将在5分钟内过期,建议刷新"); - } else if (remainingTime <= 600000) { // 10分钟内过期 - cacheData.put("warning", "Token将在10分钟内过期"); - } - } - } - - return cacheData; - - } catch (Exception e) { - return null; - } - } - - /** - * 格式化时间显示 - */ - private String formatTime(long millis) { - if (millis <= 0) { - return "已过期"; - } - - long minutes = millis / 60000; - long seconds = (millis % 60000) / 1000; - - if (minutes > 0) { - return minutes + "分" + seconds + "秒"; - } else { - return seconds + "秒"; - } - } - - /** - * 获取token过期时间配置 - */ - public static long getTokenExpireTime() { - return TOKEN_EXPIRE_TIME; - } - - /** - * 获取token过期分钟数 - */ - public static int getTokenExpireMinutes() { - return (int) (TOKEN_EXPIRE_TIME / 60000); - } -} \ No newline at end of file diff --git a/src/main/java/com/tem/bocai/util/TokenCacheService.java b/src/main/java/com/tem/bocai/util/TokenCacheService.java new file mode 100644 index 0000000..ecaf7f0 --- /dev/null +++ b/src/main/java/com/tem/bocai/util/TokenCacheService.java @@ -0,0 +1,92 @@ +package com.tem.bocai.util; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.stereotype.Service; + +import java.util.concurrent.Callable; + +@Service +public class TokenCacheService { + + private static final String TOKEN_CACHE_NAME = "tokenCache"; + private static final String TOKEN_KEY = "login_token"; + private static final String TOKEN_INFO_KEY = "token_info"; + + @Autowired + private CacheManager tokenCacheManager; + + /** + * 保存token到缓存 + */ + public void saveToken(String token) { + Cache cache = tokenCacheManager.getCache(TOKEN_CACHE_NAME); + if (cache != null) { + cache.put(TOKEN_KEY, token); + System.out.println("Token已保存到内存缓存"); + } + } + + /** + * 从缓存获取token + */ + public String getToken() { + Cache cache = tokenCacheManager.getCache(TOKEN_CACHE_NAME); + if (cache != null) { + return cache.get(TOKEN_KEY, String.class); + } + return null; + } + + /** + * 从缓存获取token,如果不存在则通过回调函数获取 + */ + public String getToken(Callable tokenLoader) { + Cache cache = tokenCacheManager.getCache(TOKEN_CACHE_NAME); + if (cache != null) { + return cache.get(TOKEN_KEY, tokenLoader); + } + return null; + } + + /** + * 清除token缓存 + */ + public void clearToken() { + Cache cache = tokenCacheManager.getCache(TOKEN_CACHE_NAME); + if (cache != null) { + cache.evict(TOKEN_KEY); + System.out.println("Token已从内存缓存清除"); + } + } + + /** + * 检查是否有有效token + */ + public boolean hasValidToken() { + return getToken() != null; + } + + /** + * 保存token相关信息 + */ + public void saveTokenInfo(String key, Object value) { + Cache cache = tokenCacheManager.getCache(TOKEN_CACHE_NAME); + if (cache != null) { + cache.put(TOKEN_INFO_KEY + "_" + key, value); + } + } + + /** + * 获取token相关信息 + */ + public T getTokenInfo(String key, Class type) { + Cache cache = tokenCacheManager.getCache(TOKEN_CACHE_NAME); + if (cache != null) { + return cache.get(TOKEN_INFO_KEY + "_" + key, type); + } + return null; + } + +}