From 73c315f71404bbe610941cccd494a2080f7084fe Mon Sep 17 00:00:00 2001 From: Cheney Wong Date: Wed, 2 Jul 2025 17:59:26 +0800 Subject: [PATCH] =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=85=BC=E5=AE=B9=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 154 +++++++----------- .../java/com/sunyard/SydApiException.java | 10 +- .../java/com/sunyard/log/ILogFactory.java | 5 + src/main/java/com/sunyard/log/ILogger.java | 13 ++ .../java/com/sunyard/log/SydLogFactory.java | 101 ++++++++++++ src/main/java/com/sunyard/log/SydLogInfo.java | 48 ++++++ src/main/java/com/sunyard/log/SydLogger.java | 47 ++++++ .../java/racal/sunyard/main/SydApi4j.java | 146 +++++++++++------ 8 files changed, 372 insertions(+), 152 deletions(-) create mode 100644 src/main/java/com/sunyard/log/ILogFactory.java create mode 100644 src/main/java/com/sunyard/log/ILogger.java create mode 100644 src/main/java/com/sunyard/log/SydLogFactory.java create mode 100644 src/main/java/com/sunyard/log/SydLogInfo.java create mode 100644 src/main/java/com/sunyard/log/SydLogger.java 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();