第一种实现方式分为三步:
第三步:封装请求
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