Simple8583是一款简洁高效的8583报文解析框架,旨在帮助开发者轻松处理金融交易中的各种复杂需求。该工具集成了多种实用功能,并提供详细的文档和示例代码,以促进快速开发与部署。
最近在开发中国银行的一个快捷支付渠道项目,并且使用了 ISO8583 协议。起初采用了 JPOS 框架进行开发,但后来觉得这个框架过于庞大复杂,而且相关文档也不够丰富详尽。于是,在等待银行专线的期间,我决定自己从零开始创建了一个简易版的 8583 报文解析框架 —— Simple8583,并重新编写了项目代码。这使项目的代码量大幅减少。
在调试中国银行接口的过程中,终于完成了测试环境中的所有配置和测试工作。现在抽时间分享一下这段时间所学到的知识点:
数据类型与编码格式:根据我接触到的数据类型,将它们归类为以下几种:
- CHAR(ASCII 编码),直接使用字符串的 getBytes(ENCODING) 方法获取字节数组;
- BINARY(二进制编码,在打包时需要将8位01值组装成一个字节);
- NUMERIC (BCD 编码,即 8421 码);
- LLVAR 和 LLLVAR 类型都属于变长域。其中每个 LLVAR 域前会有一个表示长度的字节(采用 BCD 编码),而 LLLVAR 则会有两个这样的字节;
- LLVAR_NUMERIC 同样是变长域,不过它使用的是 BCD 编码,并且其长度字段代表实际数据值的位数而非字节数。
如果遇到其他类型的数据,则可以在 IsoType 类中添加新的处理方式,在 IsoField 中进行相应的操作。BitMap:ISO8583 报文的核心是 BitMap,通过它来标识哪些域在本次请求中有用(即为有效域)。因此接收方可以根据这些信息解析特定的报文段。
具体而言,BitMap 分成两种情况:支持64个域时使用1字节;而当需要处理多达128个字段的情况下,则采用2字节。同时 BitMap 的第一位决定了是用 8 字节还是 16 字节表示整个映射表(如果为“0”则代表后者)。BitMap 中的每一位都对应着数据域中的某个具体编号,有效域会被设置成“1”。例如,“01001000”意味着第2个和第5个字段是有效的。
在 Simple8583 框架中,通过 BitMap 类实现了这一功能。MTI(Message Type Identifier):是一种4位BCD编码的数字标识符,用于描述信息类型。尽管一个 MTI 可以对应多种交易场景(如消费、退货等),但这些不同类型的交易通常具有相似的数据域定义。
在我的项目中,Simple8583 的 XML 文件被划分为两个部分:一部分是通用报文头(包括 msgLength, tpdu 和 bitmap 等信息);另一部分则是根据不同的 MTI 分成多个包体。整个实现流程如下:
1. 组装请求的 Map 数据;
2. 请求数据进入 SimpleClient 代理,通过解析 XML 文件来确定使用哪个 IsoPackage 类(这里采用了 JAXB 实现,并做了缓存处理);
3. 根据传入值中的 MTI 寻找对应的 IsoPackage 类实例,对其进行克隆操作以避免污染原对象;
4. 对新生成的副本进行域值的格式化和处理工作;
5. 生成 BitMap 并计算 MAC 值(如有必要);
6. 使用 ByteArrayOutputStream 将所有字段拼接成一个大的字节数组,并在前面添加两个表示长度的字节;
7. 经由 Socket 发送数据并接收响应,读取前两字节以确定剩余报文长度。然后根据这些信息解析 BitMap 并处理各个域的数据值;
8. 最后将所有字段放入 Map 中返回给调用者,并进行 MAC 校验(如有)。