分享

ISO8583报文工具类(组装和解析报文)

 嵌入式开发sun 2017-06-08

     很久没来csdn了。现在的工作地点在银行,妈的,不让上网啊。

写写博客其实是对自己知识的总结,这么长时间了,也该写点东西了。接触银行的项目,避免不了

遇上8583报文。具体介绍就不细讲了,这个网上一大堆介绍的。关键是怎么去组装和解析8583报文?

这个代码还真不好找。在此,我把自己的研究写成一个工具类,看的懂其实很好改写,看不懂就直接拿去用吧。

 

  1. package com.lsy.common.util;  
  2.   
  3. import java.io.FileInputStream;  
  4. import java.io.UnsupportedEncodingException;  
  5. import java.util.HashMap;  
  6. import java.util.Iterator;  
  7. import java.util.Map;  
  8. import java.util.Properties;  
  9. import java.util.TreeMap;  
  10.   
  11. /** 
  12.  *  
  13.  * 这是本人写的ISO8583报文工具类,包含了报文的组装和解析。 
  14.  *  
  15.  * 简单介绍下ISO8583。 
  16.  * 这个东西说白了就是一种数据结构。我们定义一种规则把一堆东西放进去,再按照规则 
  17.  * 把数据正确拿出来。这就是报文的实质。 
  18.  *  
  19.  * ISO8583报文的结构是:前面有16字节(128位)位图数据,后面就是数据。 
  20.  * 报文最多有128个域(字段)。具体的一个报文不会有这么多,一般是几个域。 
  21.  * 有哪几个就记录在位图中。而且域有定长和变长之分。 
  22.  * 这些都是事先定义好的,具体可以看我写的properties定义文件. 
  23.  *  
  24.  * 位图转化成01字符串就是128个,如果某一位是1,代表这个域有值,然后按照properties定义的规则取值。 
  25.  * 如果是0,则这个域没有值。 
  26.  *  
  27.  * 再说定长和变长。 
  28.  * 定长域(定长比较好理解,一个字段规定是N位,那么字段值绝对不能超过N位,不足N位就在后面补空格) 
  29.  * 变长域(变长域最后组装成的效果:例如变长3位,定义var3,这里的3是指长度值占3位,字段值是123456,最后结果就是006123456) 
  30.  * 注意(变长的长度按照域值得字节长度计算,而不是按照域值字符串长度算!) 
  31.  *  
  32.  * 从网上不难找到ISO8583报文的介绍,这里就不多说了。 
  33.  * 但是具体解析和组装的代码还真不好找,所以本人就写了一个让刚接触ISO8583报文的人更好入门。 
  34.  *  
  35.  *  
  36.  *  
  37.  * 解析的容器,我使用了Map,具体到工作中,还是要换成其他的容器的。 
  38.  * 报文定义说明:config_8583.properties 
  39.  * 例如 
  40.  * FIELD031 = string,10 
  41.  * FIELD032 = string,VAR2 
  42.  *  
  43.  * FIELD031是定长,长度是10 
  44.  * FIELD032是变长,长度值占2位,也就是说长度值最大99,也就是域值最大长度99. 
  45.  *  
  46.  * @author lushuaiyin 
  47.  *  
  48.  */  
  49. public class Lsy8583Util {  
  50.       
  51.     public static String packet_encoding="UTF-8";//报文编码 UTF-8 GBK  
  52.     private static Map map8583Definition = null;// 8583报文128域定义器  
  53.       
  54.     static{  
  55.         String basepath=Lsy8583Util.class.getClassLoader().getResource("").getPath();  
  56.         System.out.println(basepath);  
  57.         System.out.println("Lsy8583Util使用编码配置:[encoding:"+packet_encoding+"]");  
  58.         Properties property = new Properties();  
  59.         String path =  basepath+"/config_8583.properties";  
  60.         FileInputStream fis;  
  61.         try {  
  62.             fis = new FileInputStream(path);  
  63.             property.load(fis);  
  64.             Lsy8583Util.map8583Definition = new HashMap(property);  
  65.             fis.close();  
  66.         } catch (Exception e) {  
  67.             e.printStackTrace();  
  68.         }  
  69.     }  
  70.     // 8583报文初始位图:128位01字符串  
  71.     public static String getInitBitMap(){  
  72.         String initBitMap =   
  73.           "10000000" + "00000000" + "00000000" + "00000000"   
  74.         + "00000000" + "00000000" + "00000000" + "00000000"   
  75.         + "00000000" + "00000000" + "00000000" + "00000000"   
  76.         + "00000000" + "00000000" + "00000000" + "00000000";  
  77.         return initBitMap;  
  78.     }  
  79.       
  80.     /** 
  81.      * @param args 
  82.      */  
  83.     public static void main(String[] args) {  
  84.         try {  
  85.             //***********************组装8583报文测试--start***********************//  
  86.             TreeMap filedMap=new TreeMap();//报文域  
  87.             filedMap.put("FIELD003", "1799");//交易码  
  88.             filedMap.put("FIELD013", "2013-11-06");//交易日期  
  89.             filedMap.put("FIELD008", "12345678901");//账号  
  90.             filedMap.put("FIELD033", "aa索隆bb");//注意这个域是变长域!  
  91.             filedMap.put("FIELD036", "123456");//注意这个域是变长域!  
  92.               
  93.             byte[] send=make8583(filedMap);  
  94.             System.out.println("完成组装8583报文=="+new String(send,packet_encoding)+"==");  
  95.             //***********************组装8583报文测试--end***********************//  
  96.               
  97.               
  98.             //***********************解析8583报文测试--start***********************//  
  99.             Map back=analyze8583(send);  
  100.             System.out.println("完成解析8583报文=="+back.toString()+"==");  
  101.             //***********************解析8583报文测试--end***********************//  
  102.         } catch (UnsupportedEncodingException e) {  
  103.             e.printStackTrace();  
  104.         }  
  105.           
  106.     }  
  107.       
  108.     /** 
  109.      * 组装8583报文 
  110.      * @param hm 
  111.      * @return 
  112.      */  
  113.     public static byte[] make8583(TreeMap  filedMap){  
  114.         byte[] whoe8583=null;  
  115.         if(filedMap==null){  
  116.             return null;  
  117.         }  
  118.         try {  
  119.             String  bitMap128=getInitBitMap();//获取初始化的128位图  
  120.             //按照8583定义器格式化各个域的内容  
  121.             Map all=formatValueTo8583(filedMap,bitMap128);  
  122.             // 获取上送报文内容  
  123.             whoe8583=getWhole8583Packet(all);  
  124.             return whoe8583;  
  125.         } catch (Exception e) {  
  126.             e.printStackTrace();  
  127.         }  
  128.         return whoe8583;  
  129.     }  
  130.     /** 
  131.      * 获取完整的8583报文体(128域) 
  132.      * @param pacBody 
  133.      * @return 
  134.      */  
  135.     public static byte[] getWhole8583Packet(Map all){  
  136.         if(all==null||all.get("formatedFiledMap")==null||all.get("bitMap128")==null){  
  137.             return null;  
  138.         }  
  139.         try {  
  140.             String  bitMap128=(String)all.get("bitMap128");  
  141.             // 128域位图二进制字符串转16位16进制  
  142.             byte[] bitmaps= get16BitByteFromStr(bitMap128);  
  143.               
  144.             TreeMap pacBody=(TreeMap)all.get("formatedFiledMap");  
  145.             StringBuffer last128=new StringBuffer();  
  146.             Iterator it=pacBody.keySet().iterator();  
  147.             for(;it.hasNext();){  
  148.                 String key=(String)it.next();  
  149.                 String value=(String)pacBody.get(key);  
  150.                 last128.append(value);  
  151.             }  
  152.             byte[] bitContent = last128.toString().getBytes(packet_encoding);//域值  
  153.               
  154.             //组装  
  155.             byte[] package8583=null;  
  156.             package8583=Lsy8583Util.arrayApend(package8583, bitmaps);  
  157.             package8583=Lsy8583Util.arrayApend(package8583, bitContent);  
  158.   
  159.             return package8583;  
  160.         } catch (Exception e) {  
  161.             e.printStackTrace();  
  162.             return null;  
  163.         }  
  164.     }  
  165.       
  166.     public static Map formatValueTo8583(TreeMap filedMap,String  bitMap128){  
  167.         Map all=new HashMap();  
  168.         TreeMap formatedFiledMap=new TreeMap();//格式化结果  
  169.         if(filedMap!=null){  
  170.             Iterator it=filedMap.keySet().iterator();  
  171.             for(;it.hasNext();){  
  172.                 String fieldName=(String)it.next();//例如FIELD005  
  173.                 String fieldValue=(String)filedMap.get(fieldName);//字段值  
  174.                   
  175.                 try{  
  176.                     if (fieldValue == null) {  
  177.                         System.out.println("error:报文域 {" + fieldName + "}为空值");  
  178.                         fieldValue = "";  
  179.                         return null;  
  180.                     }  
  181.                     //将域值编码转换,保证报文编码统一  
  182.                     fieldValue=new String(fieldValue.getBytes(packet_encoding),packet_encoding);  
  183.                       
  184.                     // 数据域名称FIELD开头的为128域  
  185.                     if (fieldName.startsWith("FIELD") && fieldValue.length() >= 0) {  
  186.                         String fieldNo = fieldName.substring(5, 8);//例如005  
  187.                         // 组二进制位图串  
  188.                         bitMap128 = change16bitMapFlag(fieldNo, bitMap128);  
  189.   
  190.                         // 获取域定义信息  
  191.                         String[] fieldDef = Lsy8583Util.map8583Definition.get("FIELD" + fieldNo).toString().split(",");  
  192.                         String defType=fieldDef[0];//类型定义例string  
  193.                         String defLen=fieldDef[1];//长度定义,例20  
  194.                         boolean isFixLen=true;//是否定长判断  
  195.                           
  196.                         if(defLen.startsWith("VAR")){//变长域  
  197.                             isFixLen=false;  
  198.                             defLen=defLen.substring(3);//获取VAR2后面的2  
  199.                         }  
  200.                         int fieldLen = fieldValue.getBytes(packet_encoding).length;//字段值得实际长度  
  201.                           
  202.                         // 判断是否为变长域  
  203.                         if (!isFixLen) {// 变长域(变长域最后组装成的效果:例如变长3位,定义var3,这里的3是指长度值占3位,字段值是123456,最后结果就是006123456)  
  204.                             int defLen1 = Integer.valueOf(defLen);  
  205.                             if (String.valueOf(fieldLen).length() > (10*defLen1)) {  
  206.                                 System.out.println("error:字段" + fieldName + "的数据定义长度的长度为" + defLen + "位,长度不能超过"+(10*defLen1));  
  207.                                 return null;  
  208.                             }else{  
  209.                                 //将长度值组装入字段  
  210.                                 fieldValue = getVaryLengthValue(fieldValue, defLen1) + fieldValue;  
  211.                             }  
  212.                         } else {//定长域(定长比较好理解,一个字段规定是N位,那么字段值绝对不能超过N位,不足N位就在后面补空格)  
  213.                             int defLen2 = Integer.valueOf(defLen);  
  214.                             if (fieldLen > defLen2) {  
  215.                                 System.out.println("error:字段" + fieldName + "的数据定义长度为" + defLen + "位,长度不能超过"+defLen);  
  216.                                 return null;  
  217.                             }else{  
  218.                                 fieldValue=getFixFieldValue(fieldValue,defLen2);//定长处理  
  219.                             }  
  220.                         }  
  221.                         System.out.println("组装后报文域 {" + fieldName + "}==" + fieldValue+"==,域长度:"+fieldValue.getBytes(packet_encoding).length);  
  222.                     }  
  223.                       
  224.                     // 返回结果赋值  
  225.                     if (filedMap.containsKey(fieldName)) {  
  226.                         if (formatedFiledMap.containsKey(fieldName)) {  
  227.                             formatedFiledMap.remove(fieldName);  
  228.                         }  
  229.                         formatedFiledMap.put(fieldName, fieldValue);  
  230.                     } else {  
  231.                         System.out.println("error:" +fieldName + "配置文件中不存在!");  
  232.                     }  
  233.                 } catch (Exception e) {  
  234.                     e.printStackTrace();  
  235.                 }  
  236.             }//end for  
  237.         }  
  238.         System.out.println("");  
  239.         all.put("formatedFiledMap", formatedFiledMap);  
  240.         all.put("bitMap128", bitMap128);  
  241.         return all;  
  242.     }  
  243.       
  244.       
  245.   
  246.     /** 
  247.      * 解析8583报文 
  248.      *  
  249.      * @param content8583 
  250.      */  
  251.     public static Map analyze8583(byte[] content8583) {  
  252.         TreeMap filedMap=new TreeMap();  
  253.         try {  
  254.             // 取位图  
  255.             byte[] bitMap16byte = new byte[16];  
  256.             System.arraycopy(content8583, 0, bitMap16byte, 0, 16);  
  257.             // 16位图转2进制位图128位字符串  
  258.             String bitMap128Str = get16BitMapStr(bitMap16byte);  
  259.               
  260.             //记录当前位置,从位图后开始遍历取值   
  261.             int pos = 16;  
  262.             // 遍历128位图,取值。注意从FIELD002开始  
  263.             for (int i = 1; i < bitMap128Str.length(); i++) {  
  264.                 String filedValue = "";//字段值  
  265.                 String filedName = "FIELD" + getNumThree((i+1));//FIELD005  
  266.                   
  267.                 if (bitMap128Str.charAt(i) == '1') {  
  268.                     // 获取域定义信息  
  269.                     String[] fieldDef = Lsy8583Util.map8583Definition.get(filedName).toString().split(",");  
  270.                     String defType=fieldDef[0];//类型定义例string  
  271.                     String defLen=fieldDef[1];//长度定义,例20  
  272.                     boolean isFixLen=true;//是否定长判断  
  273.                       
  274.                     if(defLen.startsWith("VAR")){//变长域  
  275.                         isFixLen=false;  
  276.                         defLen=defLen.substring(3);//获取VAR2后面的2  
  277.                     }  
  278.                     // 截取该域信息  
  279.                     if (!isFixLen) {//变长域  
  280.                         int defLen1 = Integer.valueOf(defLen);//VAR2后面的2  
  281.                         String realLen1=new String(content8583, pos, defLen1, packet_encoding);//报文中实际记录域长,例如16,023  
  282.                         int realAllLen=defLen1+Integer.valueOf(realLen1);//该字段总长度(包括长度值占的长度)  
  283. //                      filedValue = new String(content8583, pos+defLen1, Integer.valueOf(realLen1), packet_encoding);  
  284.                         byte[] filedValueByte=new byte[Integer.valueOf(realLen1)];  
  285.                         System.arraycopy(content8583, pos+defLen1, filedValueByte, 0, filedValueByte.length);  
  286.                         filedValue=new String(filedValueByte,packet_encoding);  
  287.                         pos += realAllLen;//记录当前位置  
  288.                     } else {//定长域  
  289.                         int defLen2 = Integer.valueOf(defLen);//长度值占的位数  
  290.                         filedValue = new String(content8583, pos, defLen2, packet_encoding);  
  291.                         pos += defLen2;//记录当前位置  
  292.                     }  
  293.                     filedMap.put(filedName, filedValue);  
  294.                 }  
  295.             }//end for  
  296.         } catch (Exception e) {  
  297.             e.printStackTrace();  
  298.         }  
  299.         return filedMap;  
  300.     }  
  301.       
  302.     //********************************以下是工具方法,有些没有使用到***********************************************************//  
  303.   
  304.     /** 
  305.      * 复制字符 
  306.      * @param str 
  307.      * @param count 
  308.      * @return 
  309.      */  
  310.     public static String strCopy(String str,int count){  
  311.         StringBuffer sb = new StringBuffer();  
  312.         for(int i=0;i < count;i++){  
  313.             sb.append(str);  
  314.         }  
  315.         return sb.toString();  
  316.     }  
  317.     /** 
  318.      * 将setContent放入set(考虑到数组越界) 
  319.      * @param set 
  320.      * @param setContent 
  321.      * @return 
  322.      */  
  323.     public static byte[] setToByte(byte[] set,byte[] setContent){  
  324.         byte[] res=new byte[set.length];  
  325.         if(set==null||setContent==null){  
  326.               
  327.         }else{  
  328.             if(set.length<setContent.length){  
  329.                   
  330.             }else{  
  331.                 System.arraycopy(setContent, 0, res, 0, setContent.length);  
  332.             }  
  333.         }  
  334.         return res;  
  335.     }  
  336.     public static byte[] setToByte(byte[] set,String setContentStr){  
  337.         byte[] res=new byte[set.length];  
  338.         byte[] setContent;  
  339.         try {  
  340.             setContent = setContentStr.getBytes(packet_encoding);  
  341.             res=setToByte(res,setContent);  
  342.         } catch (UnsupportedEncodingException e) {  
  343.             e.printStackTrace();  
  344.         }  
  345.         return res;  
  346.     }  
  347.       
  348.     public static String getPacketLen(int len){  
  349.         String res="";  
  350.         String lenStr=String.valueOf(len);  
  351.         int lenC=4-lenStr.length();  
  352.         res=strCopy("0",lenC)+lenStr;  
  353.         return res;  
  354.     }  
  355.     public static String getPacketLen(String lenStr){  
  356.         String res="";  
  357.         if(lenStr==null){  
  358.               
  359.         }else{  
  360.             res=getPacketLen(Integer.valueOf(lenStr));  
  361.         }  
  362.         return res;  
  363.     }  
  364.       
  365.       
  366.     /** 
  367.      * 返回a和b的组合,实现累加功能 
  368.      * @param a 
  369.      * @param b 
  370.      * @return 
  371.      */  
  372.     public static byte[] arrayApend(byte[] a,byte[] b){  
  373.         int a_len=(a==null?0:a.length);  
  374.         int b_len=(b==null?0:b.length);  
  375.         byte[] c=new byte[a_len+b_len];  
  376.         if(a_len==0&&b_len==0){  
  377.             return null;  
  378.         }else if(a_len==0){  
  379.             System.arraycopy(b, 0, c, 0, b.length);  
  380.         }else if(b_len==0){  
  381.             System.arraycopy(a, 0, c, 0, a.length);  
  382.         }else{  
  383.             System.arraycopy(a, 0, c, 0, a.length);  
  384.             System.arraycopy(b, 0, c, a.length, b.length);  
  385.         }  
  386.         return c;  
  387.     }  
  388.       
  389.       
  390.     /** 
  391.      * 改变128位图中的标志为1 
  392.      * @param fieldNo 
  393.      * @param res 
  394.      * @return 
  395.      */  
  396.     public static String change16bitMapFlag(String fieldNo, String res) {  
  397.         int indexNo=Integer.parseInt(fieldNo);  
  398.         res = res.substring(0, indexNo-1) + "1" + res.substring(indexNo);  
  399.         return res;  
  400.     }  
  401.       
  402.       
  403.     /** 
  404.      * 位图操作  
  405.      *  
  406.      * 把16位图的字节数组转化成128位01字符串 
  407.      * @param packet_header_map 
  408.      * @return 
  409.      */  
  410.     public static String get16BitMapStr(byte[] bitMap16){  
  411.         String bitMap128 = "";  
  412.         // 16位图转2进制位图128位字符串  
  413.         for (int i = 0; i < bitMap16.length; i++) {  
  414.             int bc = bitMap16[i];  
  415.             bc=(bc<0)?(bc+256):bc;  
  416.             String bitnaryStr=Integer.toBinaryString(bc);//二进制字符串  
  417.             // 左补零,保证是8位  
  418.             String rightBitnaryStr = strCopy("0",Math.abs(8-bitnaryStr.length())) + bitnaryStr;//位图二进制字符串  
  419.             // 先去除多余的零,然后组装128域二进制字符串  
  420.             bitMap128+=rightBitnaryStr;  
  421.         }  
  422.         return bitMap128;  
  423.     }  
  424.       
  425.     /** 
  426.      *  位图操作  
  427.      *   
  428.      * 把128位01字符串转化成16位图的字节数组 
  429.      * @param packet_header_map 
  430.      * @return 
  431.      */  
  432.     public static byte[] get16BitByteFromStr(String str_128){  
  433.         byte[]  bit16=new byte[16];  
  434.         try {  
  435.             if(str_128==null||str_128.length()!=128){  
  436.                 return null;  
  437.             }  
  438.             // 128域位图二进制字符串转16位16进制  
  439.             byte[]  tmp=str_128.getBytes(packet_encoding);  
  440.             int weight;//权重  
  441.             byte[] strout = new byte[128];  
  442.             int i, j, w = 0;  
  443.             for (i = 0; i < 16; i++) {  
  444.                 weight = 0x0080;  
  445.                 for (j = 0; j < 8; j++) {  
  446.                     strout[i] += ((tmp[w]) - '0') * weight;  
  447.                     weight /= 2;  
  448.                     w++;  
  449.                 }  
  450.                 bit16[i] = strout[i];  
  451.             }  
  452.         } catch (UnsupportedEncodingException e) {  
  453.             e.printStackTrace();  
  454.         }  
  455.         return bit16;  
  456.     }  
  457.       
  458.       
  459.     /** 
  460.      * 从完整的8583报文中获取位图(16字节数组) 
  461.      * @param packet 
  462.      * @return 
  463.      */  
  464.     public static byte[] getPacketHeaderMap(byte[] packet){  
  465.         byte[] packet_header_map = new byte[16];  
  466.         if(packet==null||packet.length<16){  
  467.             return null;  
  468.         }  
  469.         for(int i=0;i<16;i++){  
  470.             packet_header_map[i]=packet[i];  
  471.         }  
  472.         return packet_header_map;  
  473.     }  
  474.     /** 
  475.      * 从完整的8583报文中获取16位图,转化成128位的01字符串 
  476.      *  
  477.      * @param content8583 
  478.      * @return 
  479.      */  
  480.     public static String get16BitMapFrom8583Byte(byte[] content8583){  
  481.         // 取位图  
  482.         byte[] bitMap16 = getPacketHeaderMap(content8583);  
  483.         // 16位图转2进制位图128位字符串  
  484.         String bitMap128 = get16BitMapStr(bitMap16);  
  485.           
  486.         return bitMap128;  
  487.     }  
  488.       
  489.   
  490.       
  491.     //返回字段号码,例如005  
  492.     public static String getNumThree(int i){  
  493.         String len="";  
  494.         String iStr=String.valueOf(i);  
  495.         len=strCopy("0",3-iStr.length())+iStr;  
  496.         return len;  
  497.     }  
  498.       
  499.     /** 
  500.      * 获取字符串变长值 
  501.      * @param valueStr 
  502.      * @param defLen 
  503.      * 例如getFixLengthValue("12345678", 2)返回08 
  504.      * 例如getFixLengthValue("12345678", 3)返回008 
  505.      *  
  506.      * 注意变长长度的计算: 
  507.      * 长度的判断使用转化后的字节数组长度,因为中文在不同的编码方式下,长度是不同的,GBK是2,UTF-8是3,按字符创长度算就是1. 
  508.      * 解析报文是按照字节来解析的,所以长度以字节长度为准,防止中文带来乱码。 
  509.      *  
  510.      * 比如一个变长域:aa索隆bb,如果按照字符串计算长度那么就是6,最后是06aa索隆bb。 
  511.      * 这样在解析时按照字节解析长度就乱了,因为按照GBK字节解析,一个汉字占2,按照UTF-8解析,一个汉字占3. 
  512.      * 所以在计算时必须按照字节长度为准!按照我们设置的UTF-8编码结果就是10aa索隆bb. 
  513.      * 这样在解析时长度正好是10,也就不会乱了。 
  514.      * @return 
  515.      */  
  516.     public static String getVaryLengthValue(String valueStr,int defLen){  
  517.         return getVaryLengthValue(valueStr,defLen,packet_encoding);  
  518.     }  
  519.     public static String getVaryLengthValue(String valueStr,int defLen,String encoding){  
  520.         String fixLen="";  
  521.         try{  
  522.             if(valueStr==null){  
  523.                 return strCopy("0",defLen);  
  524.             }else{  
  525.                 byte[] valueStrByte=null;  
  526.                 //这里最好指定编码,不使用平台默认编码  
  527.                 if(encoding==null||encoding.trim().equals("")){  
  528.                     valueStrByte=valueStr.getBytes();  
  529.                 }else{  
  530.                     valueStrByte=valueStr.getBytes(encoding);  
  531.                 }  
  532.                 //长度的判断使用转化后的字节数组长度,因为中文在不同的编码方式下,长度是不同的,GBK是2,UTF-8是3,按字符创长度算就是1.  
  533.                 //解析报文是按照字节来解析的,所以长度以字节长度为准,防止中文带来乱码  
  534.                 if(valueStrByte.length>(10*defLen)){  
  535.                     return null;  
  536.                 }else{  
  537.                     int len=valueStrByte.length;//字段实际长度  
  538.                     String len1=String.valueOf(len);  
  539.                     fixLen=strCopy("0",(defLen-len1.length()))+len1;  
  540.                 }  
  541.             }   
  542.         } catch (UnsupportedEncodingException e) {  
  543.             e.printStackTrace();  
  544.         }  
  545.         return fixLen;  
  546.     }  
  547.       
  548.     /** 
  549.      * 将字段值做定长处理,不足定长则在后面补空格 
  550.      * @param valueStr 
  551.      * @param defLen 
  552.      * @return 
  553.      */  
  554.     public static String getFixFieldValue(String valueStr,int defLen){  
  555.         return getFixFieldValue(valueStr,defLen,packet_encoding);  
  556.     }  
  557.     public static String getFixFieldValue(String valueStr,int defLen,String encoding){  
  558.         String fixLen="";  
  559.         try {  
  560.             if(valueStr==null){  
  561.                 return strCopy(" ",defLen);  
  562.             }else{  
  563.                 byte[] valueStrByte=null;  
  564.                 //这里最好指定编码,不使用平台默认编码  
  565.                 if(encoding==null||encoding.trim().equals("")){  
  566.                     valueStrByte=valueStr.getBytes();  
  567.                 }else{  
  568.                     valueStrByte=valueStr.getBytes(encoding);  
  569.                 }  
  570.                 //长度的判断使用转化后的字节数组长度,因为中文在不同的编码方式下,长度是不同的,GBK是2,UTF-8是3,按字符创长度算就是1.  
  571.                 //解析报文是按照字节来解析的,所以长度以字节长度为准,防止中文带来乱码  
  572.                 if(valueStrByte.length>defLen){  
  573.                     return null;  
  574.                 }else{  
  575.                     fixLen=valueStr+strCopy(" ",defLen-valueStrByte.length);  
  576.                 }  
  577.             }  
  578.         } catch (UnsupportedEncodingException e) {  
  579.             e.printStackTrace();  
  580.         }  
  581.           
  582.         return fixLen;  
  583.     }  
  584.       
  585.   
  586.     public static String getPacket_encoding() {  
  587.         return packet_encoding;  
  588.     }  
  589.   
  590.     public static void setPacket_encoding(String packet_encoding) {  
  591.         Lsy8583Util.packet_encoding = packet_encoding;  
  592.     }  
  593.   
  594.     public static Map getMap8583Definition() {  
  595.         return map8583Definition;  
  596.     }  
  597.   
  598.     public static void setMap8583Definition(Map map8583Definition) {  
  599.         Lsy8583Util.map8583Definition = map8583Definition;  
  600.     }  
  601.   
  602. }  

报文域配置文件:config_8583.properties

  1. FIELD002 = string,16  
  2. FIELD003 = string,4  
  3. FIELD004 = string,20  
  4. FIELD005 = string,20  
  5. FIELD006 = string,20  
  6. FIELD007 = string,10  
  7. FIELD008 = string,32  
  8. FIELD009 = string,3  
  9. FIELD010 = string,20  
  10. FIELD011 = string,6  
  11. FIELD012 = string,6  
  12. FIELD013 = string,10  
  13. FIELD014 = string,10  
  14. FIELD015 = string,10  
  15. FIELD016 = string,6  
  16. FIELD017 = string,6  
  17. FIELD018 = string,6  
  18. FIELD019 = string,6  
  19. FIELD020 = string,7  
  20. FIELD021 = string,7  
  21. FIELD022 = string,3  
  22. FIELD023 = string,3  
  23. FIELD024 = string,8  
  24. FIELD025 = string,5  
  25. FIELD026 = string,8  
  26. FIELD027 = string,1  
  27. FIELD028 = string,5  
  28. FIELD029 = string,5  
  29. FIELD030 = string,5  
  30. FIELD031 = string,10  
  31. FIELD032 = string,VAR2  
  32. FIELD033 = string,VAR2  
  33. FIELD034 = string,VAR2  
  34. FIELD035 = string,VAR2  
  35. FIELD036 = string,VAR3  
  36. FIELD037 = string,10  
  37. FIELD038 = string,4  
  38. FIELD039 = string,6  
  39. FIELD040 = string,2  
  40. FIELD041 = string,3  
  41. FIELD042 = string,16  
  42. FIELD043 = string,20  
  43. FIELD044 = string,VAR2  
  44. FIELD045 = string,VAR2  
  45. FIELD046 = string,VAR3  
  46. FIELD047 = string,VAR3  
  47. FIELD048 = string,VAR3  
  48. FIELD049 = string,3  
  49. FIELD050 = string,VAR3  
  50. FIELD051 = string,VAR3  
  51. FIELD052 = string,16  
  52. FIELD053 = string,VAR2  
  53. FIELD054 = string,VAR3  
  54. FIELD055 = string,VAR3  
  55. FIELD056 = string,VAR3  
  56. FIELD057 = string,VAR3  
  57. FIELD058 = string,VAR3  
  58. FIELD059 = string,VAR3  
  59. FIELD060 = string,VAR3  
  60. FIELD061 = string,VAR3  
  61. FIELD062 = string,VAR3  
  62. FIELD063 = string,VAR3  
  63. FIELD064 = string,16  
  64. FIELD065 = string,2  
  65. FIELD066 = string,1  
  66. FIELD067 = string,2  
  67. FIELD068 = string,16  
  68. FIELD069 = string,16  
  69. FIELD070 = string,3  
  70. FIELD071 = string,4  
  71. FIELD072 = string,2  
  72. FIELD073 = string,10  
  73. FIELD074 = string,10  
  74. FIELD075 = string,22  
  75. FIELD076 = string,17  
  76. FIELD077 = string,32  
  77. FIELD078 = string,VAR3  
  78. FIELD079 = string,6  
  79. FIELD080 = string,32  
  80. FIELD081 = string,32  
  81. FIELD082 = string,4  
  82. FIELD083 = string,4  
  83. FIELD084 = string,6  
  84. FIELD085 = string,15  
  85. FIELD086 = string,20  
  86. FIELD087 = string,20  
  87. FIELD088 = string,20  
  88. FIELD089 = string,6  
  89. FIELD090 = string,9  
  90. FIELD091 = string,9  
  91. FIELD092 = string,9  
  92. FIELD093 = string,VAR3  
  93. FIELD094 = string,2  
  94. FIELD095 = string,42  
  95. FIELD096 = string,8  
  96. FIELD097 = string,42  
  97. FIELD098 = string,3  
  98. FIELD099 = string,3  
  99. FIELD100 = string,80  
  100. FIELD101 = string,VAR3  
  101. FIELD102 = string,80  
  102. FIELD103 = string,80  
  103. FIELD104 = string,VAR3  
  104. FIELD105 = string,VAR3  
  105. FIELD106 = string,VAR3  
  106. FIELD107 = string,VAR3  
  107. FIELD108 = string,2  
  108. FIELD109 = string,VAR3  
  109. FIELD110 = string,9  
  110. FIELD111 = string,VAR3  
  111. FIELD112 = string,VAR3  
  112. FIELD113 = string,VAR3  
  113. FIELD114 = string,VAR3  
  114. FIELD115 = string,3  
  115. FIELD116 = string,VAR3  
  116. FIELD117 = string,VAR3  
  117. FIELD118 = string,VAR3  
  118. FIELD119 = string,VAR3  
  119. FIELD120 = string,VAR3  
  120. FIELD121 = string,32  
  121. FIELD122 = string,VAR3  
  122. FIELD123 = string,VAR3  
  123. FIELD124 = string,VAR3  
  124. FIELD125 = string,VAR3  
  125. FIELD126 = string,VAR3  
  126. FIELD127 = string,VAR3  
  127. FIELD128 = string,8  


简单说下,

FIELD031 = string,10
FIELD032 = string,VAR2

string代表域值类型(我只用到了string,别的就没定义了),10表示该域是定长10位。

如果是变长就定义成var,后面的2表示变长长度占2位,那么域最大就是99位。

 


运行打印结果:

  1. /D:/AppleZero/workSpace/apple/target/classes/  
  2. Lsy8583Util使用编码配置:[encoding:UTF-8]  
  3. 组装后报文域 {FIELD003}==1799==,域长度:4  
  4. 组装后报文域 {FIELD008}==12345678901                     ==,域长度:32  
  5. 组装后报文域 {FIELD013}==2013-11-06==,域长度:10  
  6. 组装后报文域 {FIELD033}==10aa索隆bb==,域长度:12  
  7. 组装后报文域 {FIELD036}==006123456==,域长度:9  
  8.   
  9. 完成组装8583报文==?  

打印的有些字节复制出来就看不到了,我把控制台打印截图吧。


  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多