很久没来csdn了。现在的工作地点在银行,妈的,不让上网啊。
写写博客其实是对自己知识的总结,这么长时间了,也该写点东西了。接触银行的项目,避免不了
遇上8583报文。具体介绍就不细讲了,这个网上一大堆介绍的。关键是怎么去组装和解析8583报文?
这个代码还真不好找。在此,我把自己的研究写成一个工具类,看的懂其实很好改写,看不懂就直接拿去用吧。
package com.lsy.common.util;
import java.io.FileInputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
/**
*
* 这是本人写的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.
*
* @author lushuaiyin
*
*/
public class Lsy8583Util {
public static String packet_encoding="UTF-8";//报文编码 UTF-8 GBK
private static Map map8583Definition = null;// 8583报文128域定义器
static{
String basepath=Lsy8583Util.class.getClassLoader().getResource("").getPath();
System.out.println(basepath);
System.out.println("Lsy8583Util使用编码配置:[encoding:"+packet_encoding+"]");
Properties property = new Properties();
String path = basepath+"/config_8583.properties";
FileInputStream fis;
try {
fis = new FileInputStream(path);
property.load(fis);
Lsy8583Util.map8583Definition = new HashMap(property);
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// 8583报文初始位图:128位01字符串
public static String getInitBitMap(){
String initBitMap =
"10000000" + "00000000" + "00000000" + "00000000"
+ "00000000" + "00000000" + "00000000" + "00000000"
+ "00000000" + "00000000" + "00000000" + "00000000"
+ "00000000" + "00000000" + "00000000" + "00000000";
return initBitMap;
}
/**
* @param args
*/
public static void main(String[] args) {
try {
//***********************组装8583报文测试--start***********************//
TreeMap filedMap=new TreeMap();//报文域
filedMap.put("FIELD003", "1799");//交易码
filedMap.put("FIELD013", "2013-11-06");//交易日期
filedMap.put("FIELD008", "12345678901");//账号
filedMap.put("FIELD033", "aa索隆bb");//注意这个域是变长域!
filedMap.put("FIELD036", "123456");//注意这个域是变长域!
byte[] send=make8583(filedMap);
System.out.println("完成组装8583报文=="+new String(send,packet_encoding)+"==");
//***********************组装8583报文测试--end***********************//
//***********************解析8583报文测试--start***********************//
Map back=analyze8583(send);
System.out.println("完成解析8583报文=="+back.toString()+"==");
//***********************解析8583报文测试--end***********************//
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* 组装8583报文
* @param hm
* @return
*/
public static byte[] make8583(TreeMap filedMap){
byte[] whoe8583=null;
if(filedMap==null){
return null;
}
try {
String bitMap128=getInitBitMap();//获取初始化的128位图
//按照8583定义器格式化各个域的内容
Map all=formatValueTo8583(filedMap,bitMap128);
// 获取上送报文内容
whoe8583=getWhole8583Packet(all);
return whoe8583;
} catch (Exception e) {
e.printStackTrace();
}
return whoe8583;
}
/**
* 获取完整的8583报文体(128域)
* @param pacBody
* @return
*/
public static byte[] getWhole8583Packet(Map all){
if(all==null||a