JAVA XML \ 定长报文 与domino转换及通讯

项目下载地址: https://download.csdn.net/download/chouyan1884/10692331

1. 项目目录

在这里插入图片描述

	目录描述:
	talent.client:通讯客户端
	talent.server : 通讯服务端
	talent.entity : domino对象
		talent.entity.fixed : domino对象与定长报文转换对象
		talent.entity.xml : domino对象与XML转换对象
	talent.util : domino对象与 XML \ 定长报文转换工具类

2. XML 与 domino 对象转换

1、 相关依赖

XML 与 domino 对象转换使用 JAXB,项目如果使用的JDK是1.8以下,需引入java 1.8的 rt.jar ;项目使用的JDK为1.8以上,可以直接使用 JAXB API。
在这里插入图片描述

2、 domino 代码编写
package talent.entity.xml.req;

import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "BODY")
@XmlAccessorType(XmlAccessType.FIELD)
public class ReqBody implements Serializable{

	private static final long serialVersionUID = 1L;
	
}

XML根目录对象 @XmlRootElement(name = “BODY”) ,BODY为根目录

package talent.entity.xml.req.impl;

import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import talent.entity.xml.req.ReqBody;
import talent.entity.xml.req.impl.ext.Req100004DetailsExt;
import talent.entity.xml.req.impl.ext.Req100004SumExt;

@XmlRootElement(name = "BODY")
@XmlAccessorType(XmlAccessType.FIELD)
public class Req100004Impl extends ReqBody {
	/**
	 */
	private static final long serialVersionUID = 1L;
	
	@XmlElement(name = "TRANS_SUM")
	private Req100004SumExt sumExt;
	@XmlElementWrapper(name = "TRANS_DETAILS")
	@XmlElement(name = "TRANS_DETAIL")
	private List<Req100004DetailsExt> detailsExt;
	
	 .........
 	get set 方法
 	.........
}
package talent.entity.xml.req.impl.ext;

import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.FIELD)
public class Req100004SumExt implements Serializable{

	private static final long serialVersionUID = 1L;
	
	/** 业务代码 */
	@XmlElement
	private String BUSINESS_CODE;
	/** 提交时间 */
	@XmlElement
	private String SUBMIT_TIME;
	/** 总记录数 */
	@XmlElement
	private String TOTAL_ITEM;
	/** 总金额 */
	@XmlElement
	private String TOTAL_SUM;

 	.........
 	get set 方法
 	.........
}
package talent.entity.xml.req.impl.ext;

import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.FIELD)
public class Req100004DetailsExt implements Serializable{

	private static final long serialVersionUID = 1L;
	/**
	 * 账号
	 */
	@XmlElement
	private String ACCOUNT_NO;
	/**
	 * 账号名
	 */
	@XmlElement
	private String ACCOUNT_NAME;
 	.........
 	get set 方法
 	.........
}

XML节点对象

3、domino 对象转换为 XML
public static String beanToXML(Object obj, String encoding, boolean noheader) throws JAXBException {
		String result = null;
		JAXBContext context = JAXBContext.newInstance(obj.getClass());
		Marshaller marshaller = context.createMarshaller();
		marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);// xml格式
		marshaller.setProperty(Marshaller.JAXB_FRAGMENT, noheader); // 去掉生成xml的默认报文头
		marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
		marshaller.setListener(new Marshaller.Listener() {
			@Override
			public void beforeMarshal(Object source) {
				super.beforeMarshal(source);
				Field[] fields = source.getClass().getDeclaredFields();
				for (Field f : fields) {
					f.setAccessible(true);
					try {
						if (f.getType() == String.class && f.get(source) == null) {
							f.set(source, "");
						}
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					}
				}
			}
		});
		StringWriter writer = new StringWriter();
		marshaller.marshal(obj, writer);
		result = writer.toString();
		return result;
	}

转换方法

public static void main(String[] args) throws JAXBException, DocumentException {
		//创建body对象
		Req100004Impl body = new Req100004Impl();
		Req100004SumExt req100004SumExt = new Req100004SumExt();
		body.setSumExt(req100004SumExt);
		List<Req100004DetailsExt> detailsExt = new ArrayList<Req100004DetailsExt>();
		Req100004DetailsExt req100004DetailsExt = new Req100004DetailsExt();
		detailsExt.add(req100004DetailsExt);
		body.setDetailsExt(detailsExt);

		//对象转xml
		String bodyxml = beanToXML(body,"gbk",true);
		System.out.println(bodyxml );
}

转换

3. 定长报文 与 domino 对象转换

1、domino 代码编写
package talent.entity.fixed;

import java.lang.annotation.Annotation;
import talent.entity.fixed.anno.FixedLengthDesc;
import talent.entity.fixed.anno.FixedLengthFieldDesc;
/**
 * 定长报文与实体间转换需继承该类
 * 通过getThisClass获取定长描述信息
 */
public abstract class FixedLengthBody {
	protected FixedLengthFieldDesc[] fixedLengthFields;
	public abstract Class<? extends FixedLengthBody> getThisClass();
	
	public FixedLengthBody() {
		this.fixedLengthFields = init(getThisClass());
	}
	public FixedLengthFieldDesc[] init(Class<? extends FixedLengthBody> cls){
		FixedLengthDesc fld = null;
		Annotation[] ans  = cls.getAnnotations();
		for (Annotation an : ans) {
			if(an instanceof FixedLengthDesc){
				fld = (FixedLengthDesc) an;
				break;
			}
		}
		return fld.value();
	}
	public FixedLengthFieldDesc[] getFixedLengthFields() {
		return fixedLengthFields;
	}
	public void setFixedLengthFields(FixedLengthFieldDesc[] fixedLengthFields) {
		this.fixedLengthFields = fixedLengthFields;
	}	
}

父类,获取子类定长信息内容

package talent.entity.fixed.req;

import talent.entity.fixed.FixedLengthBody;
import talent.entity.fixed.anno.FixedLengthDesc;
import talent.entity.fixed.anno.FixedLengthFieldDesc;
import talent.entity.fixed.enums.FixedLengthEnum;
@FixedLengthDesc({ 
		@FixedLengthFieldDesc(name = "tranType", length = 6, type = FixedLengthEnum.STRING),
		@FixedLengthFieldDesc(name = "sendType", length = 4, type = FixedLengthEnum.STRING),
		@FixedLengthFieldDesc(name = "tranIdx", length = 16, type = FixedLengthEnum.STRING),
		.... 其他字段
})
public class FixedReq100301 extends FixedLengthBody {

	private String tranType;
	private String sendType;
	private String tranIdx;
	.... 其他字段
	 
	@Override
	public Class<? extends FixedLengthBody> getThisClass() {
		return FixedReq100301.class;
	}
 	.........
 	get set 方法
 	.........

domino对象: 注解用来配置转换定长报文

2、定长报文注解配置
package talent.entity.fixed.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface FixedLengthDesc {
	public FixedLengthFieldDesc[] value();
}

package talent.entity.fixed.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import talent.entity.fixed.enums.FixedLengthEnum;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface FixedLengthFieldDesc {
	public String name();
	public int length();
	public FixedLengthEnum type();
}

3、转换工具类
package talent.util;

import java.lang.reflect.Method;

import talent.entity.fixed.FixedLengthBody;
import talent.entity.fixed.anno.FixedLengthFieldDesc;
import talent.entity.fixed.enums.FixedLengthEnum;
import talent.entity.fixed.req.FixedReq100301;

/**
 * 定长报文 与 javaBean 相互转换
 * @author admin
 *
 */
public class FixedPacketUtil {

	private final static char rightCharStr = ' ';
	private final static char leftCharStr = '0';

	/**
	 * 将pojo按照格式生成固定格式报文
	 * @param pojo 转换对象
	 * @param charsetName 编码格式
	 */
	public static String javaBeanToFixedLengthPacket(FixedLengthBody pojo, String charsetName) throws Exception {

		String fieldName;
		int fieldLenght;
		FixedLengthEnum parameterClass;
		StringBuffer requestStr = new StringBuffer();
		FixedLengthFieldDesc[] fixedLengthFieldDescs = pojo.getFixedLengthFields();

		// 循环类中配置的所有字段
		int fixedLengthFieldDescsLength = fixedLengthFieldDescs.length;
		for (int i = 0; i < fixedLengthFieldDescsLength; i++) {

			FixedLengthFieldDesc fixedLengthFieldDesc = fixedLengthFieldDescs[i];
			fieldName = fixedLengthFieldDesc.name();
			fieldLenght = fixedLengthFieldDesc.length();
			parameterClass = fixedLengthFieldDesc.type();

			// 获取bean对象的get方法,拿到数据
			Class<?> c = pojo.getClass();
			Method m = c.getMethod("get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1));
			String fieldValue = m.invoke(pojo) == null ? "" : m.invoke(pojo).toString();

			// 对数据进行报文的拼接
			if (parameterClass.equals(FixedLengthEnum.STRING))
				requestStr.append(formatFieldByRightChar(fieldValue, fieldLenght, rightCharStr, charsetName));
			else {
				if (parameterClass.equals(FixedLengthEnum.FLOAT)) {
					fieldValue = formatFieldByfloat(fieldValue, charsetName);
				}
				requestStr.append(formatFieldByLeftChar(fieldValue, fieldLenght, leftCharStr, charsetName));
			}
		}
		return requestStr.toString();
	}

	/**
	 * FLOAT 浮点处理
	 */
	public static String formatFieldByfloat(String field, String charsetName) throws Exception {
		int s = field.indexOf(".");
		int length = field.length();
		if (s == -1) {
			return formatFieldByRightChar(field, length + 2, leftCharStr, charsetName);
		} else {
			String num = field.substring(0, s);
			String point = field.substring(s + 1);
			return num + formatFieldByRightChar(point, 2, leftCharStr, charsetName);
		}
	}

	/**
	 * str右补charStr参数指定的字符,格式化为指定byte长度为size的字符串
	 * @param str 原字符串大小
	 * @param size byte长度
	 * @param charStr 补充字符
	 * @param charsetName 编码格式
	 */
	public static String formatFieldByRightChar(String str, int size, char charStr, String charsetName)
			throws Exception {

		byte[] bufferByte = new byte[size];
		for (int i = 0; i < bufferByte.length; i++) {
			bufferByte[i] = (byte) charStr;
		}
		byte[] strByte = str.getBytes(charsetName); // 得到字符的字节数
		int strLength = strByte.length;
		System.arraycopy(strByte, 0, bufferByte, 0, size > strLength ? strLength : size);
		return new String(bufferByte);
	}

	public static String formatFieldByRightChar(String str, int size, String charsetName) throws Exception {
		return formatFieldByRightChar(str, size, rightCharStr, charsetName);
	}

	/**
	 * str左补charStr参数指定的字符,格式化为指定byte长度为size的字符串
	 * @param str 原字符串大小
	 * @param size byte长度
	 * @param charStr 补充字符
	 */
	public static String formatFieldByLeftChar(String str, int size, char charStr, String charsetName)
			throws Exception {

		byte[] bufferByte = new byte[size];
		for (int i = 0; i < bufferByte.length; i++) {
			bufferByte[i] = (byte) charStr;
		}

		byte[] strByte = str.getBytes(charsetName);
		int strLength = strByte.length;

		System.arraycopy(strByte, 0, bufferByte, (size - strLength) > 0 ? (size - strLength) : 0,
				(size - strLength) > 0 ? strLength : size);
		return new String(bufferByte);
	}

	public static String formatFieldByLeftChar(String str, int size, String charsetName) throws Exception {
		return formatFieldByLeftChar(str, size, leftCharStr, charsetName);
	}

	/**
	 * 将strByte字符串按照requestPacketFormatArray三维数组定义的格式生pojo
	 */
	public static void fixedLengthPacketToJavaBean(FixedLengthBody pojo, String str, String charsetName)
			throws Exception {

		// 初始化数据
		int index = 0;
		byte[] strByte = str.getBytes(charsetName);
		String fieldName;
		int fieldLenght;
		FixedLengthEnum parameterClass;

		// 循环类中配置的所有字段
		FixedLengthFieldDesc[] fixedLengthFieldDescs = pojo.getFixedLengthFields();
		int fixedLengthFieldDescsLength = fixedLengthFieldDescs.length;
		for (int i = 0; i < fixedLengthFieldDescsLength; i++) {

			FixedLengthFieldDesc fixedLengthFieldDesc = fixedLengthFieldDescs[i];
			fieldName = fixedLengthFieldDesc.name();
			fieldLenght = fixedLengthFieldDesc.length();
			parameterClass = fixedLengthFieldDesc.type();

			// 截取报文里每个字段配置的长度(按index下标到fieldLenght截取)
			int tempLenght = fieldLenght;
			byte[] byteTemp = new byte[tempLenght];
			for (int k = 0; k < tempLenght; k++) {
				byteTemp[k] = strByte[index + k];
			}
			index = index + tempLenght;

			// 给pojo对象赋值
			Class<?> c = pojo.getClass();
			if (parameterClass.equals(FixedLengthEnum.STRING)) {
				Method m = c.getMethod("set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1),
						String.class);
				m.invoke(pojo, new String(byteTemp).trim());
			} else if (parameterClass.equals(FixedLengthEnum.INT)) {
				Method m = c.getMethod("set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1),
						int.class);
				m.invoke(pojo, Integer.valueOf(new String(byteTemp)));
			} else if (parameterClass.equals(FixedLengthEnum.LONG)) {
				Method m = c.getMethod("set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1),
						long.class);
				m.invoke(pojo, Long.valueOf(new String(byteTemp)));
			} else if (parameterClass.equals(FixedLengthEnum.FLOAT)) {
				Method m = c.getMethod("set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1),
						float.class);
				m.invoke(pojo, Float.valueOf(new String(byteTemp))/100 );
			}
		}
	}
	
	
	public static void main(String args[]) {
		FixedReq100301 fixed = new FixedReq100301();
		fixed.setTranType("100301");
		fixed.setSendType("1202");
		fixed.setTranIdx("0000000000000003");
		fixed.setEntrustDate("20080601");
		fixed.setLiquidationDate("00000000");
		fixed.setUserNum("1234567890");
		fixed.setSendCode("231255297");
		fixed.setSendNodeCode("");
		fixed.setSendBankCode("");
		fixed.setSendBankAcct("");
		fixed.setReceiveCode("201581000018");
		fixed.setReceiveNodeCode("");
		fixed.setDraweeAcct("44001400102050031709");
		fixed.setDraweeName("关羽");
		fixed.setBizType("00700");
		fixed.setProtocolId("0158102312552970070020144001400102050031709");
		fixed.setCcyCode("CNY");
		fixed.setAmt(1F);
		fixed.setFee(0F);
		fixed.setPostscript("附言");
		fixed.setBizTranId("0000000000000000");
		fixed.setRespCode("");
		fixed.setPayLdentifi(0);
		fixed.setFixedLength("00000000");
		try {
			System.out.println(javaBeanToFixedLengthPacket(fixed, "gb2312"));
		} catch (Exception e) {
			e.printStackTrace();
		}
//
//		/** 与行里进行通讯 */
//
//		// 获取银行返回数据
//		String respFixed = "1003011202000000000000000320080601000000001234567890        231255297                                                              201581000018            44001400102050031709               关羽                                                        007000158102312552970070020144001400102050031709                 CNY000000000000100000000000000000附言                                                        0000000000000000        00000000037613A9A055A55821E8C5771619A5B82876B02A47ADF57CAE3027DDA3A08268A";
//		FixedResp100301 fixedResp = new FixedResp100301();
//		try {
//			fixedLengthPacketToJavaBean(fixedResp, respFixed, "gb2312");
//			System.out.println(fixedResp);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
	}

}

4. 通讯(scoket)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值