fix(system): 优化微信登录接口的响应处理和异常处理
- 改进了微信手机号和 access_token 获取接口的响应清理逻辑 - 增加了对响应格式的验证和错误处理 -优化了缓存 access_token 的存储和解析 - 提升了代码的健壮性和错误提示的详细性
This commit is contained in:
@@ -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) {
|
||||
try {
|
||||
// 解析access_token
|
||||
JSONObject response = JSON.parseObject(value);
|
||||
// return response.getString("access_token");
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user