Commit 4a8a31f9 4a8a31f935ae1214dccfd4fe2e7437c3fc6da97a by 文鑫

bug修改

1 parent c49817a2
......@@ -36,7 +36,6 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--愉快办对接-->
<dependency>
......
package com.topdraw.dockingapi.config;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dtflys.forest.annotation.MethodLifeCycle;
import com.dtflys.forest.annotation.RequestAttributes;
import com.dtflys.forest.http.ForestRequest;
import com.dtflys.forest.http.ForestResponse;
import com.dtflys.forest.lifecycles.MethodAnnotationLifeCycle;
import com.dtflys.forest.reflection.ForestMethod;
import com.topdraw.dockingapi.util.DecryptUtils;
import lombok.SneakyThrows;
import java.lang.annotation.*;
......@@ -21,7 +11,7 @@ import java.lang.annotation.*;
* @date 2024/5/23 下午5:45
*/
@Documented
@MethodLifeCycle(Decode.DecodeLifeCycle.class)
@MethodLifeCycle(DecodeLifeCycle.class)
@RequestAttributes
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
......@@ -29,30 +19,5 @@ public @interface Decode {
String value();
class DecodeLifeCycle implements MethodAnnotationLifeCycle<Decode, Object> {
private String key;
@Override
public void onMethodInitialized(ForestMethod method, Decode annotation) {
this.key = annotation.value();
}
@SneakyThrows
@Override
public void onSuccess(Object data, ForestRequest request, ForestResponse response) {
String value = (String) getAttribute(request, "value");
String content = response.getContent();
ForestMethod<?> method = request.getMethod();
Class<?> returnClass = method.getReturnClass();
JSONObject responseData = JSON.parseObject(content, JSONObject.class);
if (StrUtil.isNotBlank(responseData.getString("errcode"))) {
data = BeanUtil.copyProperties(responseData, returnClass);
} else {
String encrypt = responseData.getString("encrypt");
String bodyJson = DecryptUtils.decode(value, encrypt);
data = BeanUtil.copyProperties(JSONObject.parseObject(bodyJson), returnClass);
}
response.setResult(data);
}
}
}
......
package com.topdraw.dockingapi.config;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dtflys.forest.http.ForestRequest;
import com.dtflys.forest.http.ForestResponse;
import com.dtflys.forest.lifecycles.MethodAnnotationLifeCycle;
import com.dtflys.forest.reflection.ForestMethod;
import com.topdraw.dockingapi.util.DecryptUtils;
import lombok.SneakyThrows;
/**
* @author wenxin
* @version 1.0
* @date 2024/5/28 下午2:46
*/
public class DecodeLifeCycle implements MethodAnnotationLifeCycle<Decode, Object> {
@Override
public void onMethodInitialized(ForestMethod method, Decode annotation) {
}
@SneakyThrows
@Override
@SuppressWarnings("all")
public void onSuccess(Object data, ForestRequest request, ForestResponse response) {
String value = (String) getAttribute(request, "value");
String content = response.getContent();
ForestMethod<?> method = request.getMethod();
Class<?> returnClass = method.getReturnClass();
JSONObject responseData = JSON.parseObject(content, JSONObject.class);
if (StrUtil.isNotBlank(responseData.getString("errcode"))) {
data = BeanUtil.copyProperties(responseData, returnClass);
} else {
String encrypt = responseData.getString("encrypt");
String bodyJson = DecryptUtils.decode(value, encrypt);
data = BeanUtil.copyProperties(JSONObject.parseObject(bodyJson), returnClass);
}
response.setResult(data);
}
}
\ No newline at end of file
package com.topdraw.dockingapi.config;
import com.alibaba.fastjson.JSON;
import com.dtflys.forest.annotation.MethodLifeCycle;
import com.dtflys.forest.annotation.RequestAttributes;
import com.dtflys.forest.http.ForestBody;
import com.dtflys.forest.http.ForestRequest;
import com.dtflys.forest.lifecycles.MethodAnnotationLifeCycle;
import com.dtflys.forest.reflection.ForestMethod;
import com.topdraw.dockingapi.entity.EncryptEntity;
import com.topdraw.dockingapi.util.DecryptUtils;
import lombok.SneakyThrows;
import java.lang.annotation.*;
import java.lang.reflect.Parameter;
/**
* 用Forest自定义注解实现一个自定义的签名加密注解
......@@ -21,7 +12,7 @@ import java.lang.reflect.Parameter;
* 可以将此注解用在接口类和方法上
*/
@Documented
@MethodLifeCycle(Encode.EncodeLifeCycle.class)
@MethodLifeCycle(EncodeLifeCycle.class)
@RequestAttributes
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
......@@ -30,42 +21,5 @@ public @interface Encode {
String value() default "";
class EncodeLifeCycle implements MethodAnnotationLifeCycle<Encode, Object> {
/**
* 当方法调用时调用此方法,此时还没有执行请求发送
* 此方法可以获得请求对应的方法调用信息,以及动态传入的方法调用参数列表
*/
@SneakyThrows
@Override
public void onInvokeMethod(ForestRequest request, ForestMethod method, Object[] args) {
String value = (String) getAttribute(request, "value");
for (Object arg : args) {
Parameter[] parameters = method.getMethod().getParameters();
for (int i = 0; i < parameters.length; i++) {
Encode annotation = parameters[i].getAnnotation(Encode.class);
if (annotation != null) {
Object body = args[i];
String jsonString = JSON.toJSONString(body);
String encode = DecryptUtils.encode(value, jsonString);
EncryptEntity encodeBody = new EncryptEntity(encode);
ForestBody forestBody = request.getBody();
//替换body
forestBody.clear();
request.addBody(encodeBody);
}
}
}
}
@Override
public void onMethodInitialized(ForestMethod method, Encode annotation) {
}
}
}
......
package com.topdraw.dockingapi.config;
import com.dtflys.forest.annotation.Body;
import java.lang.annotation.*;
/**
* @author wenxin
* @version 1.0
* @date 2024/5/28 下午2:58
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.TYPE})
// 被组合的注解
@Body
public @interface EncodeBody {
}
package com.topdraw.dockingapi.config;
import com.alibaba.fastjson.JSON;
import com.dtflys.forest.http.ForestBody;
import com.dtflys.forest.http.ForestRequest;
import com.dtflys.forest.lifecycles.MethodAnnotationLifeCycle;
import com.dtflys.forest.reflection.ForestMethod;
import com.topdraw.dockingapi.entity.EncryptEntity;
import com.topdraw.dockingapi.util.DecryptUtils;
import lombok.SneakyThrows;
import java.lang.reflect.Parameter;
/**
* @author wenxin
* @version 1.0
* @date 2024/5/28 下午2:46
*/
public class EncodeLifeCycle implements MethodAnnotationLifeCycle<Encode, Object> {
/**
* 当方法调用时调用此方法,此时还没有执行请求发送
* 此方法可以获得请求对应的方法调用信息,以及动态传入的方法调用参数列表
*/
@SneakyThrows
@Override
public void onInvokeMethod(ForestRequest request, ForestMethod method, Object[] args) {
String value = (String) getAttribute(request, "value");
Parameter[] parameters = method.getMethod().getParameters();
for (int i = 0; i < parameters.length; i++) {
EncodeBody annotation = parameters[i].getAnnotation(EncodeBody.class);
if (annotation != null) {
Object body = args[i];
String jsonString = JSON.toJSONString(body);
String encode = DecryptUtils.encode(value, jsonString);
EncryptEntity encodeBody = new EncryptEntity(encode);
ForestBody forestBody = request.getBody();
//替换body
forestBody.clear();
request.addBody(encodeBody);
}
}
}
@Override
public void onMethodInitialized(ForestMethod method, Encode annotation) {
}
}
package com.topdraw.dockingapi.controller;
import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.digital.szzz.gateway.sdk.api.GatewaySender;
......@@ -8,11 +9,11 @@ import com.digital.szzz.gateway.sdk.bean.GatewayResponse;
import com.topdraw.dockingapi.config.EnvConfiguration;
import com.topdraw.dockingapi.entity.DecodeBody;
import com.topdraw.dockingapi.http.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
......@@ -27,20 +28,22 @@ import java.util.Optional;
@RestController
@Slf4j
@RequestMapping("/api")
@RequiredArgsConstructor
@CrossOrigin
public class ApiController {
private final EnvConfiguration configuration;
private final UserService userService;
@Resource
EnvConfiguration configuration;
@Resource
private
UserService userService;
String url;
String appId;
String iv;
String appKey;
String appSecretKey;
int readTimeout = 1000;
int connTimeout = 1000;
int readTimeout = 5000;
int connTimeout = 5000;
@PostConstruct
public void init() {
......@@ -90,6 +93,27 @@ public class ApiController {
readTimeout, connTimeout);
}
private String getPhone(String authCode) {
String method = "app.ykb.uc.oauth.userInfo";
JSONObject param = new JSONObject();
param.put("authCode", authCode);
Map<String, String> headerMap = new HashMap<>();
GatewayResponse send = GatewaySender.send(url, appId, method,
iv, appKey, appSecretKey, param, authCode,
headerMap, readTimeout, connTimeout);
log.info("获取手机号返回的结果是:{}", JSONArray.toJSONString(send));
String data = send.getData();
return Optional.ofNullable(JSONObject.parseObject(data, JSONObject.class))
.map(t -> t.getJSONObject("data"))
.map(t -> t.getJSONObject("userInfo"))
.map(t -> t.getString("phone"))
.filter(StrUtil::isNotBlank)
.orElseThrow(() -> new RuntimeException("获取手机号失败"));
}
/**
* 获取用户脱敏信息
*
......@@ -99,20 +123,15 @@ public class ApiController {
@PostMapping("/user/info")
public DecodeBody<Object> getUserInfoByAuthCode(@RequestBody JSONObject data) {
//通过authCode获取用户手机号
JSONObject userInfoByAuthCode = userService.getUserInfoByAuthCode(data);
String phone = Optional.ofNullable(userInfoByAuthCode)
.map(t -> t.getJSONObject("data"))
.map(t -> t.getJSONObject("userInfo"))
.map(t -> t.getString("phone"))
.orElseThrow(() -> new RuntimeException("获取用户信息失败"));
String phone = getPhone(data.getString("authCode"));
//判断手机号是否已经注册
DecodeBody<JSONObject> register = userService.checkIsRegisterByPhoneNum(MapBuilder.<String, String>create()
.put("phone", phone).build());
.put("phoneNum", phone).build());
String isRegister = register.getData().getString("isRegister");
if ("0".equals(isRegister)) {
//注册用户
DecodeBody<Object> body = userService.privateRegister(MapBuilder.<String, String>create()
.put("phone", phone)
.put("phoneNum", phone)
.put("token", "")
.build());
String errcode = body.getErrcode();
......@@ -123,7 +142,7 @@ public class ApiController {
}
//获取用户信息
return userService.privateLogin(MapBuilder.<String, String>create()
.put("phone", phone)
.put("phoneNum", phone)
.put("token", "").build());
}
}
......
......@@ -2,10 +2,10 @@ package com.topdraw.dockingapi.http;
import com.alibaba.fastjson.JSONObject;
import com.dtflys.forest.annotation.BaseRequest;
import com.dtflys.forest.annotation.Body;
import com.dtflys.forest.annotation.Post;
import com.topdraw.dockingapi.config.Decode;
import com.topdraw.dockingapi.config.Encode;
import com.topdraw.dockingapi.config.EncodeBody;
import com.topdraw.dockingapi.entity.DecodeBody;
import java.util.Map;
......@@ -19,8 +19,7 @@ import java.util.Map;
baseURL = "{baseUrl}", // 默认域名
headers = {
"Content-Type:application/json" // 默认请求头
},
sslProtocol = "TLS" // 默认单向SSL协议
}
)
public interface UserService {
/**
......@@ -36,7 +35,7 @@ public interface UserService {
@Post("/cpc-ms-service-user/user/yk/checkIsRegisterByPhoneNum")
@Encode("${key}")
@Decode("${key}")
DecodeBody<JSONObject> checkIsRegisterByPhoneNum(@Body @Encode Map<String,?> body);
DecodeBody<JSONObject> checkIsRegisterByPhoneNum(@EncodeBody Map<String, ?> body);
/**
* 用户注册
......@@ -52,7 +51,7 @@ public interface UserService {
@Post("/cpc-ms-service-user/user/yk/privateRegister")
@Encode("${key}")
@Decode("${key}")
DecodeBody<Object> privateRegister(@Body @Encode Map<String,?> body);
DecodeBody<Object> privateRegister(@EncodeBody Map<String, ?> body);
/**
* 用户登录获取用户信息
......@@ -68,17 +67,7 @@ public interface UserService {
@Post("/cpc-ms-service-user/login/yk/privateLogin")
@Encode("${key}")
@Decode("${key}")
DecodeBody<Object> privateLogin(@Body @Encode Map<String,?> body);
/**
* 获取用户手机号码
*
* @param body authCode
* @return 手机号
*/
@Post("/cpc-ms-service-user/user/yk/getUserInfoByAuthCode")
JSONObject getUserInfoByAuthCode(@Body JSONObject body);
DecodeBody<Object> privateLogin(@EncodeBody Map<String, ?> body);
}
......
# 指定启动的时候springboot的激活环境
spring.profiles.active=test
# Forest配置
# 后端HTTP框架(默认为 okhttp3)
forest.backend=okhttp3
# 连接池最大连接数(默认为 500)
forest.max-connections=1000
# 每个路由的最大连接数(默认为 500)
forest.max-route-connections=500
# 最大请求等待队列大小
forest.max-request-queue-size=100
# 最大异步线程数
forest.max-async-thread-size=300
# 最大异步线程池队列大小
forest.max-async-queue-size=16
# 连接超时时间,单位为毫秒(默认为 timeout)
forest.connect-timeout=30000
# 数据读取超时时间,单位为毫秒(默认为 timeout)
forest.read-timeout=30000
# 请求失败后重试次数(默认为 0 次不重试)
forest.max-retry-count=1
# 单向验证的HTTPS的默认TLS协议(默认为 TLS)
forest.ssl-protocol=TLS
# 打开或关闭日志(默认为 true)
forest.log-enabled=true
# 打开/关闭Forest请求日志(默认为 true)
forest.log-request=true
# 打开/关闭Forest响应状态日志(默认为 true)
forest.log-response-status=true
# 打开/关闭Forest响应内容日志(默认为 false)
forest.log-response-content=true
# 用户信息接口URL
forest.variables.userInfoUrl=https://cpcapi.cbg.cn
......
......@@ -5,10 +5,9 @@ forest:
max-request-queue-size: 100 # [自v1.5.22版本起可用] 最大请求等待队列大小
max-async-thread-size: 300 # [自v1.5.21版本起可用] 最大异步线程数
max-async-queue-size: 16 # [自v1.5.22版本起可用] 最大异步线程池队列大小
timeout: 3000 # [已不推荐使用] 请求超时时间,单位为毫秒(默认为 3000)
connect-timeout: 3000 # 连接超时时间,单位为毫秒(默认为 timeout)
read-timeout: 3000 # 数据读取超时时间,单位为毫秒(默认为 timeout)
max-retry-count: 0 # 请求失败后重试次数(默认为 0 次不重试)
connect-timeout: 30000 # 连接超时时间,单位为毫秒(默认为 timeout)
read-timeout: 30000 # 数据读取超时时间,单位为毫秒(默认为 timeout)
max-retry-count: 1 # 请求失败后重试次数(默认为 0 次不重试)
ssl-protocol: TLS # 单向验证的HTTPS的默认TLS协议(默认为 TLS)
log-enabled: true # 打开或关闭日志(默认为 true)
log-request: true # 打开/关闭Forest请求日志(默认为 true)
......
......@@ -25,7 +25,7 @@ public class ApiTest {
// 密钥
byte[] keyBytes = "wmsj2021".getBytes(StandardCharsets.UTF_8); // DES密钥长度为8字节
// 需要加密的数据
String text = "{\"phoneNum\":\"15983678047\"}";
String text = "{\"phoneNum\":\"13627618074\"}";
byte[] data = text.getBytes(StandardCharsets.UTF_8);
// 创建密钥
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "DES");
......@@ -53,7 +53,7 @@ public class ApiTest {
@SneakyThrows
@Test
public void testEncode(){
String text = "{\"phoneNum\":\"15983678047\"}";
String text = "{\"phoneNum\":\"13627618074\"}";
System.out.println(DecryptUtils.encode("wmsj2021", text));
String tt="U0ELEkckqqxwzutWXbySgJmGbWQovd9n7UZSWqYt5HpXOxOsQwTnrjGp7geAhD/Mp9Jy3okXkRtt0cuFDdlMjPDgsBK3SMu0";
System.out.println(DecryptUtils.decode("wmsj2021", tt));
......
package com.topdraw.dockingapi;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.digital.szzz.gateway.sdk.bean.GatewayResponse;
import com.topdraw.dockingapi.controller.ApiController;
import com.topdraw.dockingapi.entity.DecodeBody;
import com.topdraw.dockingapi.http.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
......@@ -12,6 +16,8 @@ class DockingApiApplicationTests {
@Resource
private UserService userService;
@Resource
private ApiController apiController;
@Test
void contextLoads() {
......@@ -20,4 +26,21 @@ class DockingApiApplicationTests {
System.out.println(userService.checkIsRegisterByPhoneNum(param));
}
@Test
void testApi() {
JSONObject param = new JSONObject();
param.put("userId","8798981653125");
GatewayResponse authCodeByUserId = apiController.getAuthCodeByUserId(param);
String data = authCodeByUserId.getData();
JSONObject j = JSON.parseObject(data, JSONObject.class);
String string = j.getJSONObject("data")
.getString("authCode");
JSONObject p = new JSONObject();
p.put("authCode",string);
DecodeBody<Object> userInfoByAuthCode = apiController.getUserInfoByAuthCode(p);
System.out.println("----------------------------------------------------");
System.out.println(JSON.toJSONString(userInfoByAuthCode));
}
}
......