diff --git a/pom.xml b/pom.xml
index f47ba44..2d74e50 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
com.sunyard
sydapi4j
- 1.0.20220722
+ 1.15.20250701
jar
sydapi4j
@@ -82,10 +82,14 @@
com.sunyard
proto
- 1.0-20220412
+ 1.0-20220905
-
+
+ org.codehaus.groovy
+ groovy
+ 2.4.15
+
@@ -148,73 +152,57 @@
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 3.1.1
-
- ./public/
- html
- html5
- com.sunyard.SydApi:com.sunyard.inf.*:com.sunyard.cert.*
-
-
+
+
+
+
+
+
+
+
+
+
+
-
- org.apache.maven.plugins
- maven-source-plugin
- 2.4
+
+
+
+
-
-
-
-
-
- package
-
- jar-no-fork
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
- org.apache.maven.plugins
- maven-jar-plugin
-
-
-
- true
- lib/
- com.xxx.uploadFile
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-dependency-plugin
-
- runtime
-
-
-
- copy
- package
-
- copy-dependencies
-
-
-
- ${project.build.directory}/lib
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -238,38 +226,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/java/com/sunyard/SydApiException.java b/src/main/java/com/sunyard/SydApiException.java
index d0f1c4f..c0a4af9 100644
--- a/src/main/java/com/sunyard/SydApiException.java
+++ b/src/main/java/com/sunyard/SydApiException.java
@@ -100,7 +100,15 @@ public class SydApiException extends RuntimeException{
transMsg();
}
-
+ public SydApiException(String msg, int ret, Throwable e){
+ super("SydApiException(" +"code ="+ String.format(" %d", ret) + " : "+"msg ="+ (null == msg ? "未定义的错误" : msg) +")" , e);
+ this.retCode = ret;
+ if (null == msg || "".equals(msg)){
+ transMsg();
+ }else {
+ this.msg = msg;
+ }
+ }
public SydApiException(String msg, int ret){
super("SydApiException(" +"code ="+ String.format(" %d", ret) + " : "+"msg ="+ (null == msg ? "未定义的错误" : msg) +")" );
this.retCode = ret;
diff --git a/src/main/java/com/sunyard/log/ILogFactory.java b/src/main/java/com/sunyard/log/ILogFactory.java
new file mode 100644
index 0000000..f2a85b3
--- /dev/null
+++ b/src/main/java/com/sunyard/log/ILogFactory.java
@@ -0,0 +1,5 @@
+package com.sunyard.log;
+
+public interface ILogFactory {
+ ILogger getLogger(Class var1);
+}
\ No newline at end of file
diff --git a/src/main/java/com/sunyard/log/ILogger.java b/src/main/java/com/sunyard/log/ILogger.java
new file mode 100644
index 0000000..3853327
--- /dev/null
+++ b/src/main/java/com/sunyard/log/ILogger.java
@@ -0,0 +1,13 @@
+package com.sunyard.log;
+
+public interface ILogger {
+ int getCurrentLogLevel();
+
+ void error(String var1, Object... var2);
+
+ void info(String var1, Object... var2);
+
+ void debug(String var1, Object... var2);
+
+ boolean isDebugEnabled();
+}
diff --git a/src/main/java/com/sunyard/log/SydLogFactory.java b/src/main/java/com/sunyard/log/SydLogFactory.java
new file mode 100644
index 0000000..5edcd3f
--- /dev/null
+++ b/src/main/java/com/sunyard/log/SydLogFactory.java
@@ -0,0 +1,101 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by FernFlower decompiler)
+//
+
+package com.sunyard.log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+public class SydLogFactory implements ILogFactory {
+ private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+ public static String pcLogPath = "./sydapi-logs/";
+ public static final String logName = "sydapi-log";
+ public static int iLogLevel = 0;
+ private static ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();
+ public static boolean debug = false;
+ private static Executor executor = Executors.newSingleThreadExecutor();
+
+ static {
+ executor.execute(new Runnable() {
+ public void run() {
+ String logFileName = "";
+ FileOutputStream logFos = null;
+
+ while(true) {
+ while(true) {
+ while(true) {
+ try {
+ if (SydLogFactory.queue.isEmpty()) {
+ Thread.sleep(500L);
+ } else {
+ String mayLogFileName = String.format("%s_%s.log", "sydapi-log", SydLogFactory.format.format(new Date()));
+ if (!logFileName.equals(mayLogFileName)) {
+ logFileName = mayLogFileName;
+ if (logFos != null) {
+ logFos.flush();
+ logFos.close();
+ }
+
+ File folder = new File(SydLogFactory.pcLogPath);
+ if (!folder.exists()) {
+ folder.mkdirs();
+ }
+
+ File f = new File(SydLogFactory.pcLogPath, logFileName);
+ if (!f.exists()) {
+ f.createNewFile();
+ }
+
+ logFos = new FileOutputStream(f, true);
+ }
+
+ while(!SydLogFactory.queue.isEmpty()) {
+ SydLogInfo info = (SydLogInfo)SydLogFactory.queue.poll();
+ logFos.write(String.format("[%d:%s <%s-%d>] %s\r\n", info.getLevel(), SydLogFactory.format.format(new Date(info.getDatatime())), info.getTname(), info.getTid(), info.getMsg()).getBytes());
+ }
+
+ logFos.flush();
+ }
+ } catch (Exception var9) {
+ Exception e = var9;
+ e.printStackTrace();
+ } finally {
+ SydLogFactory.closeFileOutputStream(logFos);
+ logFileName = "";
+ }
+ }
+ }
+ }
+ }
+ });
+ }
+
+ private static void closeFileOutputStream(FileOutputStream fos) {
+ if (fos != null) {
+ try {
+ fos.flush();
+ } catch (Exception var2) {
+ }
+
+ try {
+ fos.close();
+ } catch (Exception var1) {
+ }
+ }
+
+ }
+
+ private SydLogFactory() {
+ }
+
+ public ILogger getLogger(Class cls) {
+ return new SydLogger(queue);
+ }
+}
diff --git a/src/main/java/com/sunyard/log/SydLogInfo.java b/src/main/java/com/sunyard/log/SydLogInfo.java
new file mode 100644
index 0000000..2d31b9b
--- /dev/null
+++ b/src/main/java/com/sunyard/log/SydLogInfo.java
@@ -0,0 +1,48 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by FernFlower decompiler)
+//
+
+package com.sunyard.log;
+
+public class SydLogInfo {
+ private int level;
+ private long datatime;
+ private String tname;
+ private long tid;
+ private String msg;
+ private Object[] objects;
+
+ public SydLogInfo(int level, String msg, Object[] objects) {
+ this.level = level;
+ this.msg = msg;
+ this.objects = objects;
+ this.datatime = System.currentTimeMillis();
+ this.tname = Thread.currentThread().getName();
+ this.tid = Thread.currentThread().getId();
+ }
+
+ public int getLevel() {
+ return this.level;
+ }
+
+ public long getDatatime() {
+ return this.datatime;
+ }
+
+ public String getTname() {
+ return this.tname;
+ }
+
+ public long getTid() {
+ return this.tid;
+ }
+
+ public String getMsg() {
+ return this.msg;
+ }
+
+ public Object[] getObjects() {
+ return this.objects;
+ }
+}
diff --git a/src/main/java/com/sunyard/log/SydLogger.java b/src/main/java/com/sunyard/log/SydLogger.java
new file mode 100644
index 0000000..3977059
--- /dev/null
+++ b/src/main/java/com/sunyard/log/SydLogger.java
@@ -0,0 +1,47 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by FernFlower decompiler)
+//
+
+package com.sunyard.log;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public class SydLogger implements ILogger {
+ private ConcurrentLinkedQueue queue;
+
+ SydLogger(ConcurrentLinkedQueue queue) {
+ this.queue = queue;
+ }
+
+ @Override
+ public void debug(String msg, Object... params) {
+ if (SydLogFactory.iLogLevel == 3) {
+ this.queue.add(new SydLogInfo(3, msg, params));
+ }
+ }
+
+ @Override
+ public boolean isDebugEnabled() {
+ return SydLogFactory.iLogLevel == 3;
+ }
+
+ @Override
+ public void info(String msg, Object... params) {
+ if (SydLogFactory.iLogLevel >= 2) {
+ this.queue.add(new SydLogInfo(2, msg, params));
+ }
+ }
+
+ @Override
+ public void error(String msg, Object... params) {
+ if (SydLogFactory.iLogLevel >= 1) {
+ this.queue.add(new SydLogInfo(1, msg, params));
+ }
+ }
+
+ @Override
+ public int getCurrentLogLevel() {
+ return SydLogFactory.iLogLevel;
+ }
+}
diff --git a/src/main/java/racal/sunyard/main/SydApi4j.java b/src/main/java/racal/sunyard/main/SydApi4j.java
index f84300b..09e3b2a 100644
--- a/src/main/java/racal/sunyard/main/SydApi4j.java
+++ b/src/main/java/racal/sunyard/main/SydApi4j.java
@@ -6,11 +6,12 @@ import com.sunyard.SydApi;
import com.sunyard.SydApiException;
import com.sunyard.cert.X509;
import com.sunyard.entity.Struct;
+import com.sunyard.log.ILogFactory;
+import com.sunyard.log.ILogger;
import com.sunyard.proto.Packet;
import com.sunyard.proto.PacketSection;
import com.sunyard.proto.Util;
import com.sunyard.proto.section.SectionValue;
-import com.sunyard.proto.value.Str;
import com.sunyard.trans.Alg;
import com.sunyard.trans.FullMode;
import com.sunyard.trans.PacketSN;
@@ -20,7 +21,10 @@ import com.sunyard.util.FileUtil;
import com.sunyard.util.MyUtil;
import com.sunyard.util.SYMUtil;
import org.apache.logging.log4j.Logger;
-import racal.sunyard.main.dto.*;
+import racal.sunyard.main.dto.DTO77;
+import racal.sunyard.main.dto.DTO78;
+import racal.sunyard.main.dto.DTO79;
+import racal.sunyard.main.dto.DTO7A;
import racal.sunyard.main.proto.*;
import java.io.*;
@@ -28,13 +32,14 @@ import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
-import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.*;
public class SydApi4j implements SydApi {
+ private static ILogFactory logFactory = null;
+ private static ILogger logger = null;
// 数据包长度
private final int MaxDataLenEachPack = 4064;
@@ -54,6 +59,16 @@ public class SydApi4j implements SydApi {
private static int port;
private static int timeout;
+ public static ILogFactory getLogFactory() {
+ return logFactory;
+ }
+
+ public static void setLogFactory(ILogFactory logFactory) {
+ SydApi4j.logFactory = logFactory;
+ logger = logFactory.getLogger(SydApi4j.class);
+ }
+
+
public static void setLogger(Logger log) {
SydApi4j.log = log;
}
@@ -1096,21 +1111,40 @@ public class SydApi4j implements SydApi {
if ( debug ) {
System.out.println(i);
}
- if ( null != log ) {
+ if ( null != log && log.isDebugEnabled()) {
log.debug("{}", i);
}
+ if ( null != logger && logger.isDebugEnabled()) {
+ logger.debug("{}", i);
+ }
}
private static void print(Object i) {
if (debug) {
System.out.print(i);
}
- if ( null != log ) {
+ if ( null != log && log.isDebugEnabled()) {
log.debug("{}", i);
}
+ if ( null != logger && logger.isDebugEnabled()) {
+ logger.debug("{}", i);
+ }
}
- //gc回收
+
+ private static void printHex(byte[] data) {
+ if (debug) {
+ System.out.print(Util.bytes2HexString(data));
+ }
+ if ( null != log && log.isDebugEnabled()) {
+ log.debug("{}", Util.bytes2HexString(data));
+ }
+ if ( null != logger && logger.isDebugEnabled()) {
+ logger.debug("{}", Util.bytes2HexString(data));
+ }
+ }
+
+ // gc回收
@Override
protected void finalize() throws Throwable {
super.finalize();
@@ -1137,6 +1171,7 @@ public class SydApi4j implements SydApi {
try {
s1.connect(address, timeout);
socket = s1;
+ socket.setTcpNoDelay(true);
socket.setSoTimeout(timeout);
} catch (Exception e) {
Socket s2 = new Socket();
@@ -1144,6 +1179,7 @@ public class SydApi4j implements SydApi {
try {
s2.connect(add2, timeout);
socket = s2;
+ socket.setTcpNoDelay(true);
socket.setSoTimeout(timeout);
} catch (Exception e2) {
throw new SydApiException(-2);
@@ -1170,16 +1206,16 @@ public class SydApi4j implements SydApi {
println("\n\n发送数据");
-// print("原始数据: \t");
-// println(Arrays.toString(buff));
print("HEX数据: \t");
- println(Util.bytes2HexString(buff));
+ printHex(buff);
if (null != builder && builder.isUseEBCDMode()) {
// 对十个字节之后的进行 EBCD 转码
buff = CoderUtil.ASCIIToEBCDICFIX(buff, 10);
+
print("EBCD 数据: \t");
- println(Util.bytes2HexString(buff));
+ printHex(buff);
+
}
testSocket();
@@ -1205,7 +1241,7 @@ public class SydApi4j implements SydApi {
print("原始数据: \t");
println(Arrays.toString(buff));
print("HEX数据: \t");
- println(Util.bytes2HexString(buff));
+ printHex(buff);
testSocket();
@@ -1239,58 +1275,62 @@ public class SydApi4j implements SydApi {
private ByteBuffer read(Socket socket) throws IOException {
InputStream is = socket.getInputStream();
- int d;
- int high = is.read();
- int low = is.read();
- int len = (high << 8) + low;
- len += 2;
-
- print("H\t");
- println(Integer.toHexString(high));
- print("L\t");
- println(Integer.toHexString(low));
- print("Len\t");
- println(len);
-
-
- ByteBuffer bb = ByteBuffer.allocate(len);
- bb.put((byte) (high & 0xFF));
- //println(String.format("%d %d %s",len, bb.position() -1, Util.bytes2HexString(new byte[]{(byte) (high & 0xFF)})));
-
- bb.put((byte) (low & 0xFF));
- //println(String.format("%d %d %s",len, bb.position() -1, Util.bytes2HexString(new byte[]{(byte) (low & 0xFF)})));
-
-
- while (true) {
- d = is.read();
- if (-1 == d) {
- break;
- }
-
- bb.put((byte) (d & 0xFF));
-
- //println(String.format("%d %d %s",len, bb.position() -1, Util.bytes2HexString(new byte[]{(byte) (d & 0xFF)})));
-
- if (bb.position() == len) {
- break;
- }
+ // 一次性读取前2个字节(长度字段)
+ byte[] lenBytes = new byte[2];
+ int bytesRead = is.read(lenBytes);
+ if (bytesRead != 2) {
+ throw new EOFException("Connection closed before reading length bytes");
}
+ int high = lenBytes[0] & 0xFF;
+ int low = lenBytes[1] & 0xFF;
+ int len = (high << 8) + low + 2; // 总长度 = 数据长度 + 2字节长度字段
+
+ if (debug) {
+ // 调试输出
+ print("H\t");
+ println(Integer.toHexString(high));
+ print("L\t");
+ println(Integer.toHexString(low));
+ print("Len\t");
+ println(len);
+ }
+
+ // 分配缓冲区并放入前2个字节
+ ByteBuffer bb = ByteBuffer.allocate(len);
+ bb.put(lenBytes);
+
+ // 读取剩余数据
+ byte[] data = new byte[len - 2];
+ int totalRead = 0;
+ while (totalRead < data.length) {
+ bytesRead = is.read(data, totalRead, data.length - totalRead);
+ if (bytesRead == -1) {
+ throw new EOFException("Connection closed before reading all data");
+ }
+ totalRead += bytesRead;
+ }
+ bb.put(data);
if (null != builder && builder.isUseEBCDMode()) {
- print("EBCD 数据: \t");
- println(Util.bytes2HexString(bb.array()));
+ if (debug) {
+ print("EBCD 数据: \t");
+ printHex(bb.array());
+ }
byte[] b = bb.array();
CoderUtil.EBCDICToASCIIFIX(b, 10);
}
- print("HEX数据: \t");
- println(Util.bytes2HexString(bb.array()));
+
+ print("read HEX数据: \t");
+ printHex(bb.array());
+
return bb;
}
+
/**
* 阻塞读取
* 前两个字节是长度
@@ -2266,8 +2306,8 @@ public class SydApi4j implements SydApi {
} else {
// 加密
for ( byte[]d : pINdata ) {
- if ( d.length > 1024 ) {
- throw new IllegalArgumentException("批量单数据超长 1024");
+ if ( d.length > 1040 ) {
+ throw new IllegalArgumentException("批量单数据超长 1040");
}
}
}
@@ -3441,6 +3481,7 @@ public class SydApi4j implements SydApi {
//1.1生成一个对称密钥(*) -> pass (对比之前添加了可产生ZMK加密下的密钥)
// 测试通过
+ @Override
public RetWrap genSymKey(int mode, String keyType, char solution, String zmk) {
ProtoA0 proto = new ProtoA0();
HashMap packet = new HashMap();
@@ -8737,6 +8778,7 @@ public class SydApi4j implements SydApi {
* @return 目的 ZPK 下加密的目的 PIN 块
*/
// 测试通过
+ @Override
public String transPINFromTPKToZPK(String tpk, String zpk, int sca, int dca, int spt, int dpt, String pin, String account) {
ProtoCA proto = new ProtoCA();