ISO 8583使用总结(附Java部分源码)(二)

第一种实现方式

第一种实现方式分为三步:

  • 第一步:创建域对象
  • 第二步:创建各种数据转换的工具类
  • 第三步:封装请求

    第一步:创建域对象
    这一步就比较简单了,也比较容易理解,适合域比较少,或者每次填写就那么十几个域。
    打开你的接口文档,看一下文档中的接口报文都有多少个域,我这里是有64个域,有的域下面还有子域。
public class Message8583Body {
    private String msgType;// 消息类型
    private String bitMap;// 位元表
    private String domain2;
    private String domain3;
    private String domain4;
    ··· 
    private String domain48;
    private String domain49; 
    private String domain58;  
    private String domain58_1;  
    private String domain58_2;  
    private String domain58_3;
}

这里我就简单表示一下,共有64域,根据每个域和其子域中创建一个类。子域我以58域这里举例,假设55域下面还有三个子域,有子域的地方set方法需要特别处理。

  
  public String getDomain58() {
    return domain58;
  }
  public void setDomain58(String domain58) {
    this.domain58 = domain58;
  }
  public String getDomain58_1() {
    return domain58_1;
  }
  public void setDomain58_1(String domain58_1) {
    this.domain58_1 = domain58_1;
    this.domain58 += domain58_1;
  }
  public String getDomain58_2() {
    return domain58_2;
  }  
  public void setDomain58_2(String domain58_2) {
    this.domain58_2 = domain58_2;
    this.domain58 += domain58_2;
  }
  public String getDomain58_3() {
    return domain58_3;
  }
  public void setDomain58_3(String domain58_3) {
    this.domain58_3 = domain58_3;
    this.domain58 += domain58_3;
  }

也就是说,这个子域报文是依次向后拼接在58域后面的。假如58_1下面还有子域,一样的写法这里就不多阐述了。到此为止,第一步完成了。
(WARNING:我这里是简要表达意思,使用时请依据实际情况考虑高并发的问题。)

第二步:创建各种数据转换的工具类

因为在8583中,报文是以数字和字母进行传输的,有的是转成ASCII,有的只是左/右靠BCD补0等等。这里列出常用的字符转换,如果需要我这边完整版本,请移步github。

    /**
     * 获取位元表
     *
     * @param list
     * @return
     */
    public static String getBitMap(List<Integer> list) {
        StringBuffer result = new StringBuffer("");
        byte[] bytes = new byte[64];
        for (int i = 0; i < 64; i++) {
            if (list.contains(i + 1)) {
                bytes[i] = 1;
            } else {
                bytes[i] = 0;
            }
        }
        StringBuffer sb = new StringBuffer("");
        for (int i = 0; i <= 64; i++) {
            if (i % 4 == 0 && i != 0) {
                result.append(
                        String.format("%x", Integer.valueOf(sb.toString(), 2))
                                .toUpperCase());
                sb.delete(0, sb.length());
                if (i < 64) {
                    sb.append(bytes[i]);
                }
            } else {
                sb.append(bytes[i]);
            }
        }
        log.info("bitMap=" + result.toString());
        return result.toString();
    }
    
    /**
         * 普通字符串转为ascii字符串
         *
         * @param asciiString 字节数组
         * @return
         */
        public static String asciiToHex(String asciiString) {
            if (asciiString == null) {
                return "";
            }
            StringBuffer buff = new StringBuffer();
            byte[] bytes = asciiString.getBytes();
            int len = bytes.length;
            for (int j = 0; j < len; j++) {
                if ((bytes[j] & 0xff) < 16) {
                    buff.append('0');
                }
                buff.append(Integer.toHexString(bytes[j] & 0xff).toUpperCase());
            }
            return buff.toString();
        }

由于篇幅限制,我这里就暂时先列出两个示例方法,创建好各种工具,第二步就算完成了。

第三步:封装请求

封装请求比较简单了,先进行位元表创建,然后进行域赋值就可以了。

        //位元表填写
    Integer[] array = {2,3,4,11,25,41,42,58,60,63,64};
    List<Integer> list=  Arrays.asList(array);
    

这里位元表里面的值代表了哪些域有值,通过数据创建一个list,然后对域赋值的时候,再将list转化为位元表。
下面进行对于赋值,还是先上示例代码

Message8583Body body = new Message8583Body();
body.setMsgType("1111");
body.setBitMap(getBitMap(list));
body.setDomain2("2222");
body.setDomain3("3333");
body.setDomain4("4444");
···
body.setDomain58_1("581581581");
body.setDomain58_2("582582582");
body.setDomain58_3("583583583");
String domain58 = (这里调用实际报文转换的方式,一般58域是获取整体报文长度,拼装在58域的前面)(body.getDomain58(), 3);
body.setDomain58(domain58);

当把你的报文都set完毕后,调用和服务方约定的方式,计算所有的报文长度,拼在报文前面。到此为止,第三步完成了。
三步都做好后,此时就可以用socket发送到服务方了,剩下就是调试工作。

第二种实现方式

第二种实现方式也分为三步:

  • 第一步:创建域对象
  • 第二步:创建各种数据转换的工具类
  • 第三步:封装请求
    #### 第一步:创建域对象
    这一步就与第一步不同的是,这个域对象不再是简单的表示每个域的报文了,而是这个一个类,代表所有域的信息。
public class FieldObject {
   /**
    * 域所在的位
    */
   private int index;
   /**
    * 长度
    */
   private int length;
   /**
    * 格式
    */
   private int format;
   
   /**
    * 类型
    */
   private int type;
   
   /**
    * 值
    */
   private String value;
   
   /**
    * 是否定长
    */
   private int isVar;
   
   /**
    * 响应结果LLLVAR长度
    */
   private int varLength;
   
}

上面是每一个域的信息,包括所在的位,长度,字段信息等。这个类有两个构造方法,一个是请求对象的构建,一个是响应报文的解析。

        /**
     * ISO 8583请求对象构建
     * @param index
     * @param value
     * @param varLength
     * @param type
     */
    public FieldObject(int index,String value,int isVar,int type){
        this.index = index;
        this.value = value;
        this.isVar = isVar;
        this.type = type;
    }
    
    /**
     * ISO8583解析对象构建
     * @param index
     * @param length
     * @param isVar
     * @param type
     */
    public FieldObject(int index,int length,int varLength,int type){
        this.index = index;
        this.length = length;
        this.varLength = varLength;
        this.type = type;
    }

这两个构建构造方法,一个是用来构建,一个用来解析,使用的时候注意参数不要传递错误导致问题。这里,第一步就做好了。

第二步:创建各种数据转换的工具类

同第一种的第二步。

第三步:封装请求

这里就先简单演示一下,请求参数如何封装

List<FieldObject> fieldList = new ArrayList<>();
fieldList.add( new FieldObject(1, "1111", 1, 1));
fieldList.add( new FieldObject(2, "2222", 2, 2));
fieldList.add( new FieldObject(3, "3333", 3, 3));
···

这里后面两位是标识这个域的参数类型(比如1是普通数字,2是ASCII,3是BCD等等,看自己定义),当这个list拼装好了之后,就可以进行参数封装等信息然后发送给服务端。


到此为止,两种封装方式就分享给大家了,后面会上传的到git,如果有需要请移步下载,如果觉得还可以,请给个赞。如果有任何问题,欢迎留言,我会及时回复。

转载于:https://www.cnblogs.com/ragnaros/p/11304797.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值