token
This commit is contained in:
@@ -3,6 +3,7 @@ package com.tem.bocai.service.impl;
|
|||||||
import com.tem.bocai.service.LoginService;
|
import com.tem.bocai.service.LoginService;
|
||||||
import com.tem.bocai.util.LotteryDataPipeline;
|
import com.tem.bocai.util.LotteryDataPipeline;
|
||||||
import com.tem.bocai.util.LotteryWebMagicCrawler;
|
import com.tem.bocai.util.LotteryWebMagicCrawler;
|
||||||
|
import com.tem.bocai.util.TokenCacheService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import net.sourceforge.tess4j.Tesseract;
|
import net.sourceforge.tess4j.Tesseract;
|
||||||
import net.sourceforge.tess4j.TesseractException;
|
import net.sourceforge.tess4j.TesseractException;
|
||||||
@@ -38,6 +39,8 @@ public class LoginServiceImpl implements LoginService {
|
|||||||
private static final int MAX_RETRY = 5;
|
private static final int MAX_RETRY = 5;
|
||||||
@Autowired
|
@Autowired
|
||||||
private Tesseract tesseract;
|
private Tesseract tesseract;
|
||||||
|
@Autowired
|
||||||
|
private TokenCacheService tokenCacheService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String loginAutomatic(String username, String password, String loginUrl, Integer winNum, Integer loseNum) {
|
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 + " 次尝试 ===");
|
System.out.println("\n=== 第 " + attempt + " 次尝试 ===");
|
||||||
try {
|
try {
|
||||||
token = attemptLogin();
|
token = attemptLogin();
|
||||||
|
tokenCacheService.saveToken(token);
|
||||||
if (token != null && !token.isEmpty()) {
|
if (token != null && !token.isEmpty()) {
|
||||||
// 2. 创建爬虫实例,传入token
|
// 2. 创建爬虫实例,传入token
|
||||||
LotteryWebMagicCrawler crawler = new LotteryWebMagicCrawler(token);
|
LotteryWebMagicCrawler crawler = new LotteryWebMagicCrawler(token);
|
||||||
@@ -88,6 +92,7 @@ public class LoginServiceImpl implements LoginService {
|
|||||||
System.out.println("\n=== 第 " + attempt + " 次尝试 ===");
|
System.out.println("\n=== 第 " + attempt + " 次尝试 ===");
|
||||||
try {
|
try {
|
||||||
token = attemptLogin();
|
token = attemptLogin();
|
||||||
|
|
||||||
if (token != null && !token.isEmpty()) {
|
if (token != null && !token.isEmpty()) {
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
92
src/main/java/com/tem/bocai/util/TokenCacheService.java
Normal file
92
src/main/java/com/tem/bocai/util/TokenCacheService.java
Normal file
@@ -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<String> 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> T getTokenInfo(String key, Class<T> type) {
|
||||||
|
Cache cache = tokenCacheManager.getCache(TOKEN_CACHE_NAME);
|
||||||
|
if (cache != null) {
|
||||||
|
return cache.get(TOKEN_INFO_KEY + "_" + key, type);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user