修复验证码发送递归重复问题
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
bin/
|
||||
logs/
|
||||
runtime/
|
||||
config.ini
|
||||
*.log
|
||||
|
||||
75752
bash/hs_err_pid12840.log
75752
bash/hs_err_pid12840.log
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
#!/bin/bash
|
||||
# Termux专属启动脚本 编译+启动 解决exit后卡空行/需手动^C问题
|
||||
# 优化:增加JVM内存限制、进程异常捕获、日志输出
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")" || { echo "目录切换失败"; exit 1; }
|
||||
BASE_DIR=$(cd .. && pwd)
|
||||
|
||||
@@ -12,12 +13,28 @@ CLASSPATH="$BASE_DIR/runtime"
|
||||
[ -d "$BASE_DIR/libs" ] && CLASSPATH="$CLASSPATH:$BASE_DIR/libs/*"
|
||||
MAIN_CLASS="Main"
|
||||
|
||||
# 3. 关键修复:预重置终端+进程绑定+退出后强制清流
|
||||
# 3. 关键优化:JVM内存限制(避免内存耗尽)+ 异常日志输出
|
||||
export _JAVA_OPTIONS="-Xmx128m -Xms64m" # 限制最大堆内存128M,初始堆64M,适配Termux
|
||||
STOP_SIGNAL=0
|
||||
|
||||
# 捕获进程异常终止信号
|
||||
on_exit() {
|
||||
STOP_SIGNAL=1
|
||||
echo -e "\n⚠️ 服务异常终止,可查看日志排查问题"
|
||||
stty sane
|
||||
exit 1
|
||||
}
|
||||
trap 'on_exit' SIGABRT SIGSEGV SIGILL SIGTERM
|
||||
|
||||
# 4. 启动服务+日志输出
|
||||
stty -echoctl # 屏蔽^C视觉印记
|
||||
echo -e "\n🚀 服务启动中,输入help查指令,输入exit优雅停机"
|
||||
# 启动并绑定进程,Java结束脚本立刻走后续逻辑
|
||||
java -cp "$CLASSPATH" "$MAIN_CLASS"
|
||||
# Java退出后 强制重置终端+脚本退出,彻底无残留
|
||||
java -cp "$CLASSPATH" "$MAIN_CLASS" 2> "$BASE_DIR/logs/error.log" # 异常日志写入文件
|
||||
|
||||
# 5. Java退出后 强制重置终端+脚本退出,彻底无残留
|
||||
if [ $STOP_SIGNAL -eq 0 ]; then
|
||||
echo -e "\n✅ 服务优雅停机"
|
||||
fi
|
||||
stty sane
|
||||
exit $?
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import cc.winboll.LogUtils;
|
||||
import cc.winboll.auth.AuthCenterHttpService;
|
||||
import cc.winboll.auth.MailAuthUtils;
|
||||
import cc.winboll.service.AuthCenterHttpService;
|
||||
import cc.winboll.util.ConsoleInputUtils;
|
||||
import cc.winboll.util.EmailSendUtils;
|
||||
import cc.winboll.util.EnvInfoUtils;
|
||||
import cc.winboll.util.IniConfigUtils;
|
||||
import cc.winboll.util.ServerUtils;
|
||||
import cc.winboll.util.InitCheckUtils;
|
||||
import cc.winboll.util.EmailSendUtils;
|
||||
import cc.winboll.util.ServerUtils;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package cc.winboll.auth;
|
||||
package cc.winboll.service;
|
||||
|
||||
import cc.winboll.LogUtils;
|
||||
import cc.winboll.util.ServerUtils;
|
||||
@@ -71,7 +71,7 @@ public class AuthCenterHttpService extends NanoHTTPD {
|
||||
} catch (Exception e) {
|
||||
LogUtils.e(TAG, "请求处理异常", e);
|
||||
return newFixedLengthResponse(Response.Status.INTERNAL_ERROR, "application/json",
|
||||
"{\"code\":500,\"msg\":\"服务内部异常\",\"data\":null}");
|
||||
"{\"code\":500,\"msg\":\"服务内部异常\",\"data\":null}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,18 +79,26 @@ public class AuthCenterHttpService extends NanoHTTPD {
|
||||
private Response handlePingRequest() {
|
||||
LogUtils.d(TAG, "ping请求响应成功,返回pong");
|
||||
return newFixedLengthResponse(Response.Status.OK, "application/json",
|
||||
"{\"code\":200,\"msg\":\"pong\",\"data\":null}");
|
||||
"{\"code\":200,\"msg\":\"pong\",\"data\":null}");
|
||||
}
|
||||
|
||||
// 发送验证码:直接调用ServerUtils
|
||||
// 发送验证码:修改为调用本地方法,解决递归问题
|
||||
private Response handleSendVerifyCode(IHTTPSession session) throws IOException, NanoHTTPD.ResponseException{
|
||||
session.parseBody(null);
|
||||
Map<String, String> params = session.getParms();
|
||||
String email = params.get("email");
|
||||
LogUtils.d(TAG, "接收验证码发送请求,邮箱:" + email);
|
||||
|
||||
String result = ServerUtils.sendVerifyCode(email);
|
||||
return newFixedLengthResponse(Response.Status.OK, "application/json", result);
|
||||
// 核心修改:替换为本地发送方法,返回布尔值
|
||||
boolean sendResult = ServerUtils.sendVerifyCodeLocal(email);
|
||||
// 统一返回JSON格式,与其他接口保持一致
|
||||
String responseJson;
|
||||
if (sendResult) {
|
||||
responseJson = "{\"code\":200,\"msg\":\"验证码发送成功\",\"data\":null}";
|
||||
} else {
|
||||
responseJson = "{\"code\":500,\"msg\":\"验证码发送失败\",\"data\":null}";
|
||||
}
|
||||
return newFixedLengthResponse(Response.Status.OK, "application/json", responseJson);
|
||||
}
|
||||
|
||||
// 校验验证码:直接调用ServerUtils
|
||||
@@ -102,6 +110,10 @@ public class AuthCenterHttpService extends NanoHTTPD {
|
||||
LogUtils.d(TAG, "接收验证码校验请求,邮箱:" + email + ",验证码:" + code);
|
||||
|
||||
String result = ServerUtils.verifyCode(email, code);
|
||||
// 兜底处理null值,避免返回空响应
|
||||
if (result == null) {
|
||||
result = "{\"code\":500,\"msg\":\"校验失败\",\"data\":null}";
|
||||
}
|
||||
return newFixedLengthResponse(Response.Status.OK, "application/json", result);
|
||||
}
|
||||
|
||||
@@ -114,6 +126,9 @@ public class AuthCenterHttpService extends NanoHTTPD {
|
||||
LogUtils.d(TAG, "接收公钥提交请求,邮箱:" + email + ",公钥:" + publicKey);
|
||||
|
||||
String result = ServerUtils.submitAppPublicKey(email, publicKey);
|
||||
if (result == null) {
|
||||
result = "{\"code\":500,\"msg\":\"公钥提交失败\",\"data\":null}";
|
||||
}
|
||||
return newFixedLengthResponse(Response.Status.OK, "application/json", result);
|
||||
}
|
||||
|
||||
@@ -125,6 +140,9 @@ public class AuthCenterHttpService extends NanoHTTPD {
|
||||
LogUtils.d(TAG, "接收心跳请求,加密数据:" + encryptData);
|
||||
|
||||
String result = ServerUtils.sendPingRequest(encryptData);
|
||||
if (result == null) {
|
||||
result = "{\"code\":500,\"msg\":\"心跳请求失败\",\"data\":null}";
|
||||
}
|
||||
return newFixedLengthResponse(Response.Status.OK, "application/json", result);
|
||||
}
|
||||
|
||||
@@ -13,10 +13,10 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* 纯服务器交互工具类,仅负责封装HTTP请求、调用远程接口,无监听能力
|
||||
* 适配Java7语法,兼容Android API30环境,新增服务器连通性一键测试
|
||||
* 适配Java7语法,兼容Android API30环境,新增服务器连通性一键测试 + 本地验证码发送能力
|
||||
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||
* @Date 2026/01/16 00:00:00
|
||||
* @LastEditTime 2026/01/17 16:00:00
|
||||
* @LastEditTime 2026/01/18 10:00:00
|
||||
*/
|
||||
public class ServerUtils {
|
||||
// 基础属性
|
||||
@@ -39,18 +39,44 @@ public class ServerUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 优化版:发送验证码请求(POST),增强校验+兜底提示
|
||||
* ===================== 新增核心:本地发送验证码(供HTTP服务内部调用,无递归) =====================
|
||||
* 直接调用EmailSendUtils,不发起HTTP请求,彻底解决递归问题
|
||||
*/
|
||||
public static boolean sendVerifyCodeLocal(String email) {
|
||||
LogUtils.d(TAG, "调用sendVerifyCodeLocal,本地发送验证码,邮箱:" + email);
|
||||
// 1. 前置校验:邮箱格式
|
||||
if (email == null || email.trim().isEmpty() || !email.contains("@")) {
|
||||
LogUtils.w(TAG, "本地发送验证码失败:邮箱为空或格式不合法");
|
||||
return false;
|
||||
}
|
||||
String trimEmail = email.trim();
|
||||
// 2. 生成6位验证码(依赖VerifyCodeUtils,需确保该类存在)
|
||||
String verifyCode = VerifyCodeUtils.generateCode();
|
||||
// 3. 直接调用邮件工具类发送
|
||||
boolean sendResult = EmailSendUtils.sendVerifyCodeEmail(trimEmail, verifyCode);
|
||||
// 4. 缓存验证码(供后续校验,依赖VerifyCodeCacheUtils)
|
||||
if (sendResult) {
|
||||
VerifyCodeCacheUtils.putCode(trimEmail, verifyCode);
|
||||
LogUtils.i(TAG, "本地验证码发送成功,邮箱[" + trimEmail + "] 验证码[" + verifyCode + "]");
|
||||
} else {
|
||||
LogUtils.e(TAG, "本地验证码发送失败,邮箱[" + trimEmail + "]");
|
||||
}
|
||||
return sendResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 优化版:发送验证码请求(POST,供外部客户端调用远程接口,保留原逻辑)
|
||||
*/
|
||||
public static String sendVerifyCode(String email) {
|
||||
LogUtils.d(TAG, "调用sendVerifyCode,邮箱参数:" + email);
|
||||
LogUtils.d(TAG, "调用sendVerifyCode,远程请求验证码,邮箱参数:" + email);
|
||||
// 1. 前置校验:服务器地址未初始化
|
||||
if (serverBaseUrl == null || serverBaseUrl.trim().isEmpty()) {
|
||||
LogUtils.e(TAG, "发送验证码失败:服务器地址未初始化,请先调用initServerUrl()");
|
||||
LogUtils.e(TAG, "远程发送验证码失败:服务器地址未初始化,请先调用initServerUrl()");
|
||||
return null;
|
||||
}
|
||||
// 2. 前置校验:邮箱空值/格式基础校验
|
||||
if (email == null || email.trim().isEmpty() || !email.contains("@")) {
|
||||
LogUtils.w(TAG, "发送验证码失败:邮箱地址为空或格式不合法");
|
||||
LogUtils.w(TAG, "远程发送验证码失败:邮箱地址为空或格式不合法");
|
||||
return null;
|
||||
}
|
||||
String trimEmail = email.trim();
|
||||
@@ -58,7 +84,7 @@ public class ServerUtils {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("email", trimEmail);
|
||||
String result = sendPostRequest(url, params);
|
||||
LogUtils.d(TAG, "验证码发送请求执行完成,邮箱[" + trimEmail + "] 接口响应:" + (result == null ? "null" : result));
|
||||
LogUtils.d(TAG, "远程验证码请求执行完成,邮箱[" + trimEmail + "] 接口响应:" + (result == null ? "null" : result));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
32
src/cc/winboll/util/VerifyCodeCacheUtils.java
Normal file
32
src/cc/winboll/util/VerifyCodeCacheUtils.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package cc.winboll.util;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 验证码缓存工具类,适配Java7,临时存储验证码用于校验
|
||||
*/
|
||||
public class VerifyCodeCacheUtils {
|
||||
private static final Map<String, String> CODE_CACHE = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 存入验证码,键为邮箱
|
||||
*/
|
||||
public static void putCode(String email, String code) {
|
||||
CODE_CACHE.put(email, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证码,键为邮箱
|
||||
*/
|
||||
public static String getCode(String email) {
|
||||
return CODE_CACHE.get(email);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除已校验的验证码,释放内存
|
||||
*/
|
||||
public static void removeCode(String email) {
|
||||
CODE_CACHE.remove(email);
|
||||
}
|
||||
}
|
||||
|
||||
16
src/cc/winboll/util/VerifyCodeUtils.java
Normal file
16
src/cc/winboll/util/VerifyCodeUtils.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package cc.winboll.util;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* 验证码生成工具类,适配Java7
|
||||
*/
|
||||
public class VerifyCodeUtils {
|
||||
/**
|
||||
* 生成6位纯数字验证码
|
||||
*/
|
||||
public static String generateCode() {
|
||||
Random random = new Random();
|
||||
return String.format("%06d", random.nextInt(999999));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user