使用jpos为ISO 8583消息添加报头失败的技术问询
ISO 8583报头未被添加到发送消息的问题解决
问题详情
作为ISO 8583开发新手,我尝试在ISO消息前添加报头ISO008000099,但按以下代码实现后,发送的消息中并未包含该报头:
代码示例
GenericPackager packager = new GenericPackager("tes1.xml"); // 创建ISOMsg对象并绑定自定义packager ISOMsg isoMsg = new ISOMsg(); isoMsg.setPackager(packager); isoMsg.setHeader("ISO008000099".getBytes()); isoMsg.setMTI("0800"); isoMsg.set(7, "1011110140"); isoMsg.set(11, "047478"); isoMsg.set(70, "401"); ASCIIChannel c = new ASCIIChannel("localhost", 6000, packager); c.connect(); c.send(isoMsg); System.out.println("ISO message : " + new String(isoMsg.pack()));
实际发送的消息(无报头)
0000 30 38 30 30 38 32 32 30 30 30 30 30 30 30 30 30 0800822000000000 0010 30 30 30 30 30 34 30 30 30 30 30 30 30 30 30 30 0000040000000000 0020 30 30 30 30 31 30 31 31 31 31 30 31 34 30 30 34 0000101111014004 0030 37 34 37 38 34 30 31 7478401
发送的消息内容:0800822000000000000004000000000000001011110140047478401
期望发送的消息(含报头)
ISO0080000990800822000000000000004000000000000001011110140047478401
配置文件(tes1.xml)
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE isopackager SYSTEM "genericpackager3.dtd"> <!-- ISO 8583:1987 (ASCII) field descriptions for GenericPackager --> <isopackager> <header length="12" value ="""></header> <isofield id="0" length="4" name="MESSAGE TYPE INDICATOR" class="org.jpos.iso.IFA_NUMERIC"/> <isofield id="1" length="16" name="BIT MAP" class="org.jpos.iso.IFA_BITMAP"/> <isofield id="2" length="21" name="PAN - PRIMARY ACCOUNT NUMBER" class="org.jpos.iso.IFA_LLNUM"/> <isofield id="3" length="6" name="PROCESSING CODE" class="org.jpos.iso.IFA_NUMERIC"/> <isofield id="4" length="12" name="AMOUNT, TRANSACTION" class="org.jpos.iso.IFA_NUMERIC"/> </isopackager>
发送的消息字段
<isomsg direction="outgoing"> <!-- org.jpos.iso.packager.GenericPackager[tes1.xml] --> <header>49534F303038303030303939</header> <field id="0" value="0800"/> <field id="7" value="1011110140"/> <field id="11" value="047478"/> <field id="70" value="401"/> </isomsg>
问题原因
jPOS中ISOMsg.setHeader()仅将报头存储在消息对象中,默认情况下GenericPackager.pack()方法不会自动将该报头添加到打包后的字节流中。同时ASCIIChannel.send(isoMsg)内部会调用packager的打包方法,因此发送的消息自然不会包含报头。配置文件中的<header>标签仅用于解析消息时读取固定长度的报头,并不负责发送时自动添加报头。
解决方案
方法1:手动拼接报头与消息体
修改发送逻辑,手动将报头和打包后的消息体拼接为完整字节数组后发送:
GenericPackager packager = new GenericPackager("tes1.xml"); ISOMsg isoMsg = new ISOMsg(); isoMsg.setPackager(packager); isoMsg.setHeader("ISO008000099".getBytes()); isoMsg.setMTI("0800"); isoMsg.set(7, "1011110140"); isoMsg.set(11, "047478"); isoMsg.set(70, "401"); // 打包消息体 byte[] body = isoMsg.pack(); // 获取设置的报头 byte[] header = isoMsg.getHeader(); // 拼接报头与消息体 byte[] fullMessage = new byte[header.length + body.length]; System.arraycopy(header, 0, fullMessage, 0, header.length); System.arraycopy(body, 0, fullMessage, header.length, body.length); ASCIIChannel c = new ASCIIChannel("localhost", 6000, packager); c.connect(); // 发送完整消息 c.send(fullMessage); System.out.println("ISO message : " + new String(fullMessage));
方法2:自定义Packager自动处理报头
如果需要长期自动处理报头,可以自定义GenericPackager的子类,重写pack()方法,在打包时自动添加ISOMsg的报头。不过对于新手来说,方法1更简单直接。
内容的提问来源于stack exchange,提问作者Raul Roa
相关产品推荐
相关产品推荐

