8583報文組裝解析工具和定義器示例
阿新 • • 發佈:2018-12-16
8583報文組裝和解析工具類(Send8583Util),程式碼如下:
import com.alibaba.fastjson.JSONObject; import org.apache.commons.lang.CharEncoding; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.FileInputStream; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.util.*; /** * * ISO8583報文工具類,包含了報文的組裝和解析。 * 簡單介紹下ISO8583。 * 這個東西說白了就是一種資料結構。我們定義一種規則把一堆東西放進去,再按照規則 * 把資料正確拿出來。這就是報文的實質。 * ISO8583報文的結構是:前面有16位元組(128位)點陣圖資料,後面就是資料。 * 報文最多有128個域(欄位)。具體的一個報文不會有這麼多,一般是幾個域。 * 有哪幾個就記錄在點陣圖中。而且域有定長和變長之分。 * 這些都是事先定義好的,具體可以看我寫的properties定義檔案. * 點陣圖轉化成01字串就是128個,如果某一位是1,代表這個域有值,然後按照properties定義的規則取值。 * 如果是0,則這個域沒有值。 * 再說定長和變長。 * 定長域(定長比較好理解,一個欄位規定是N位,那麼欄位值絕對不能超過N位,不足N位就在後面補空格) * 變長域(變長域最後組裝成的效果:例如變長3位,定義var3,這裡的3是指長度值佔3位,欄位值是123456,最後結果就是006123456) * 注意(變長的長度按照域值得位元組長度計算,而不是按照域值字串長度算!) * 從網上不難找到ISO8583報文的介紹,這裡就不多說了。 * 但是具體解析和組裝的程式碼還真不好找,所以本人就寫了一個讓剛接觸ISO8583報文的人更好入門。 * 解析的容器,我使用了Map,具體到工作中,還是要換成其他的容器的。 * 報文定義說明:config_8583.properties * 例如 * FIELD031 = string,10 * FIELD032 = string,VAR2 * * FIELD031是定長,長度是10 * FIELD032是變長,長度值佔2位,也就是說長度值最大99,也就是域值最大長度99. */ public class Send8583Util { private static final Logger log = LoggerFactory.getLogger(Send8583Util.class); public static String default_encoding = CharEncoding.UTF_8;//報文編碼 UTF-8 GBK /** * @param args */ public static void main(String[] args) throws Exception{ try { String basepath=Send8583Util.class.getClassLoader().getResource("").getPath(); String path = basepath+"/config_8583.properties"; Map config8583Map = get8583Config(path); // =====================方式二:通過資料Map組裝8583報文和解析報文 System.out.println("=====================方式二:通過資料Map組裝8583報文和解析報文"); //***********************組裝8583報文測試--start***********************// Map dataMap=new HashMap();//報文域 dataMap.put("flow_no", System.currentTimeMillis()); dataMap.put("trad_code", "1799");//交易碼 dataMap.put("acc_no", "12345678901");//賬號 dataMap.put("trad_time", "2013-11-06");//交易日期 dataMap.put("content", "aa索隆bb");//注意這個域是變長域! dataMap.put("remark", "123456");//注意這個域是變長域! System.out.println("初始內容報文:"+ JSONObject.toJSONString(dataMap)); String message = package8583(dataMap, config8583Map); System.out.println("8583報文:"+message); //***********************組裝8583報文測試--end***********************// //***********************解析8583報文測試--start***********************// Map map=analyze8583(message, config8583Map); System.out.println("完成解析8583報文:"+map.toString()); //***********************解析8583報文測試--end***********************// // =====================方式三:通過域欄位Map組裝8583報文和解析報文 System.out.println(); System.out.println("=====================方式三:通過域欄位Map組裝8583報文和解析報文"); //***********************組裝8583報文測試--start***********************// TreeMap filedMap=new TreeMap();//報文域 filedMap.put("FIELD001", System.currentTimeMillis()); filedMap.put("FIELD003", "1799");//交易碼 filedMap.put("FIELD008", "12345678901");//賬號 filedMap.put("FIELD013", "2013-11-06");//交易日期 filedMap.put("FIELD033", "aa索隆bb");//注意這個域是變長域! filedMap.put("FIELD036", "123456");//注意這個域是變長域! System.out.println("初始內容報文:"+ JSONObject.toJSONString(filedMap)); byte[] send=make8583(filedMap, config8583Map); System.out.println("最終8583報文:"+new String(send,default_encoding)+"====="+new String(send,default_encoding).length()); //***********************組裝8583報文測試--end***********************// //***********************解析8583報文測試--start***********************// Map back=analyze8583(send, config8583Map); System.out.println("完成解析8583報文:"+back.toString()); //***********************解析8583報文測試--end***********************// } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } // 8583報文初始點陣圖:128位01字串 public static String getInitBitMap(){ String initBitMap = "00000000" + "00000000" + "00000000" + "00000000" + "00000000" + "00000000" + "00000000" + "00000000" + "00000000" + "00000000" + "00000000" + "00000000" + "00000000" + "00000000" + "00000000" + "00000000"; return initBitMap; } /** * 獲取8583報文定義器 * @param realPath * @return */ public static Map get8583Config(String realPath) { Properties property = new Properties(); FileInputStream fis; try { fis = new FileInputStream(realPath); property.load(fis); fis.close(); return new HashMap(property); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 根據實體bean和8583報文定義器-----組裝8583報文 * @param bean 實體bean * @param config8583Map 8583報文定義器 * @return * @throws Exception */ public static String package8583(Object bean, Map config8583Map) throws Exception{ if(bean == null){ return null; } if(config8583Map == null){ return null; } // 從8583報文定義器中獲取屬性名與域欄位名對應的Map Map attributeMap = getAttributeMap(config8583Map); if(attributeMap == null || attributeMap.size() == 0){ return null; } // 待組裝的報文 TreeMap fieldMap = new TreeMap<>(); try { // 遍歷bean的屬性 Class clazz = bean.getClass(); // 獲取屬性集合 Field[] fields = clazz.getDeclaredFields(); for(Field field : fields){ field.setAccessible(true); // 設定這些屬性是可以訪問的 String attributeName = field.getName(); // 屬性名 Object value = field.get(bean); // 屬性值 if(value != null && StringUtil.isNotEmpty(String.valueOf(value))){ // 如果定義器中存在改屬性,則將屬性名對應的域欄位名與屬性值放入待組裝報文的Map中 if(attributeMap.containsKey(attributeName)){ fieldMap.put(attributeMap.get(attributeName), value); } } } if(fieldMap.size() > 0){ // 組裝8583報文 byte[] send = make8583(fieldMap, config8583Map); return Base64Util.encode(new String(send, CharEncoding.ISO_8859_1), CharEncoding.UTF_8); } }catch (Exception e){ e.printStackTrace(); } return null; } /** * 根據map和8583報文定義器-----組裝8583報文 * @param dataMap 資料Map * @param config8583Map 8583報文定義器 * @return * @throws Exception */ public static String package8583(Map dataMap, Map config8583Map) throws Exception{ if(dataMap == null){ return null; } if(config8583Map == null){ return null; } // 從8583報文定義器中獲取屬性名與域欄位名對應的Map Map attributeMap = getAttributeMap(config8583Map); if(attributeMap == null || attributeMap.size() == 0){ return null; } // 待組裝的報文 TreeMap fieldMap = new TreeMap<>(); try { // 遍歷dataMap Iterator it = dataMap.keySet().iterator(); for(;it.hasNext();){ // 屬性名 String key = (String) it.next(); // 屬性值 Object value = dataMap.get(key); if(value != null && StringUtil.isNotEmpty(String.valueOf(value))){ // 如果定義器中存在改屬性,則將屬性名對應的域欄位名與屬性值放入待組裝報文的Map中 if(attributeMap.containsKey(key)){ fieldMap.put(attributeMap.get(key), value); } } } if(fieldMap.size() > 0){ // 組裝8583報文 byte[] send = make8583(fieldMap, config8583Map); return Base64Util.encode(new String(send, CharEncoding.ISO_8859_1), CharEncoding.UTF_8); } }catch (Exception e){ e.printStackTrace(); } return null; } /** * 根據8583報文定義器-----解析8583報文 * @param message 8583報文 * @param config8583Map 8583報文定義器 * @return * @throws Exception */ public static Map analyze8583(String message, Map config8583Map) throws Exception{ Map dataMap = new HashMap(); if(StringUtil.isEmpty(message)){ return null; } if(config8583Map == null){ return null; } // 從8583報文定義器中獲取域欄位名與屬性名對應的Map Map fieldMap = getFieldMap(config8583Map); if(fieldMap == null || fieldMap.size() == 0){ return null; } try { // 解碼 message = Base64Util.decode(message, CharEncoding.UTF_8); // 8583報文位元組陣列 byte[] content8583 = message.getBytes(CharEncoding.ISO_8859_1); // 解析8583報文 Map map = analyze8583(content8583, config8583Map); if(map != null && map.size() > 0){ Iterator it = map.keySet().iterator(); for(;it.hasNext();) { // 域欄位名 String key = (String) it.next(); // 屬性值 Object value = map.get(key); // 如果定義器中存在該域欄位,則將域欄位名對應的屬性名與屬性值放入dataMap中 if (fieldMap.containsKey(key)) { dataMap.put(fieldMap.get(key), value); } } } return dataMap; }catch (Exception e){ e.printStackTrace(); } return dataMap; } /** * 組裝8583報文 * @param filedMap 域欄位名與屬性值的Map * @param config8583Map 8583定義器 * @return */ public static byte[] make8583(TreeMap filedMap, Map config8583Map){ byte[] whoe8583=null; if(filedMap==null){ return null; } try { String bitMap128=getInitBitMap();//獲取初始化的128點陣圖 // 按照8583定義器格式化各個域的內容 Map all=formatValueTo8583(filedMap, bitMap128, config8583Map); // 獲取上送報文內容 whoe8583=getWhole8583Packet(all); return whoe8583; } catch (Exception e) { e.printStackTrace(); } return whoe8583; } /** * 獲取完整的8583報文體(128域) * @param all * @return */ public static byte[] getWhole8583Packet(Map all){ if(all==null||all.get("formatedFiledMap")==null||all.get("bitMap128")==null){ return null; } try { String bitMap128=(String)all.get("bitMap128"); System.out.println("組裝點陣圖:"+bitMap128); // 128域點陣圖二進位制字串轉16位16進位制 byte[] bitmaps= get16BitByteFromStr(bitMap128); log.info("組裝點陣圖:{}", bitMap128); TreeMap pacBody=(TreeMap)all.get("formatedFiledMap"); StringBuffer last128=new StringBuffer(); Iterator it=pacBody.keySet().iterator(); for(;it.hasNext();){ String key=(String)it.next(); String value=(String)pacBody.get(key); last128.append(value); } byte[] bitContent = last128.toString().getBytes(default_encoding);//域值 //System.out.println("資料:"+last128.toString()+"---"+last128.length()); //組裝 byte[] package8583=null; package8583= Send8583Util.arrayApend(package8583, bitmaps); package8583= Send8583Util.arrayApend(package8583, bitContent); return package8583; } catch (Exception e) { e.printStackTrace(); return null; } } /** * 按照8583定義器格式化各個域的內容 * @param filedMap 域欄位名與屬性值的Map * @param bitMap128 128點陣圖 * @param config8583Map 8583定義器 * @return */ public static Map formatValueTo8583(TreeMap filedMap, String bitMap128, Map config8583Map){ Map all=new HashMap(); TreeMap formatedFiledMap=new TreeMap();//格式化結果 if(filedMap!=null){ Iterator it=filedMap.keySet().iterator(); for(;it.hasNext();){ String fieldName=(String) it.next();//例如FIELD005 String fieldValue= String.valueOf(filedMap.get(fieldName));//欄位值 try{ if (fieldValue == null) { log.error("error:報文域 {}為空值", fieldName); return null; } //將域值編碼轉換,保證報文編碼統一 fieldValue=new String(fieldValue.getBytes(default_encoding), default_encoding); // 資料域名稱FIELD開頭的為128域 if (fieldName.startsWith("FIELD") && fieldValue.length() >= 0) { String fieldNo = fieldName.substring(5, 8);//例如005 // 組二進位制點陣圖串(該域欄位存在時更新128點陣圖) bitMap128 = change16bitMapFlag(fieldNo, bitMap128); // 獲取域定義資訊 String[] fieldDef = config8583Map.get("FIELD" + fieldNo).toString().split(","); String defType=fieldDef[0];//型別定義例string String defLen=fieldDef[1];//長度定義,例20 boolean isFixLen=true;//是否定長判斷 if(defLen.startsWith("VAR")){//變長域 isFixLen=false; defLen=defLen.substring(3);//獲取VAR後面的數字 } // 欄位值得實際長度(UTF-8下的位元組長度) int fieldLen = fieldValue.getBytes(default_encoding).length; // 判斷是否為變長域 if (!isFixLen) { // 變長域(變長域最後組裝成的效果:例如變長3位,定義var3,這裡的3是指長度值佔3位,欄位值是123456,最後結果就是006123456) int defLen1 = Integer.valueOf(defLen); // 最大位元組數 int maxdefLen = Integer.valueOf(strCopy("9", defLen1)); if (fieldLen > maxdefLen) { log.error("error:欄位{}的資料定義長度的長度為{}位,長度不能超過{}", fieldName, fieldLen, maxdefLen); return null; }else{ //將長度值組裝入欄位 fieldValue = getVaryLengthValue(fieldValue, defLen1) + fieldValue; } } else { //定長域(定長比較好理解,一個欄位規定是N位,那麼欄位值絕對不能超過N位,不足N位就在後面補空格) int defLen2 = Integer.valueOf(defLen); if (fieldLen > defLen2) { log.error("error:欄位{}的資料定義長度為{}位,長度不能超過{}", fieldName, fieldLen, defLen2); return null; }else{ fieldValue=getFixFieldValue(fieldValue,defLen2);//定長處理 } } log.info("組裝後報文域 {}=={}==,域長度:{}", fieldName, fieldValue,fieldValue.getBytes(default_encoding).length); } // 返回結果賦值 if (filedMap.containsKey(fieldName)) { if (formatedFiledMap.containsKey(fieldName)) { formatedFiledMap.remove(fieldName); } formatedFiledMap.put(fieldName, fieldValue); } else { log.error("error:{}配置檔案中不存在!", fieldName); } } catch (Exception e) { e.printStackTrace(); } }//end for } System.out.println(""); all.put("formatedFiledMap", formatedFiledMap); all.put("bitMap128", bitMap128); return all; } /** * 解析8583報文 * @param content8583 */ public static Map analyze8583(byte[] content8583, Map config8583Map) { TreeMap filedMap=new TreeMap(); if(config8583Map == null){ return null; } try { // 取點陣圖 byte[] bitMap16byte = new byte[16]; System.arraycopy(content8583, 0, bitMap16byte, 0, 16); // 16點陣圖轉2進位制點陣圖128位字串 String bitMap128Str = get16BitMapStr(bitMap16byte); System.out.println("解析點陣圖:"+bitMap128Str); log.info("解析點陣圖:{}", bitMap128Str); //記錄當前位置,從點陣圖後開始遍歷取值 int pos = 16; // 遍歷128點陣圖,取值。注意從FIELD001開始 for (int i = 0; i < bitMap128Str.length(); i++) { String filedValue = "";//欄位值 String filedName = "FIELD" + getNumThree((i+1)); // FIELD001 if (bitMap128Str.charAt(i) == '1') { // 獲取域定義資訊 String[] fieldDef = config8583Map.get(filedName).toString().split(","); String defType=fieldDef[0];//型別定義例string String defLen=fieldDef[1];//長度定義,例20 boolean isFixLen=true;//是否定長判斷 if(defLen.startsWith("VAR")){//變長域 isFixLen=false; defLen=defLen.substring(3);//獲取VAR2後面的2 } // 擷取該域資訊 if (!isFixLen) {//變長域 int defLen1 = Integer.valueOf(defLen); //VAR後面的2 //報文中實際記錄域長,例如16,023 String realLen1=new String(content8583, pos, defLen1, default_encoding); //該欄位總長度(包括長度值佔的長度) int realAllLen=defLen1+Integer.valueOf(realLen1); byte[] filedValueByte=new byte[Integer.valueOf(realLen1)]; System.arraycopy(content8583, pos+defLen1, filedValueByte, 0, filedValueByte.length); filedValue=new String(filedValueByte,default_encoding); pos += realAllLen;//記錄當前位置 } else {//定長域 int defLen2 = Integer.valueOf(defLen);//長度值佔的位數 filedValue = new String(content8583, pos, defLen2, default_encoding).trim(); pos += defLen2;//記錄當前位置 } filedMap.put(filedName, filedValue); } }//end for } catch (Exception e) { e.printStackTrace(); } return filedMap; } //********************************以下是工具方法,有些沒有使用到***********************************************************// /** * 複製字元 * @param str * @param count * @return */ public static String strCopy(String str,int count){ StringBuffer sb = new StringBuffer(); for(int i=0;i < count;i++){ sb.append(str); } return sb.toString(); } /** * 將setContent放入set(考慮到陣列越界) * @param set * @param setContent * @return */ public static byte[] setToByte(byte[] set,byte[] setContent){ byte[] res=new byte[set.length]; if(set==null||setContent==null){ }else{ if(set.length<setContent.length){ }else{ System.arraycopy(setContent, 0, res, 0, setContent.length); } } return res; } public static byte[] setToByte(byte[] set,String setContentStr){ byte[] res=new byte[set.length]; byte[] setContent; try { setContent = setContentStr.getBytes(default_encoding); res=setToByte(res,setContent); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return res; } public static String getPacketLen(int len){ String res=""; String lenStr=String.valueOf(len); int lenC=4-lenStr.length(); res=strCopy("0",lenC)+lenStr; return res; } public static String getPacketLen(String lenStr){ String res=""; if(lenStr==null){ }else{ res=getPacketLen(Integer.valueOf(lenStr)); } return res; } /** * 返回a和b的組合,實現累加功能 * @param a * @param b * @return */ public static byte[] arrayApend(byte[] a,byte[] b){ int a_len=(a==null?0:a.length); int b_len=(b==null?0:b.length); byte[] c=new byte[a_len+b_len]; if(a_len==0&&b_len==0){ return null; }else if(a_len==0){ System.arraycopy(b, 0, c, 0, b.length); }else if(b_len==0){ System.arraycopy(a, 0, c, 0, a.length); }else{ System.arraycopy(a, 0, c, 0, a.length); System.arraycopy(b, 0, c, a.length, b.length); } return c; } /** * 改變128點陣圖中的標誌為1 * @param fieldNo * @param res * @return */ public static String change16bitMapFlag(String fieldNo, String res) { int indexNo=Integer.parseInt(fieldNo); res = res.substring(0, indexNo-1) + "1" + res.substring(indexNo); return res; } /** * 點陣圖操作 * * 把16點陣圖的位元組陣列轉化成128位01字串 * @param bitMap16 * @return */ public static String get16BitMapStr(byte[] bitMap16){ String bitMap128 = ""; // 16點陣圖轉2進位制點陣圖128位字串 for (int i = 0; i < bitMap16.length; i++) { int bc = bitMap16[i]; bc=(bc<0)?(bc+256):bc; String bitnaryStr=Integer.toBinaryString(bc);//二進位制字串 // 左補零,保證是8位 String rightBitnaryStr = strCopy("0",Math.abs(8-bitnaryStr.length())) + bitnaryStr;//點陣圖二進位制字串 // 先去除多餘的零,然後組裝128域二進位制字串 bitMap128+=rightBitnaryStr; } return bitMap128; } /** * 點陣圖操作 * * 把128位01字串轉化成16點陣圖的位元組陣列 * @param str_128 * @return */ public static byte[] get16BitByteFromStr(String str_128){ byte[] bit16=new byte[16]; try { if(str_128==null||str_128.length()!=128){ return null; } // 128域點陣圖二進位制字串轉16位16進位制 byte[] tmp=str_128.getBytes(default_encoding); int weight;//權重 byte[] strout = new byte[128]; int i, j, w = 0; for (i = 0; i < 16; i++) { weight = 0x0080; for (j = 0; j < 8; j++) { strout[i] += ((tmp[w]) - '0') * weight; weight /= 2; w++; } bit16[i] = strout[i]; } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return bit16; } /** * 從完整的8583報文中獲取點陣圖(16位元組陣列) * @param packet * @return */ public static byte[] getPacketHeaderMap(byte[] packet){ byte[] packet_header_map = new byte[16]; if(packet==null||packet.length<16){ return null; } for(int i=0;i<16;i++){ packet_header_map[i]=packet[i]; } return packet_header_map; } /** * 從完整的8583報文中獲取16點陣圖,轉化成128位的01字串 * * @param content8583 * @return */ public static String get16BitMapFrom8583Byte(byte[] content8583){ // 取點陣圖 byte[] bitMap16 = getPacketHeaderMap(content8583); // 16點陣圖轉2進位制點陣圖128位字串 String bitMap128 = get16BitMapStr(bitMap16); return bitMap128; } //返回欄位號碼,例如005 public static String getNumThree(int i){ String len=""; String iStr=String.valueOf(i); len=strCopy("0",3-iStr.length())+iStr; return len; } /** * 獲取字串變長值 * @param valueStr * @param defLen * 例如getFixLengthValue("12345678", 2)返回08 * 例如getFixLengthValue("12345678", 3)返回008 * * 注意變長長度的計算: * 長度的判斷使用轉化後的位元組陣列長度,因為中文在不同的編碼方式下,長度是不同的,GBK是2,UTF-8是3,按字元創長度算就是1. * 解析報文是按照位元組來解析的,所以長度以位元組長度為準,防止中文帶來亂碼。 * * 比如一個變長域:aa索隆bb,如果按照字串計算長度那麼就是6,最後是06aa索隆bb。 * 這樣在解析時按照位元組解析長度就亂了,因為按照GBK位元組解析,一個漢字佔2,按照UTF-8解析,一個漢字佔3. * 所以在計算時必須按照位元組長度為準!按照我們設定的UTF-8編碼結果就是10aa索隆bb. * 這樣在解析時長度正好是10,也就不會亂了。 * @return */ public static String getVaryLengthValue(String valueStr,int defLen){ return getVaryLengthValue(valueStr,defLen,default_encoding); } public static String getVaryLengthValue(String valueStr,int defLen,String encoding){ String fixLen=""; try{ if(valueStr==null){ return strCopy("0",defLen); }else{ byte[] valueStrByte=null; //這裡最好指定編碼,不使用平臺預設編碼 if(encoding==null||encoding.trim().equals("")){ valueStrByte=valueStr.getBytes(); }else{ valueStrByte=valueStr.getBytes(encoding); } //長度的判斷使用轉化後的位元組陣列長度,因為中文在不同的編碼方式下,長度是不同的,GBK是2,UTF-8是3,按字元創長度算就是1. //解析報文是按照位元組來解析的,所以長度以位元組長度為準,防止中文帶來亂碼 // 最大位元組數 int maxdefLen = Integer.valueOf(strCopy("9", defLen)); if(valueStrByte.length > maxdefLen){ return null; }else{ int len=valueStrByte.length;//欄位實際長度 String len1=String.valueOf(len); fixLen=strCopy("0", (defLen-len1.length())) + len1; } } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return fixLen; } /** * 將欄位值做定長處理,不足定長則在後面補空格 * @param valueStr * @param defLen * @return */ public static String getFixFieldValue(String valueStr,int defLen){ return getFixFieldValue(valueStr,defLen,default_encoding); } public static String getFixFieldValue(String valueStr,int defLen,String encoding){ String fixLen=""; try { if(valueStr==null){ return strCopy(" ",defLen); }else{ byte[] valueStrByte=null; //這裡最好指定編碼,不使用平臺預設編碼 if(encoding==null||encoding.trim().equals("")){ valueStrByte=valueStr.getBytes(); }else{ valueStrByte=valueStr.getBytes(encoding); } //長度的判斷使用轉化後的位元組陣列長度,因為中文在不同的編碼方式下,長度是不同的,GBK是2,UTF-8是3,按字元創長度算就是1. //解析報文是按照位元組來解析的,所以長度以位元組長度為準,防止中文帶來亂碼 if(valueStrByte.length > defLen){ return null; }else{ fixLen=valueStr+strCopy(" ",defLen-valueStrByte.length); } } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return fixLen; } /** * 獲取8583報文定義器中屬性名與域欄位名的Map * @param config8583Map * @return */ public static Map<String, String> getAttributeMap(Map config8583Map){ Map<String, String> map = new HashMap<>(); Iterator it = config8583Map.keySet().iterator(); for(;it.hasNext();){ // 域欄位名 String fieldName = (String) it.next(); // 域欄位值 String fieldValue = (String) config8583Map.get(fieldName); // 獲取域定義資訊 String[] fieldDef = fieldValue.split(","); String defType = fieldDef[0]; // 型別定義,例如:string String defLen = fieldDef[1]; // 長度定義,例如:定長 20 String attributeName = fieldDef[2]; // 報文屬性名稱 if(StringUtil.isNotEmpty(attributeName)){ map.put(attributeName, fieldName); } } return map; } /** * 獲取8583報文定義器中域欄位名與屬性名的Map * @param config8583Map * @return */ public static Map<String, String> getFieldMap(Map config8583Map){ Map<String, String> map = new HashMap<>(); Iterator it = config8583Map.keySet().iterator(); for(;it.hasNext();){ // 域欄位名 String fieldName = (String) it.next(); // 域欄位值 String fieldValue = (String) config8583Map.get(fieldName); // 獲取域定義資訊 String[] fieldDef = fieldValue.split(","); String defType = fieldDef[0]; // 型別定義,例如:string String defLen = fieldDef[1]; // 長度定義,例如:定長 20 String attributeName = fieldDef[2]; // 報文屬性名稱 if(StringUtil.isNotEmpty(attributeName)){ map.put(fieldName, attributeName); } } return map; } }
8583報文定義器(config_8583.properties):
FIELD001 = string,16,flow_no
FIELD002 = string,16,card_no
FIELD003 = string,4,trad_code
FIELD008 = string,32,acc_no
FIELD013 = string,10,trad_time
FIELD033 = string,VAR2,content
FIELD036 = string,VAR3,remark
Base64Util編碼解碼工具:
import org.apache.commons.lang.CharEncoding; import org.apache.commons.lang.StringUtils; import org.apache.tomcat.util.codec.binary.Base64; import java.io.UnsupportedEncodingException; public class Base64Util { /** * 編碼字串 * @param str * @return */ public static String encode(String str, String encoding){ if(StringUtils.isEmpty(str)) return ""; if(StringUtil.isEmpty(encoding)){ encoding = CharEncoding.UTF_8; } try { return Base64.encodeBase64String(str.getBytes(encoding)); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return ""; } /** * 解碼字串 * @param str * @return */ public static String decode(String str, String encoding){ if(StringUtils.isEmpty(str)) return ""; if(StringUtil.isEmpty(encoding)){ encoding = CharEncoding.UTF_8; } try { return new String(Base64.decodeBase64(str), encoding); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } }