我需要使用 Java 实现或集成 ISO8583。我正在使用 jpos 来实现。在代码中,一切看起来都很好;但在服务器级别,发现格式不符合预期。网络团队说标题不是他们的。
代码如下:
// Load the ISO 8583 packager from the resources folder
InputStream is = ISO8583MessageHandler.class.getClassLoader().getResourceAsStream("iso93ascii.xml");
if (is == null) {
throw new IllegalArgumentException("iso8583.xml is not found in resources!");
}
// Load the ISO 8583 packager
ISOPackager packager = new GenericPackager(is);
// Create an ASCIIChannel (use appropriate channel as per your requirement)
// ASCIIChannel is just one of the many available channels in JPOS
ASCIIChannel channel = new ASCIIChannel(serverIP, serverPort, packager);
// Connect to the server
channel.connect();
System.out.println("Connected to server: " + serverIP + ":" + serverPort);
// Sending Network Management Request
ISOMsg isoMsg = new ISOMsg();
isoMsg.setPackager(packager);
isoMsg.setMTI("1804");
String stan = TransactionUtils.generateSTAN();
System.out.println(stan + " -> length : " + stan.length() );
isoMsg.set(11, stan); // Unique STAN
String datetime = new SimpleDateFormat("yyMMddHHmmss").format(new Date());
System.out.println(datetime + " -> length : " + datetime.length());
isoMsg.set(12, datetime); // yyMMddHHmmss
isoMsg.set(24, "831"); // Function code
// Serialize the message once
byte[] packedMessage = isoMsg.pack();
// Prepare the header
byte[] header = new byte[2];
int length = packedMessage.length + 2;
header[0] = (byte) (length >> 8); // High byte
header[1] = (byte) (length); // Low byte
isoMsg.setHeader(header);
packedMessage = isoMsg.pack();
// Prepare a combined array for the header and the message
byte[] fullMessage = new byte[header.length + packedMessage.length];
// Copy the header and the packed message into the fullMessage array
System.arraycopy(header, 0, fullMessage, 0, header.length);
System.arraycopy(packedMessage, 0, fullMessage, header.length, packedMessage.length);
// Now dump the full message
System.out.println("Message Hex Dump:: ");
System.out.println(ISOUtil.hexdump(packedMessage));
System.out.println("Full Message Hex Dump:: ");
System.out.println(TransactionUtils.toFormattedHexDump(fullMessage));
channel.send(isoMsg);
System.out.println("ISO Network Management Call Sent...");
ISOMsg response = channel.receive();
System.out.println("Received Network Management Response from the Server!");
printISOMessage(response);
上面的代码用于 echo test 调用。根据集成文档,协议要求类似于:
HOST2HOST 通信协议 Host2Host 接口支持 TCP/IP 传输协议。 TCP/IP是点对点通信 具有传送保证和数据顺序保证的协议。这 发起连接的连接方是 TCP/IP 客户端。 接受连接的连接方是 TCP/IP 服务器。 TCP/IP 客户端建立识别目标的连接 具有主机 IP 地址和端口号的应用程序 那个主人。如果连接因任何原因断开,应该是 由客户端应用程序重新建立。 SVFE主机可以充当 TCP/IP 连接作为客户端或服务器,具体取决于主机 配置。 TCP/IP 使用会话来进行数据传输。每个 session是一个双向数据流。 SVFE协议使用单一 TCP/IP 会话在主机之间双向传输数据。这 连续的 TCP/IP 数据流被分成帧。每个 ISO - 8583 消息在单独的帧中发送。一个帧由 2 个字节组成 长度标头和消息体。标头包含的长度 以下消息。首先传输值的高字节, 然后再发送值的低字节。 2字节 N字节 消息长度 = N ISO - 8583 消息
我到底做错了什么,非常感谢您在这方面的支持。
通道为您处理长度标头。你实际设置的是什么
// Prepare the header
byte[] header = new byte[2];
int length = packedMessage.length + 2;
header[0] = (byte) (length >> 8); // High byte
header[1] = (byte) (length); // Low byte
是消息头,它是位于长度头之后的头,根据共享规范似乎不需要它。
看来你需要一个
PostChannel
,代码将是这样的:
// Load the ISO 8583 packager
ISOPackager packager = new GenericPackager("jar:iso93ascii.xml"); //jPOS can load the packager for you
// Create an ASCIIChannel (use appropriate channel as per your requirement) the appropriate channel seems to be PostChannel
ISOChannel channel = new PostChannel(serverIP, serverPort, packager);
// Connect to the server
channel.connect();
System.out.println("Connected to server: " + serverIP + ":" + serverPort);
// Sending Network Management Request
ISOMsg isoMsg = new ISOMsg();
//channel will set the packager
isoMsg.setMTI("1804");
String stan = TransactionUtils.generateSTAN();
System.out.println(stan + " -> length : " + stan.length() );
isoMsg.set(11, stan); // Unique STAN
String datetime = new SimpleDateFormat("yyMMddHHmmss").format(new Date());
System.out.println(datetime + " -> length : " + datetime.length());
isoMsg.set(12, datetime); // yyMMddHHmmss
isoMsg.set(24, "831"); // Function code
channel.send(isoMsg);
System.out.println("ISO Network Management Call Sent...");
ISOMsg response = channel.receive();
System.out.println("Received Network Management Response from the Server!");
printISOMessage(response);
如果您想知道 TCP/IP 流上发生了什么,您最好使用 tcpdump 或 Wireshark 等嗅探器。您可以为打包器设置一个记录器来检查打包的消息。
我在移动设备上,稍后会扩展,但您也应该考虑使用 Q2 来配置通道。