fix(system): 优化微信登录接口的响应处理和异常处理

- 改进了微信手机号和 access_token 获取接口的响应清理逻辑
- 增加了对响应格式的验证和错误处理
-优化了缓存 access_token 的存储和解析
- 提升了代码的健壮性和错误提示的详细性
This commit is contained in:
2025-09-04 10:22:08 +08:00
parent 691467907c
commit 54a840dea2

View File

@@ -292,12 +292,34 @@ public class WxLoginController extends BaseController {
throw new BusinessException("微信接口响应为空");
}
// 清理响应中的控制字符
String cleanResponse = post.trim().replaceAll("[\u0000-\u001f]", "");
System.out.println("微信获取手机号响应: " + cleanResponse);
// 更全面地清理响应中的特殊字符
String cleanResponse = post.trim()
.replaceAll("[\u0000-\u001f\u007f-\u009f]", "") // 清理控制字符
.replaceAll("\\p{Cntrl}", "") // 清理所有控制字符
.replaceAll("[\\x00-\\x1f\\x7f]", ""); // 清理ASCII控制字符
JSONObject json = JSON.parseObject(cleanResponse);
if (json.get("errcode").equals(0)) {
System.out.println("微信获取手机号原始响应: " + post);
System.out.println("微信获取手机号清理后响应: " + cleanResponse);
// 验证清理后的响应是否为有效JSON
if (!cleanResponse.startsWith("{") || !cleanResponse.endsWith("}")) {
System.err.println("响应不是有效的JSON格式: " + cleanResponse);
throw new BusinessException("微信接口响应格式异常");
}
JSONObject json;
try {
json = JSON.parseObject(cleanResponse);
} catch (Exception parseException) {
System.err.println("JSON解析失败: " + parseException.getMessage());
System.err.println("原始响应: " + post);
System.err.println("清理后响应: " + cleanResponse);
throw new BusinessException("微信接口响应解析失败");
}
// 检查微信接口是否返回错误
Object errcode = json.get("errcode");
if (errcode != null && errcode.equals(0)) {
JSONObject phoneInfo = JSON.parseObject(json.getString("phone_info"));
// 微信用户的手机号码
final String phoneNumber = phoneInfo.getString("phoneNumber");
@@ -310,13 +332,16 @@ public class WxLoginController extends BaseController {
return phoneNumber;
} else {
String errorMsg = json.getString("errmsg");
System.err.println("微信获取手机号失败: errcode=" + json.get("errcode") + ", errmsg=" + errorMsg);
System.err.println("微信获取手机号失败: errcode=" + errcode + ", errmsg=" + errorMsg);
throw new BusinessException("获取手机号失败:" + errorMsg);
}
} catch (BusinessException be) {
// 重新抛出业务异常
throw be;
} catch (Exception e) {
System.err.println("获取微信手机号异常: " + e.getMessage());
e.printStackTrace();
throw new BusinessException("获取手机号失败,请重试");
throw new BusinessException("获取手机号失败,请重试: " + e.getMessage());
}
}
@@ -346,17 +371,30 @@ public class WxLoginController extends BaseController {
// 从缓存获取access_token
String value = redisTemplate.opsForValue().get(key);
if (value != null) {
// 解析access_token
JSONObject response = JSON.parseObject(value);
// return response.getString("access_token");
try {
// 解析access_token
JSONObject response = JSON.parseObject(value);
String accessToken = response.getString("access_token");
if (StrUtil.isNotBlank(accessToken)) {
System.out.println("从缓存获取access_token: " + accessToken);
return accessToken;
}
} catch (Exception e) {
System.err.println("解析缓存的access_token失败: " + e.getMessage());
// 缓存数据异常,删除缓存,重新获取
redisTemplate.delete(key);
}
}
// 微信获取凭证接口
String apiUrl = "https://api.weixin.qq.com/cgi-bin/token";
// 组装url参数
String url = apiUrl.concat("?grant_type=client_credential").concat("&appid=").concat(setting.getString("appId")).concat("&secret=").concat(setting.getString("appSecret"));
System.out.println("请求微信access_token接口: " + url);
// 执行get请求
String result = HttpUtil.get(url);
System.out.println("result = " + result);
System.out.println("微信access_token原始响应: " + result);
try {
// 验证响应内容
@@ -364,24 +402,56 @@ public class WxLoginController extends BaseController {
throw new BusinessException("微信接口响应为空");
}
// 清理响应中的控制字符
String cleanResult = result.trim().replaceAll("[\u0000-\u001f]", "");
// 更全面地清理响应中的特殊字符
String cleanResult = result.trim()
.replaceAll("[\u0000-\u001f\u007f-\u009f]", "") // 清理控制字符
.replaceAll("\\p{Cntrl}", "") // 清理所有控制字符
.replaceAll("[\\x00-\\x1f\\x7f]", ""); // 清理ASCII控制字符
System.out.println("微信access_token清理后响应: " + cleanResult);
// 验证清理后的响应是否为有效JSON
if (!cleanResult.startsWith("{") || !cleanResult.endsWith("}")) {
System.err.println("响应不是有效的JSON格式: " + cleanResult);
throw new BusinessException("微信接口响应格式异常");
}
// 解析access_token
JSONObject response = JSON.parseObject(cleanResult);
if (response.getString("access_token") != null) {
// 存入缓存
redisTemplate.opsForValue().set(key, cleanResult, 7000L, TimeUnit.SECONDS);
return response.getString("access_token");
} else {
JSONObject response;
try {
response = JSON.parseObject(cleanResult);
} catch (Exception parseException) {
System.err.println("JSON解析失败: " + parseException.getMessage());
System.err.println("原始响应: " + result);
System.err.println("清理后响应: " + cleanResult);
throw new BusinessException("微信接口响应解析失败");
}
// 检查是否有错误码
Object errcode = response.get("errcode");
if (errcode != null && !errcode.equals(0)) {
String errorMsg = response.getString("errmsg");
System.err.println("获取access_token失败: " + errorMsg);
System.err.println("获取access_token失败: errcode=" + errcode + ", errmsg=" + errorMsg);
throw new BusinessException("获取access_token失败" + errorMsg);
}
String accessToken = response.getString("access_token");
if (StrUtil.isNotBlank(accessToken)) {
// 存入缓存设置过期时间为7000秒约2小时微信access_token有效期为2小时
redisTemplate.opsForValue().set(key, cleanResult, 7000L, TimeUnit.SECONDS);
System.out.println("获取新的access_token成功: " + accessToken);
return accessToken;
} else {
System.err.println("响应中没有access_token字段: " + cleanResult);
throw new BusinessException("获取access_token失败响应格式异常");
}
} catch (BusinessException be) {
// 重新抛出业务异常
throw be;
} catch (Exception e) {
System.err.println("解析access_token异常: " + e.getMessage());
e.printStackTrace();
throw new BusinessException("小程序配置不正确或网络异常");
throw new BusinessException("小程序配置不正确或网络异常: " + e.getMessage());
}
}