| @@ -5,10 +5,39 @@ import com.nsgk.agentcentersdk.api.NSSDK; | |||
| import com.nsgk.agentcentersdk.api.NSSDKClient; | |||
| import com.nsgk.agentcentersdk.core.NSProtocol; | |||
| import com.nsgk.agentcentersdk.entity.NSContractionEntity; | |||
| import com.nsgk.agentcentersdk.utility.NSReflect; | |||
| public final class NSMain | |||
| { | |||
| public static void main(String[] args) | |||
| public static void main(String[] args) throws Exception | |||
| { | |||
| //Test(); | |||
| Test_reflect(); | |||
| } | |||
| public static void Test_reflect() throws InstantiationException, IllegalAccessException | |||
| { | |||
| Class<?> NSContractionEntity_class = NSReflect.Class("com.nsgk.agentcentersdk.entity.NSContractionEntity"); | |||
| Class<?> NSSDK_class = NSReflect.Class("com.nsgk.agentcentersdk.api.NSSDK"); | |||
| Object client; | |||
| Object entity; | |||
| Object result; | |||
| NSReflect.CallStatic_s(NSSDK_class, "InitClient", String.class, "http://localhost", short.class, (short) 8081, String.class, "test", String.class, "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=="); | |||
| client = NSReflect.CallStatic(NSSDK_class, "InstanceClient"); | |||
| entity = NSContractionEntity_class.newInstance(); | |||
| NSReflect.Call(entity, "setBuildingTime", "2000-12-23"); | |||
| NSReflect.Call(entity, "setName", "测试合同"); | |||
| NSReflect.Call(entity, "setDeptId", 187L); | |||
| NSReflect.Call(entity, "setBookId", 166L); | |||
| NSReflect.Call(entity, "setOutId", 250L); | |||
| result = NSReflect.Call_s(client, "Send", int.class, NSProtocol.NS_PROTOCOL_CONTRACTION, NSReflect.Class("com.nsgk.agentcentersdk.entity.NSEntityBase"), entity); | |||
| System.err.println(result); | |||
| } | |||
| public static void Test() | |||
| { | |||
| NSSDKClient client; | |||
| NSContractionEntity entity; | |||
| @@ -19,9 +48,10 @@ public final class NSMain | |||
| entity = new NSContractionEntity(); | |||
| entity.setBuildingTime("2000-12-23") | |||
| .setName("测试合同") | |||
| .setDeptId(187L) | |||
| .setBookId(166L) | |||
| .setName("测试合同") | |||
| .setDeptId(187L) | |||
| .setBookId(166L) | |||
| .setOutId(999L) | |||
| ; | |||
| result = client.Send(NSProtocol.NS_PROTOCOL_CONTRACTION, entity); | |||
| System.err.println(result); | |||
| @@ -2,22 +2,49 @@ package com.nsgk.agentcentersdk.api; | |||
| import com.alibaba.fastjson2.JSON; | |||
| import com.alibaba.fastjson2.JSONObject; | |||
| import com.nsgk.agentcentersdk.err.NSErrno; | |||
| import lombok.Data; | |||
| // 服务端返回对象 | |||
| @Data | |||
| public class NSApiResult | |||
| public final class NSApiResult | |||
| { | |||
| public static final int NS_RESULT_SUCCESS = 200; | |||
| public static final int NS_RESULT_ERROR = 500; | |||
| public final int code; | |||
| public final String msg; | |||
| public final Object data; | |||
| public final long timestamp = System.currentTimeMillis(); | |||
| public final Long timestamp; | |||
| public final int errno; | |||
| NSApiResult(int code, String msg, Object data) | |||
| { | |||
| this(code, msg, data, NSErrno.ERRNO_OK); | |||
| } | |||
| NSApiResult(int code, String msg, Object data, int errno) | |||
| { | |||
| this(code, msg, data, System.currentTimeMillis(), errno); | |||
| } | |||
| NSApiResult(int code, String msg, Object data, Long timestamp, int errno) | |||
| { | |||
| this.code = code; | |||
| this.msg = msg; | |||
| this.data = data; | |||
| this.timestamp = timestamp; | |||
| this.errno = errno; | |||
| } | |||
| static NSApiResult Success(String msg, Object data) | |||
| { | |||
| return new NSApiResult(NS_RESULT_SUCCESS, msg, data); | |||
| } | |||
| static NSApiResult Error(int errno, String msg, Object data) | |||
| { | |||
| return new NSApiResult(NS_RESULT_ERROR, msg, data, errno); | |||
| } | |||
| static NSApiResult FromJSON(String str) | |||
| @@ -25,6 +52,12 @@ public class NSApiResult | |||
| JSONObject jsonObject; | |||
| jsonObject = JSON.parseObject(str); | |||
| return new NSApiResult(jsonObject.getInteger("code"), jsonObject.getString("msg"), jsonObject.get("data")); | |||
| return new NSApiResult( | |||
| jsonObject.getInteger("code"), | |||
| jsonObject.getString("msg"), | |||
| jsonObject.containsKey("data") ? jsonObject.get("data") : null, | |||
| jsonObject.containsKey("data") ? jsonObject.getLong("timestamp") : null, | |||
| jsonObject.containsKey("errno") ? jsonObject.getInteger("errno") : null | |||
| ); | |||
| } | |||
| } | |||
| @@ -1,11 +1,19 @@ | |||
| package com.nsgk.agentcentersdk.api; | |||
| import cn.hutool.core.util.URLUtil; | |||
| import com.nsgk.agentcentersdk.core.NSProtocol; | |||
| import com.nsgk.agentcentersdk.core.NSReportObject; | |||
| import com.nsgk.agentcentersdk.entity.NSEntityBase; | |||
| import com.nsgk.agentcentersdk.err.NSAssert; | |||
| import com.nsgk.agentcentersdk.err.NSErrGlobal; | |||
| import com.nsgk.agentcentersdk.err.NSErrno; | |||
| import com.nsgk.agentcentersdk.network.NSNetworkManager; | |||
| import com.nsgk.agentcentersdk.network.NSNetworkRequest; | |||
| import com.nsgk.agentcentersdk.network.NSNetworkResponse; | |||
| import com.nsgk.agentcentersdk.utility.NSCrypto; | |||
| import com.nsgk.agentcentersdk.utility.NSStr; | |||
| import java.util.Objects; | |||
| // SDK客户端 | |||
| /* | |||
| @@ -42,12 +50,16 @@ public final class NSSDKClient | |||
| NSReportObject<T> reportObject; | |||
| NSNetworkRequest request; | |||
| NSAssert.NotNull(object, NSErrno.ERRNO_CLI_DATA_MISSING); | |||
| NSAssert.NotEmpty(identifier, NSErrno.ERRNO_CLI_PARAMETER_MISSING); | |||
| NSErrGlobal.ASSERT(NSProtocol.IsValid(protocol), NSErrno.ERRNO_SYS_INVALID_PROTOCOL); | |||
| url = NSApi.NS_API_REPORT; | |||
| reportObject = new NSReportObject<>(identifier, protocol, object); | |||
| request = new NSNetworkRequest(); | |||
| request.setUrl(BuildUrl(url)); | |||
| request.WriteDataObject(reportObject, publicKey); | |||
| WriteDataObject(request, reportObject); | |||
| NSNetworkResponse response = NSNetworkManager.Post(request); | |||
| NSErrGlobal.ASSERT(response.IsSuccess(), NSErrno.ERRNO_SYS_HTTP); | |||
| String json = response.getData(); | |||
| return NSApiResult.FromJSON(json); | |||
| } | |||
| @@ -56,4 +68,28 @@ public final class NSSDKClient | |||
| { | |||
| return URLUtil.completeUrl(host + ":" + port, url); | |||
| } | |||
| private <T> void WriteDataObject(NSNetworkRequest request, NSReportObject<T> object) | |||
| { | |||
| String dataStr; | |||
| request.ClearHeaders().AddHeader("sign", object.getSign()); | |||
| request.ClearQueries().AddQuery("identifier", object.getIdentifier()) | |||
| .AddQuery("protocol", object.getProtocol()) | |||
| .AddQuery("timestamp", object.getTimestamp()) | |||
| ; | |||
| dataStr = object.getDataStr(); | |||
| try | |||
| { | |||
| dataStr = NSCrypto.RSAEncrypt(dataStr, publicKey); | |||
| NSAssert.NotEmpty(dataStr, NSErrno.ERRNO_SYS_ENCRYPT_FAIL); | |||
| } | |||
| catch(Exception e) | |||
| { | |||
| e.printStackTrace(); | |||
| NSErrGlobal.Throw(NSErrno.ERRNO_SYS_ENCRYPT_FAIL); | |||
| return; | |||
| } | |||
| request.setData(dataStr); | |||
| } | |||
| } | |||
| @@ -2,12 +2,14 @@ package com.nsgk.agentcentersdk.api; | |||
| import com.nsgk.agentcentersdk.core.NSReportObject; | |||
| import com.nsgk.agentcentersdk.entity.NSEntityBase; | |||
| import com.nsgk.agentcentersdk.err.NSAssert; | |||
| import com.nsgk.agentcentersdk.err.NSErrGlobal; | |||
| import com.nsgk.agentcentersdk.err.NSErrno; | |||
| import com.nsgk.agentcentersdk.utility.NSArr; | |||
| import com.nsgk.agentcentersdk.utility.NSCrypto; | |||
| import com.nsgk.agentcentersdk.utility.NSHttp; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import java.util.Map; | |||
| // SDK服务端 | |||
| public final class NSSDKServer | |||
| @@ -27,24 +29,47 @@ public final class NSSDKServer | |||
| String data; | |||
| sign = request.getHeader("sign"); | |||
| NSAssert.NotEmpty(sign, NSErrno.ERRNO_CLI_SIGN_MISSING); | |||
| data = NSHttp.GetRequestBody(request); | |||
| NSAssert.NotEmpty(data, NSErrno.ERRNO_CLI_DATA_MISSING); | |||
| res = new NSReportObject<>(); | |||
| res.SetTimestampStr(request.getParameter("timestamp")) | |||
| .setIdentifier(request.getParameter("identifier")) | |||
| .SetProtocolStr(request.getParameter("protocol")) | |||
| .SetDataStr(NSCrypto.RSADecrypt(data, privateKey), clazz) | |||
| ; | |||
| try | |||
| { | |||
| data = NSCrypto.RSADecrypt(data, privateKey); | |||
| NSAssert.NotEmpty(data, NSErrno.ERRNO_SYS_DECRYPT_FAIL); | |||
| res.SetDataStr(data, clazz); | |||
| } | |||
| catch(Exception e) | |||
| { | |||
| e.printStackTrace(); | |||
| return NSErrGlobal.ThrowAndReturnNull(NSErrno.ERRNO_SYS_DECRYPT_FAIL); | |||
| } | |||
| if(!res.CheckSign(sign)) | |||
| { | |||
| return null; | |||
| return NSErrGlobal.ThrowAndReturn(NSErrno.ERRNO_SYS_INVALID_SIGN, null); | |||
| } | |||
| res.setSign(sign); | |||
| return res; | |||
| } | |||
| // 响应客户端 | |||
| public NSApiResult Resp(int code, String msg, Object...data) | |||
| public static NSApiResult Resp(int code, String msg, Object...data) | |||
| { | |||
| return new NSApiResult(code, msg, NSArr.DefParms(data)); | |||
| return new NSApiResult(code, msg, NSArr.DefParm(data)); | |||
| } | |||
| public static NSApiResult Success(String msg, Object...data) | |||
| { | |||
| return NSApiResult.Success(msg, NSArr.DefParm(data)); | |||
| } | |||
| public static NSApiResult Fail(int errno, String msg, Object...data) | |||
| { | |||
| return NSApiResult.Error(errno, msg, NSArr.DefParm(data)); | |||
| } | |||
| } | |||
| @@ -13,5 +13,10 @@ public final class NSProtocol | |||
| return Math.abs(i); | |||
| } | |||
| public static boolean IsValid(int protocol) | |||
| { | |||
| return protocol > 0; // TODO: full check | |||
| } | |||
| private NSProtocol() {} | |||
| } | |||
| @@ -2,6 +2,8 @@ package com.nsgk.agentcentersdk.core; | |||
| import cn.hutool.core.bean.BeanUtil; | |||
| import com.alibaba.fastjson2.JSON; | |||
| import com.nsgk.agentcentersdk.err.NSErrGlobal; | |||
| import com.nsgk.agentcentersdk.err.NSErrno; | |||
| import com.nsgk.agentcentersdk.utility.NSSignTool; | |||
| import com.nsgk.agentcentersdk.utility.NSStr; | |||
| import lombok.Data; | |||
| @@ -14,11 +16,12 @@ import java.util.Map; | |||
| @Accessors(chain = true) | |||
| public class NSReportObject<T> | |||
| { | |||
| protected static final String[] SIGN_FIELDS = { | |||
| "identifier", "protocol", "timestamp", "dataLength", | |||
| protected static final String[] SIGN_FIELDS = { // 字母顺序 | |||
| "identifier", "protocol", "timestamp", "length", | |||
| }; | |||
| private String identifier; // 识别ID | |||
| private String sign; // 签名 | |||
| // md5(identifier=<客户端身份标识ID>&length=<data长度(加密前明文)>&protocol=<协议>×tamp=<毫秒时间戳>) | |||
| private int protocol = NSProtocol.NS_PROTOCOL_INVALID; // 协议 | |||
| private Long timestamp; // 客户端时间戳 | |||
| private T data; | |||
| @@ -60,16 +63,26 @@ public class NSReportObject<T> | |||
| public boolean IsValid() | |||
| { | |||
| return NSStr.IsNotEmpty(identifier) && null != timestamp && protocol > 0; | |||
| return NSStr.IsNotEmpty(identifier) && null != timestamp && timestamp > 0 && NSProtocol.IsValid(protocol); | |||
| } | |||
| //"d10457fb8d1ae32b27f9eb9c0a107c75" | |||
| public String Sign() | |||
| { | |||
| Map<String, Object> map; | |||
| map = BeanUtil.beanToMap(this); | |||
| map.put("dataLength", NSStr.Length(dataStr)); | |||
| return NSSignTool.Sign(map, SIGN_FIELDS); | |||
| NSErrGlobal.ASSERT(IsValid(), NSErrno.ERRNO_CLI_PARAMETER_MISSING); | |||
| try | |||
| { | |||
| map = BeanUtil.beanToMap(this); | |||
| map.put("length", NSStr.Length(dataStr)); | |||
| return NSSignTool.Sign(map, SIGN_FIELDS); | |||
| } | |||
| catch(Exception e) | |||
| { | |||
| e.printStackTrace(); | |||
| return NSErrGlobal.ThrowAndReturnNull(NSErrno.ERRNO_SYS_INVALID_SIGN); | |||
| } | |||
| } | |||
| public boolean CheckSign(String src) | |||
| @@ -1,9 +1,12 @@ | |||
| package com.nsgk.agentcentersdk.entity; | |||
| import com.nsgk.agentcentersdk.utility.NSArr; | |||
| import lombok.Data; | |||
| import lombok.experimental.Accessors; | |||
| import java.io.Serializable; | |||
| import java.util.LinkedHashMap; | |||
| import java.util.Map; | |||
| // 基本实体 | |||
| @Data | |||
| @@ -19,5 +22,47 @@ public abstract class NSEntityBase implements Serializable | |||
| protected Long deptId; | |||
| /** 外部ID */ | |||
| private Long outId; | |||
| protected Long outId; | |||
| protected Map<String, Object> parms; | |||
| protected Map<String, Object> PARMS() | |||
| { | |||
| if(null == parms) | |||
| parms = new LinkedHashMap<>(); | |||
| return parms; | |||
| } | |||
| @SuppressWarnings("unchecked") | |||
| public <T extends NSEntityBase> T Parm(String name, Object val) | |||
| { | |||
| PARMS().put(name, val); | |||
| return (T)this; | |||
| } | |||
| @SuppressWarnings("unchecked") | |||
| public <T extends NSEntityBase> T DelParm(String...name) | |||
| { | |||
| if(null != parms && NSArr.IsNotEmpty(name)) | |||
| { | |||
| NSArr.Stream(name).forEach(parms::remove); | |||
| } | |||
| return (T)this; | |||
| } | |||
| public boolean HasParm(String name) | |||
| { | |||
| if(null == parms) | |||
| return false; | |||
| return parms.containsKey(name); | |||
| } | |||
| @SuppressWarnings("unchecked") | |||
| public <T> T ParmT(String name, T...val) | |||
| { | |||
| T def = NSArr.DefParm(val); | |||
| if(null == parms) | |||
| return def; | |||
| return (T)parms.getOrDefault(name, def); | |||
| } | |||
| } | |||
| @@ -0,0 +1,28 @@ | |||
| package com.nsgk.agentcentersdk.err; | |||
| import cn.hutool.core.collection.CollectionUtil; | |||
| import com.nsgk.agentcentersdk.utility.NSStr; | |||
| import java.util.Collection; | |||
| import java.util.Objects; | |||
| // 断言 | |||
| public final class NSAssert | |||
| { | |||
| public static void NotNull(Object obj, Integer...err) | |||
| { | |||
| NSErrGlobal.ASSERT(Objects.nonNull(obj), err); | |||
| } | |||
| public static void NotEmpty(String obj, Integer...err) | |||
| { | |||
| NSErrGlobal.ASSERT(NSStr.IsNotEmpty(obj), err); | |||
| } | |||
| public static void NotEmpty(Collection<?> obj, Integer...err) | |||
| { | |||
| NSErrGlobal.ASSERT(CollectionUtil.isNotEmpty(obj), err); | |||
| } | |||
| private NSAssert() {} | |||
| } | |||
| @@ -0,0 +1,98 @@ | |||
| package com.nsgk.agentcentersdk.err; | |||
| import com.nsgk.agentcentersdk.utility.NSArr; | |||
| import java.io.Serializable; | |||
| // 全局错误记录 | |||
| public final class NSErrGlobal | |||
| { | |||
| private static final ThreadLocal<Integer> errno = new ThreadLocal<>(); | |||
| public static int Err(int newErr) | |||
| { | |||
| int err; | |||
| err = errno.get(); | |||
| errno.set(newErr); | |||
| return err; | |||
| } | |||
| public static void Throw(int err) | |||
| { | |||
| if(err == NSErrno.ERRNO_OK) | |||
| return; | |||
| throw new NSException(err); | |||
| } | |||
| public static void Throw() | |||
| { | |||
| Throw(Errno()); | |||
| } | |||
| public static <T> T ThrowAndReturnNull(int err) | |||
| { | |||
| return ThrowAndReturn(err, null); | |||
| } | |||
| public static <T> T ThrowAndReturnNull() | |||
| { | |||
| return ThrowAndReturn(null); | |||
| } | |||
| public static <T> T ThrowAndReturn(int err, T t) | |||
| { | |||
| if(err == NSErrno.ERRNO_OK) | |||
| return t; | |||
| throw new NSException(err); | |||
| } | |||
| public static <T> T ThrowAndReturn(T t) | |||
| { | |||
| return ThrowAndReturn(Errno(), t); | |||
| } | |||
| public static <T> T Return(int err, T t) | |||
| { | |||
| if(err != NSErrno.ERRNO_OK) | |||
| Err(err); | |||
| return t; | |||
| } | |||
| public static <T> T Return(T t) | |||
| { | |||
| return Return(Errno(), t); | |||
| } | |||
| // 默认清除 | |||
| public static int Errno(boolean...clear) | |||
| { | |||
| int err; | |||
| err = errno.get(); | |||
| if(null == clear || clear.length == 0 || clear[0]) | |||
| errno.set(NSErrno.ERRNO_OK); | |||
| return err; | |||
| } | |||
| public static boolean HasError(boolean...clear) | |||
| { | |||
| return Errno(clear) != NSErrno.ERRNO_OK; | |||
| } | |||
| public static String Error(boolean...clear) | |||
| { | |||
| return NSErrno.ErrStr(Errno(clear)); | |||
| } | |||
| public static void ASSERT(boolean expression, Integer...err) | |||
| { | |||
| int e; | |||
| e = NSArr.GetParm(NSErrno.ERRNO_ERROR, err); | |||
| if(!expression) | |||
| Throw(e); | |||
| } | |||
| private NSErrGlobal() {} | |||
| } | |||
| @@ -0,0 +1,43 @@ | |||
| package com.nsgk.agentcentersdk.err; | |||
| // 错误码 | |||
| public final class NSErrno | |||
| { | |||
| public static final int ERRNO_OK = 0; | |||
| public static final int ERRNO_ERROR = 0x00001; | |||
| public static final int ERRNO_SYS_INVALID_SIGN = 0x01001; | |||
| public static final int ERRNO_SYS_ENCRYPT_FAIL = 0x01002; | |||
| public static final int ERRNO_SYS_DECRYPT_FAIL = 0x01003; | |||
| public static final int ERRNO_SYS_INVALID_PROTOCOL = 0x01004; | |||
| public static final int ERRNO_SYS_SIGN_FAIL = 0x01005; | |||
| public static final int ERRNO_SYS_HTTP = 0x01006; | |||
| public static final int ERRNO_CLI_PARAMETER_MISSING = 0x03001; | |||
| public static final int ERRNO_CLI_DATA_MISSING = 0x03002; | |||
| public static final int ERRNO_CLI_SIGN_MISSING = 0x03003; | |||
| public static final int ERRNO_SRV_HTTP = 0x04001; | |||
| private NSErrno() {} | |||
| public static String ErrStr(int errno) | |||
| { | |||
| switch(errno) | |||
| { | |||
| case ERRNO_SYS_INVALID_SIGN: return "签名无效"; | |||
| case ERRNO_SYS_ENCRYPT_FAIL: return "加密失败"; | |||
| case ERRNO_SYS_DECRYPT_FAIL: return "解密失败"; | |||
| case ERRNO_SYS_INVALID_PROTOCOL: return "无效协议"; | |||
| case ERRNO_SYS_SIGN_FAIL: return "签名失败"; | |||
| case ERRNO_SYS_HTTP: return "Http请求错误"; | |||
| case ERRNO_CLI_PARAMETER_MISSING: return "参数缺失"; | |||
| case ERRNO_CLI_DATA_MISSING: return "数据缺失"; | |||
| case ERRNO_CLI_SIGN_MISSING: return "签名缺失"; | |||
| case ERRNO_ERROR: default: return "错误"; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| package com.nsgk.agentcentersdk.err; | |||
| import lombok.Data; | |||
| @Data | |||
| public final class NSException extends RuntimeException | |||
| { | |||
| private final int errno; | |||
| public NSException(int errno) | |||
| { | |||
| super(NSErrno.ErrStr(errno)); | |||
| this.errno = errno; | |||
| } | |||
| public NSException(int errno, String error) | |||
| { | |||
| super(error); | |||
| this.errno = errno; | |||
| } | |||
| } | |||
| @@ -10,16 +10,4 @@ import lombok.experimental.Accessors; | |||
| @Accessors(chain = true) | |||
| public class NSNetworkRequest extends NSNetworkTransport | |||
| { | |||
| public <T> void WriteDataObject(NSReportObject<T> object, String publicKey) | |||
| { | |||
| String dataStr; | |||
| ClearHeaders().AddHeader("sign", object.getSign()); | |||
| ClearQueries().AddQuery("identifier", object.getIdentifier()) | |||
| .AddQuery("protocol", object.getProtocol()) | |||
| .AddQuery("timestamp", object.getTimestamp()) | |||
| ; | |||
| dataStr = object.getDataStr(); | |||
| setData(NSCrypto.RSAEncrypt(dataStr, publicKey)); | |||
| } | |||
| } | |||
| @@ -5,7 +5,6 @@ import com.nsgk.agentcentersdk.utility.NSStr; | |||
| import lombok.Data; | |||
| import lombok.experimental.Accessors; | |||
| import java.util.HashMap; | |||
| import java.util.LinkedHashMap; | |||
| import java.util.Map; | |||
| @@ -40,7 +39,7 @@ public class NSNetworkTransport | |||
| public String Header(String name, String...value) | |||
| { | |||
| return headers.getOrDefault(name, NSArr.DefParms(value)); | |||
| return headers.getOrDefault(name, NSArr.DefParm(value)); | |||
| } | |||
| public NSNetworkTransport ClearQueries() | |||
| @@ -57,6 +56,6 @@ public class NSNetworkTransport | |||
| public Object Query(String name, Object...value) | |||
| { | |||
| return query.getOrDefault(name, NSArr.DefParms(value)); | |||
| return query.getOrDefault(name, NSArr.DefParm(value)); | |||
| } | |||
| } | |||
| @@ -1,14 +1,39 @@ | |||
| package com.nsgk.agentcentersdk.utility; | |||
| import java.util.ArrayList; | |||
| import java.util.stream.Stream; | |||
| // 数组工具 | |||
| public final class NSArr | |||
| { | |||
| public static <T> T DefParms(T...args) | |||
| public static <T> T DefParm(T...args) | |||
| { | |||
| if(null == args || args.length == 0) | |||
| return null; | |||
| return args[0]; | |||
| } | |||
| public static <T> T GetParm(T def, T[] args) | |||
| { | |||
| if(null == args || args.length == 0) | |||
| return def; | |||
| return args[0]; | |||
| } | |||
| public static <T> boolean IsEmpty(T...args) | |||
| { | |||
| return(null == args || args.length == 0); | |||
| } | |||
| public static <T> boolean IsNotEmpty(T...args) | |||
| { | |||
| return !IsEmpty(args); | |||
| } | |||
| public static <T> Stream<T> Stream(T...args) | |||
| { | |||
| return IsEmpty(args) ? new ArrayList<T>().stream() : Stream.of(args); | |||
| } | |||
| private NSArr() {} | |||
| } | |||
| @@ -0,0 +1,144 @@ | |||
| package com.nsgk.agentcentersdk.utility; | |||
| import java.lang.reflect.Method; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| // 反射工具 | |||
| public final class NSReflect | |||
| { | |||
| public static Class<?> Class(String className) | |||
| { | |||
| try | |||
| { | |||
| return Class.forName(className); | |||
| } | |||
| catch(ClassNotFoundException e) | |||
| { | |||
| e.printStackTrace(); | |||
| throw new RuntimeException("SDK版本不匹配"); | |||
| } | |||
| } | |||
| @SuppressWarnings("unchecked") | |||
| public static <T> T CallStaticT(Class<?> classObject, String methodName, Object...args) | |||
| { | |||
| return (T)CallStatic(classObject, methodName, args); | |||
| } | |||
| @SuppressWarnings("unchecked") | |||
| public static <T> T CallStaticT_s(Class<?> classObject, String methodName, Object...args) | |||
| { | |||
| return (T)CallStatic_s(classObject, methodName, args); | |||
| } | |||
| public static Object CallStatic(Class<?> classObject, String methodName, Object...args) | |||
| { | |||
| if(null == args || args.length == 0) | |||
| return CallStatic_s(classObject, methodName); | |||
| Object[] objs = new Object[args.length * 2]; | |||
| for(int i = 0; i < args.length; i++) | |||
| { | |||
| objs[i * 2] = args[i].getClass(); | |||
| objs[i * 2 + 1] = args[i]; | |||
| } | |||
| return CallStatic_s(classObject, methodName, objs); | |||
| } | |||
| public static Object CallStatic_s(Class<?> classObject, String methodName, Object...args) | |||
| { | |||
| List<Class<?>> classes = new ArrayList<>(); | |||
| List<Object> params = new ArrayList<>(); | |||
| if(null != args && args.length > 0) | |||
| { | |||
| for(int i = 0; i < args.length; i += 2) | |||
| { | |||
| Class<?> clazz; | |||
| Object c = args[i]; | |||
| if(null != c) | |||
| clazz = (Class<?>) c; | |||
| else | |||
| clazz = args[i + 1].getClass(); | |||
| classes.add(clazz); | |||
| params.add(args[i + 1]); | |||
| } | |||
| } | |||
| try | |||
| { | |||
| Method method = classObject.getMethod(methodName, classes.toArray(new Class<?>[0])); | |||
| return method.invoke(null, params.toArray(new Object[0])); | |||
| } | |||
| catch(NoSuchMethodException | IllegalAccessException | IllegalArgumentException e) | |||
| { | |||
| e.printStackTrace(); | |||
| throw new RuntimeException("SDK版本不匹配"); | |||
| } | |||
| catch(Exception e) | |||
| { | |||
| e.printStackTrace(); | |||
| throw new RuntimeException(e); | |||
| } | |||
| } | |||
| @SuppressWarnings("unchecked") | |||
| public static <T> T CallT(Object object, String methodName, Object...args) | |||
| { | |||
| return (T)Call(object, methodName, args); | |||
| } | |||
| @SuppressWarnings("unchecked") | |||
| public static <T> T CallT_s(Object object, String methodName, Object...args) | |||
| { | |||
| return (T)Call_s(object, methodName, args); | |||
| } | |||
| public static Object Call(Object object, String methodName, Object...args) | |||
| { | |||
| if(null == args || args.length == 0) | |||
| return Call_s(object, methodName); | |||
| Object[] objs = new Object[args.length * 2]; | |||
| for(int i = 0; i < args.length; i++) | |||
| { | |||
| objs[i * 2] = args[i].getClass(); | |||
| objs[i * 2 + 1] = args[i]; | |||
| } | |||
| return Call_s(object, methodName, objs); | |||
| } | |||
| public static Object Call_s(Object object, String methodName, Object...args) | |||
| { | |||
| List<Class<?>> classes = new ArrayList<>(); | |||
| List<Object> params = new ArrayList<>(); | |||
| if(null != args && args.length > 0) | |||
| { | |||
| for(int i = 0; i < args.length; i += 2) | |||
| { | |||
| Class<?> clazz; | |||
| Object c = args[i]; | |||
| if(null != c) | |||
| clazz = (Class<?>) c; | |||
| else | |||
| clazz = args[i + 1].getClass(); | |||
| classes.add(clazz); | |||
| params.add(args[i + 1]); | |||
| } | |||
| } | |||
| try | |||
| { | |||
| Method method = object.getClass().getMethod(methodName, classes.toArray(new Class<?>[0])); | |||
| return method.invoke(object, params.toArray(new Object[0])); | |||
| } | |||
| catch(NoSuchMethodException | IllegalAccessException | IllegalArgumentException e) | |||
| { | |||
| e.printStackTrace(); | |||
| throw new RuntimeException("SDK版本不匹配"); | |||
| } | |||
| catch(Exception e) | |||
| { | |||
| e.printStackTrace(); | |||
| throw new RuntimeException(e); | |||
| } | |||
| } | |||
| private NSReflect() {} | |||
| } | |||
| @@ -24,7 +24,7 @@ public final class NSSignTool | |||
| fields = Arrays.stream(signFields).sorted(String::compareTo).collect(Collectors.toList()); | |||
| sb = new StringBuilder(); | |||
| for(int i = 0; i < fields.size(); i++) | |||
| {//dataLength=69&identifier=test&protocol=1×tamp=1683442648774 | |||
| { | |||
| if(i > 0) | |||
| sb.append("&"); | |||
| String key = fields.get(i); | |||
| @@ -3,10 +3,17 @@ package com.ruoyi.web.controller.agentcenter; | |||
| import com.nsgk.agentcentersdk.api.NSApiResult; | |||
| import com.nsgk.agentcentersdk.api.NSSDK; | |||
| import com.nsgk.agentcentersdk.api.NSSDKServer; | |||
| import com.nsgk.agentcentersdk.core.NSProtocol; | |||
| import com.nsgk.agentcentersdk.core.NSReportObject; | |||
| import com.nsgk.agentcentersdk.entity.NSContractionEntity; | |||
| import com.nsgk.agentcentersdk.err.NSErrGlobal; | |||
| import com.nsgk.agentcentersdk.err.NSErrno; | |||
| import com.nsgk.agentcentersdk.err.NSException; | |||
| import com.ruoyi.agentcenter.object.ContractionMessage; | |||
| import com.ruoyi.agentcenter.object.Message; | |||
| import com.ruoyi.common.config.RuoYiConfig; | |||
| import com.ruoyi.common.core.controller.BaseController; | |||
| import com.ruoyi.common.utils.EventBusEngine; | |||
| import org.springframework.web.bind.annotation.PostMapping; | |||
| import org.springframework.web.bind.annotation.RequestMapping; | |||
| import org.springframework.web.bind.annotation.RestController; | |||
| @@ -32,7 +39,7 @@ public class AgentCenterController extends BaseController | |||
| server = NSSDK.InstanceServer(); | |||
| recv = server.Recv(request, NSContractionEntity.class); | |||
| return server.Resp(200, "测试成功", recv.getDataStr()); | |||
| return server.Resp(0, "测试成功", recv.getDataStr()); | |||
| } | |||
| @PostMapping("/report") | |||
| @@ -42,9 +49,36 @@ public class AgentCenterController extends BaseController | |||
| NSReportObject<NSContractionEntity> recv; | |||
| NSSDK.InitServer(RuoYiConfig.Secret.privateKey); | |||
| server = NSSDK.InstanceServer(); | |||
| recv = server.Recv(request, NSContractionEntity.class); | |||
| try | |||
| { | |||
| server = NSSDK.InstanceServer(); | |||
| recv = server.Recv(request, NSContractionEntity.class); | |||
| EventBusEngine.Post(convMsg(recv)); | |||
| return NSSDKServer.Success("上报成功"); | |||
| } | |||
| catch(NSException e) | |||
| { | |||
| return NSSDKServer.Fail(e.getErrno(), e.getMessage()); | |||
| } | |||
| } | |||
| private Message<?> convMsg(NSReportObject<?> reportObject) | |||
| { | |||
| Message<?> msg; | |||
| int protocol; | |||
| return server.Resp(200, "上报成功", recv.getDataStr()); | |||
| protocol = reportObject.getProtocol(); | |||
| switch(reportObject.getProtocol()) | |||
| { | |||
| case NSProtocol.NS_PROTOCOL_CONTRACTION: | |||
| msg = new ContractionMessage(protocol, reportObject.getIdentifier(), reportObject.getTimestamp(), (NSContractionEntity)reportObject.getData()); | |||
| break; | |||
| default: | |||
| NSErrGlobal.Err(NSErrno.ERRNO_SYS_INVALID_PROTOCOL); | |||
| throw new RuntimeException(String.format("未知的协议类型: 0x%x", protocol)); | |||
| } | |||
| return msg; | |||
| } | |||
| } | |||
| @@ -0,0 +1,26 @@ | |||
| package com.ruoyi.agentcenter.listener; | |||
| import com.alibaba.fastjson2.JSONObject; | |||
| import com.google.common.eventbus.Subscribe; | |||
| import com.ruoyi.agentcenter.object.ContractionMessage; | |||
| import com.ruoyi.common.utils.EventBusEngine; | |||
| import org.springframework.stereotype.Component; | |||
| import javax.annotation.PostConstruct; | |||
| @Component | |||
| public class ContractionListener | |||
| { | |||
| @PostConstruct | |||
| public void init() | |||
| { | |||
| EventBusEngine.Register(this); | |||
| } | |||
| @Subscribe | |||
| //@AllowConcurrentEvents | |||
| public void handle(ContractionMessage msg) | |||
| { | |||
| System.err.println(JSONObject.toJSONString(msg)); | |||
| } | |||
| } | |||
| @@ -1,8 +1,7 @@ | |||
| package com.ruoyi.agentcenter.listener; | |||
| import com.google.common.eventbus.AllowConcurrentEvents; | |||
| import com.google.common.eventbus.Subscribe; | |||
| import com.ruoyi.common.object.Message; | |||
| import com.ruoyi.agentcenter.object.Message; | |||
| import com.ruoyi.common.utils.EventBusEngine; | |||
| import org.springframework.stereotype.Component; | |||
| @@ -14,13 +13,13 @@ public class TestListener | |||
| @PostConstruct | |||
| public void init() | |||
| { | |||
| EventBusEngine.Register(this); | |||
| //EventBusEngine.Register(this); | |||
| } | |||
| @Subscribe | |||
| //@AllowConcurrentEvents | |||
| public void handle(Message msg) | |||
| { | |||
| System.err.println("LLL " + msg.data + " " + Thread.currentThread().getId()); | |||
| System.err.println("LLL " + msg.getData() + " " + Thread.currentThread().getId()); | |||
| } | |||
| } | |||
| @@ -0,0 +1,11 @@ | |||
| package com.ruoyi.agentcenter.object; | |||
| import com.nsgk.agentcentersdk.entity.NSContractionEntity; | |||
| public class ContractionMessage extends Message<NSContractionEntity> | |||
| { | |||
| public ContractionMessage(int protocol, String identifier, Long timestamp, NSContractionEntity data) | |||
| { | |||
| super(protocol, identifier, timestamp, data); | |||
| } | |||
| } | |||
| @@ -0,0 +1,31 @@ | |||
| package com.ruoyi.agentcenter.object; | |||
| import com.nsgk.agentcentersdk.core.NSProtocol; | |||
| import lombok.Data; | |||
| import lombok.experimental.Accessors; | |||
| @Data | |||
| @Accessors(chain = true) | |||
| public abstract class Message<T> | |||
| { | |||
| private final int protocol; // 协议 | |||
| private final String identifier; // 识别ID | |||
| private final Long timestamp; // 客户端时间戳 | |||
| private final T data; | |||
| public Message() | |||
| { | |||
| this.protocol = NSProtocol.NS_PROTOCOL_INVALID; | |||
| this.identifier = ""; | |||
| this.timestamp = 0L; | |||
| this.data = null; | |||
| } | |||
| public Message(int protocol, String identifier, Long timestamp, T data) | |||
| { | |||
| this.protocol = protocol; | |||
| this.identifier = identifier; | |||
| this.timestamp = timestamp; | |||
| this.data = data; | |||
| } | |||
| } | |||
| @@ -1,14 +0,0 @@ | |||
| package com.ruoyi.common.object; | |||
| import lombok.Data; | |||
| import lombok.experimental.Accessors; | |||
| @Data | |||
| @Accessors(chain = true) | |||
| public final class Message | |||
| { | |||
| public static final int PROTOCOL_INVALID = 0; | |||
| public int protocol = PROTOCOL_INVALID; | |||
| public Object data; | |||
| } | |||