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,如果有需要請移步下載,如果覺得還可以,請給個贊。如果有任何問題,歡迎留言,我會及時回復。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM