Commit 0bcb4dce by s_guodong

update

parent 1170a55d
......@@ -16,4 +16,14 @@
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>cn.com.infosec</groupId>
<artifactId>ISFJ_v2_0_139_20_BAISC_JDK15</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${pom.basedir}/../lib/ISFJ_v2_0_139_20_BAISC_JDK15.jar</systemPath>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package rmb.report.utils;
package com.brilliance.rmb.report.model;
public abstract class Assert {
protected Assert() {
......
package com.brilliance.rmb.report.model;
import com.brilliance.rmb.report.model.format.ActiveCurrencyAndAmount;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
@XmlAccessorType(XmlAccessType.NONE)
public class Cfx {
public static final String CLASS_PREFIX = "cfx";
private String mesgType;
private HEAD head;
public Cfx(HEAD head) {
this.head = head;
this.mesgType = CLASS_PREFIX + head.getMsgNo();
}
public Cfx() {
}
public Map<String, String> getFlatCfx() throws Exception {
Map<String, String> flat = new LinkedHashMap<String, String>();
Stack<String> stack = new Stack<String>();
stack.push(this.getClass().getAnnotation(XmlRootElement.class).name());
// 模型数据
iteratorElcs(this, stack, flat);
// 报文头数据
flat.put("VER", head.getVER());
flat.put("SRC", head.getSRC());
flat.put("DES", head.getDES());
flat.put("APP", head.getAPP());
flat.put("MsgNo", head.getMsgNo());
flat.put("MsgID", head.getMsgID());
flat.put("MsgRef", head.getMsgRef());
flat.put("WorkDate", head.getWorkDate());
flat.put("Reserve", head.getReserve());
return flat;
}
private <T> void iteratorElcs(T obj, Stack<String> stack,
Map<String, String> flat) throws Exception {
Class<?> claz = obj.getClass();
if (Collection.class.isAssignableFrom(claz)) {
int i = 0;
String prefix = stack.get(stack.size() - 1);
for (Object item : (List<?>) obj) {
stack.remove(stack.size() - 1);
stack.push(prefix + "_" + i);
iteratorElcs(item, stack, flat);
i++;
}
} else if (claz.isArray()) {
int len = Array.getLength(obj);
String prefix = stack.get(stack.size() - 1);
for (int i = 0; i < len; i++) {
stack.remove(stack.size() - 1);
stack.push(prefix + "_" + i);
iteratorElcs(Array.get(obj, i), stack, flat);
}
} else {
if (obj instanceof String) {
String val = ((String) obj).trim();
flat.put(join(stack, "."), val);
} else if (obj instanceof ActiveCurrencyAndAmount) {
// 金额类型处理[取金额字段作为加签要素时,应包括该金额对应的货币符号,例如格式CNY1234.56]
ActiveCurrencyAndAmount currence = (ActiveCurrencyAndAmount) obj;
flat.put(join(stack, "."), currence.Ccy + currence.amount);
} else {
Assert.notNull(claz.getAnnotation(XmlType.class), "当前bean["
+ obj + "]不支持要素串拼接,原因[XmlType注解缺失]");
XmlType xmltype = claz.getAnnotation(XmlType.class);
Assert.notNullByArray(xmltype.propOrder(), "当前bean[" + obj
+ "]不支持要素串拼接,原因[XmlType注解的propOrder属性值为空]");
String[] propOrder = xmltype.propOrder();
for (String fieldNam : propOrder) {
stack.push(fieldNam);
Field field = claz.getField(fieldNam);
if (!field.isAccessible()) {
field.setAccessible(true);
}
Object fieldval = field.get(obj);
if (fieldval == null) {
stack.pop();
continue;
}
if (fieldval instanceof String) {
String val = ((String) fieldval).trim();
flat.put(join(stack, "."), val);
stack.pop();
} else if (fieldval instanceof ActiveCurrencyAndAmount) {
// 金额类型处理[取金额字段作为加签要素时,应包括该金额对应的货币符号,例如格式CNY1234.56]
ActiveCurrencyAndAmount currence = (ActiveCurrencyAndAmount) fieldval;
flat.put(join(stack, "."), currence.Ccy
+ currence.amount);
flat.put(join(stack, "Ccy", "."), currence.Ccy);
flat.put(join(stack, "amount", "."), currence.amount);
stack.pop();
} else {
iteratorElcs(fieldval, stack, flat);
stack.pop();
}
}
}
}
}
/**
* 获取指定报文模型的所有字段
*/
public <T> void getElcsFields(Type type, Stack<String> stack,
List<String> fields) {
try {
Class<?> claz = (Class<?>) type;
Assert.notNull(claz.getAnnotation(XmlType.class), "当前claz[" + claz
+ "]不支持要素串拼接,原因[XmlType注解缺失]");
XmlType xmltype = claz.getAnnotation(XmlType.class);
Assert.notNullByArray(xmltype.propOrder(), "当前claz[" + claz
+ "]不支持要素串拼接,原因[XmlType注解的propOrder属性值为空]");
String[] propOrder = xmltype.propOrder();
for (String fieldNam : propOrder) {
stack.push(fieldNam);
Field field = claz.getField(fieldNam);
if (!field.isAccessible()) {
field.setAccessible(true);
}
if (String.class.isAssignableFrom(field.getType())) {
fields.add(join(stack, "."));
stack.pop();
} else if (ActiveCurrencyAndAmount.class.isAssignableFrom(field
.getType())) {
fields.add(join(stack, "."));
stack.pop();
} else {
if (Collection.class.isAssignableFrom(field.getType())
|| field.getType().isArray()) {
ParameterizedType listGenericType = (ParameterizedType) field
.getGenericType();
Type[] listActualTypeArguments = listGenericType
.getActualTypeArguments();
for (int i = 0; i < listActualTypeArguments.length; i++) {
if (!String.class
.isAssignableFrom((Class<?>) listActualTypeArguments[i])) {
getElcsFields(listActualTypeArguments[i],
stack, fields);
}
}
} else {
getElcsFields(field.getType(), stack, fields);
}
stack.pop();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public String join(Collection<String> collection, String separator) {
if (collection == null) {
return null;
}
Iterator<String> iterator = collection.iterator();
if (!iterator.hasNext()) {
return "";
}
String first = iterator.next();
if (!iterator.hasNext()) {
return first;
}
StringBuilder buf = new StringBuilder(256);
buf.append(first);
while (iterator.hasNext()) {
if (separator != null) {
buf.append(separator);
}
String obj = iterator.next();
if (obj != null) {
buf.append(obj);
}
}
return buf.toString();
}
public String join(Collection<String> collection, String endItem, String separator) {
String prefix = join(collection, separator);
return prefix + separator + endItem;
}
public HEAD getHead() {
return head;
}
public String getMsgType() {
if (head == null) {
return mesgType;
}
return CLASS_PREFIX + head.getMsgNo();
}
public String getMesgType() {
return mesgType;
}
public void setMesgType(String mesgType) {
this.mesgType = mesgType;
}
public void setHead(HEAD head) {
this.head = head;
}
}
package com.brilliance.rmb.report.model;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* @Description
* @Author s_guodong
* @Date 2023/5/11
*/
@XmlType(propOrder = {"VER", "SRC", "DES", "APP", "MsgNo", "MsgID", "MsgRef", "WorkDate", "Reserve"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "HEAD")
public class HEAD {
private String sendBic;
private String VER;
private String SRC;
private String DES;
private String APP;
private String MsgNo;
private String MsgID;
private String MsgRef;
private String WorkDate;
private String Reserve;
public String getVER() {
return VER;
}
public void setVER(String VER) {
this.VER = VER;
}
public String getSRC() {
return SRC;
}
public void setSRC(String SRC) {
this.SRC = SRC;
}
public String getDES() {
return DES;
}
public void setDES(String DES) {
this.DES = DES;
}
public String getAPP() {
return APP;
}
public void setAPP(String APP) {
this.APP = APP;
}
public String getMsgNo() {
return MsgNo;
}
public void setMsgNo(String msgNo) {
MsgNo = msgNo;
}
public String getMsgID() {
return MsgID;
}
public void setMsgID(String msgID) {
MsgID = msgID;
}
public String getMsgRef() {
return MsgRef;
}
public void setMsgRef(String msgRef) {
MsgRef = msgRef;
}
public String getWorkDate() {
return WorkDate;
}
public void setWorkDate(String workDate) {
WorkDate = workDate;
}
public String getSendBic() {
return sendBic;
public String getReserve() {
return Reserve;
}
public void setSendBic(String sendBic) {
this.sendBic = sendBic;
public void setReserve(String reserve) {
Reserve = reserve;
}
}
package com.brilliance.rmb.report.model;
public class MsgDocument {
private String result;
public Cfx messageRoot;
public MsgDocument() {
}
public MsgDocument(Cfx messageRoot) {
this.messageRoot = messageRoot;
}
public MsgDocument(String result) {
this.result = result;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public Cfx getMessageRoot() {
return messageRoot;
}
public void setMessageRoot(Cfx messageRoot) {
this.messageRoot = messageRoot;
}
}
package com.brilliance.rmb.report.model.cfx2101;
import com.brilliance.rmb.report.model.Cfx;
import com.brilliance.rmb.report.model.Desc;
import com.brilliance.rmb.report.model.HEAD;
import com.brilliance.rmb.report.model.Need;
......@@ -9,10 +10,10 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlType(propOrder = { "HEAD", "MSG"})
@XmlType(propOrder = {"HEAD", "MSG"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "CFX")
public class Cfx2101 {
public class Cfx2101 extends Cfx {
@Desc("报文头")
@Need
public HEAD HEAD;
......@@ -20,11 +21,11 @@ public class Cfx2101 {
@Need
public MSG MSG;
public Cfx2101 () {
public Cfx2101() {
}
public Cfx2101 (HEAD HEAD ,MSG MSG ){
this.HEAD=HEAD;
this.MSG=MSG;
public Cfx2101(HEAD HEAD, MSG MSG) {
this.HEAD = HEAD;
this.MSG = MSG;
}
}
\ No newline at end of file
package com.brilliance.rmb.report.model.cfx2111;
import com.brilliance.rmb.report.model.Desc;
import com.brilliance.rmb.report.model.Len;
import com.brilliance.rmb.report.model.Need;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlType(propOrder = { "SendOrgCode", "EntrustDate", "PackNo", "AllNum"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "BatchHead2111")
public class BatchHead2111 {
@Len(size =12)
@Desc("发起机构代码")
@Need
public String SendOrgCode;
/**
* 请求发起日期
*/
@Desc("委托日期")
@Need
public String EntrustDate;
/**
* 用于发起方唯一标识一个包的流水号,由发起方自定义
*/
@Desc("包流水号")
@Need
@Len(size =8)
public String PackNo;
/**
* 当前包中包含的交易总数,要求总笔数不大于1000
*/
@Desc("总笔数")
@Need
public Integer AllNum;
public BatchHead2111 () {
}
public BatchHead2111 (String SendOrgCode ,String EntrustDate ,String PackNo ,Integer AllNum ){
this.SendOrgCode=SendOrgCode;
this.EntrustDate=EntrustDate;
this.PackNo=PackNo;
this.AllNum=AllNum;
}
}
\ No newline at end of file
package com.brilliance.rmb.report.model.cfx2111;
import com.brilliance.rmb.report.model.Desc;
import com.brilliance.rmb.report.model.HEAD;
import com.brilliance.rmb.report.model.Need;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlType(propOrder = { "HEAD", "MSG"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "CFX")
public class Cfx2111 {
@Desc("报文头")
@Need
public HEAD HEAD;
@Desc("报文体")
@Need
public MSG MSG;
public Cfx2111 () {
}
public Cfx2111 (HEAD HEAD ,MSG MSG ){
this.HEAD=HEAD;
this.MSG=MSG;
}
}
\ No newline at end of file
package com.brilliance.rmb.report.model.cfx2111;
import com.brilliance.rmb.report.model.Desc;
import com.brilliance.rmb.report.model.Need;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import java.util.List;
@XmlType(propOrder = { "BatchHead2111", "Payment2111"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "MSG")
public class MSG {
@Desc("批量头")
@Need
public BatchHead2111 BatchHead2111;
@Desc("支出信息")
@Need
public List<Payment2111> Payment2111;
public MSG () {
}
public MSG (BatchHead2111 BatchHead2111 ,List<Payment2111> Payment2111 ){
this.BatchHead2111=BatchHead2111;
this.Payment2111=Payment2111;
}
}
\ No newline at end of file
package com.brilliance.rmb.report.model.cfx2111;
import com.brilliance.rmb.report.model.Desc;
import com.brilliance.rmb.report.model.Len;
import com.brilliance.rmb.report.model.Need;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlType(propOrder = { "LevyNo"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Payment2111")
public class Payment2111 {
/**
* 编制规则详见附录A6
*/
@Len(size =24)
@Desc("申报号码")
@Need
public String LevyNo;
public Payment2111 () {
}
public Payment2111 (String LevyNo ){
this.LevyNo=LevyNo;
}
}
\ No newline at end of file
package com.brilliance.rmb.report.model.cfx2111;
import com.brilliance.rmb.report.model.Desc;
import com.brilliance.rmb.report.model.Need;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import java.util.List;
@XmlType(propOrder = { "PaymentList2111"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "PaymentBody2111")
public class PaymentBody2111 {
@Desc("支出明细信息")
@Need
public List<PaymentList2111> PaymentList2111;
public PaymentBody2111 () {
}
public PaymentBody2111 (List<PaymentList2111> PaymentList2111 ){
this.PaymentList2111=PaymentList2111;
}
}
\ No newline at end of file
package com.brilliance.rmb.report.model.cfx2111;
import com.brilliance.rmb.report.model.Desc;
import com.brilliance.rmb.report.model.Len;
import com.brilliance.rmb.report.model.Need;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlType(propOrder = { "SeqNo", "BalOfPayCode", "PayAmt", "BusTypeCode", "BusTypeList", "ActualPayerCode", "ActualPayerName", "IfPrePayment", "PrePayerScale", "AccountPeriod", "CustState", "CertificateNo", "ContractNo", "AddWord", "Reserve7", "Reserve8", "Reserve9", "Reserve10"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "PaymentList2111")
public class PaymentList2111 {
/**
* 同一申报号码的支出明细信息项下,该序号不能重复,修改删除时以此序号确定相关记录
*/
@Desc("序号")
@Need
public Integer SeqNo;
/**
* 详见附录A7国际收支交易编码
*/
@Desc("国际收支交易编码")
@Len(size =6)
@Need
public String BalOfPayCode;
@Desc("付款金额")
@Need
public String PayAmt;
/**
* 详见附录A1 业务种类代码
*/
@Desc("业务种类代码")
@Len(size =6)
@Need
public String BusTypeCode;
/**
* 若业务种类代码填写100011大宗商品,则填写大宗商品明细分类(详见附录);若业务种类代码填写100021新型离岸,则填写新型离岸贸易明细分类(详见附录);若业务种类代码为600011资金池,则填写资金池明细分类(详见附录),600031境外借款,则填写境外借款资金来源分类(详见附录);若业务种类代码为700021债券通,则填写债券通明细分类(详见附录);若业务种类代码为700022CIBM,则填写CIBM投资人明细分类(详见附录);若业务种类代码为700041合格投资者时,则填写合格投资者投资品明细分类(详见附录);若业务种类代码为700051境外存托凭证或700052中国存托凭证时,则填写存托凭证明细分类(详见附录);若业务种类代码为800041资产转让,则填写资产转让类型(详见附录);若业务种类代码为800071保证金,则填写保证金明细分类(详见附录);若业务种类代码为800081理财通,则填写理财通明细分类(详见附录);
*/
@Desc("业务种类明细分类")
@Len(size =8)
public String BusTypeList;
/**
* 业务种类代码为200012第三方支付且单笔金额大于3万时,填写实际付款的境内机构代码或个人身份证件号码,其他同“付款人机构代码或身份证件号码”
*/
@Desc("实际付款人代码")
@Len(min = 1,max =30 )
@Need
public String ActualPayerCode;
/**
* 业务种类代码为200012第三方支付且单笔金额大于3万时,填写实际付款的境内机构名称或个人姓名,其他同“付款人名称”
*/
@Desc("实际付款人名称")
@Need
@Len(min = 1,max =128 )
public String ActualPayerName;
/**
* 详见附录A1 是否标识
*/
@Len(size =1)
@Need
@Desc("是否预付款")
public String IfPrePayment;
/**
* 预付款占合同金额的比例。按小数填写。为预付款时必填。
*/
@Desc("预付款比例")
@Len(min = 4,max =2 )
public String PrePayerScale;
/**
* 预付与合同结清的预计时间差。单位“天”。为预付款时必填。
*/
@Desc("结账期")
public Integer AccountPeriod;
/**
* 预付款时必填,新增时默认填写0001
*/
@Len(size =4)
@Desc("物流状态")
public String CustState;
/**
* 对外直接投资时必填
*/
@Len(min = 1,max =32 )
@Desc("政府部门核准证书编号")
public String CertificateNo;
/**
* 当国际收支交易编码为融资类业务时必填。校验该编号在“跨境信贷融资业务信息”中存在
*/
@Len(size =24)
@Desc("融资合同备案号")
public String ContractNo;
@Desc("交易附言")
@Need
@Len(min = 1,max =128 )
public String AddWord;
/**
* 预留
*/
@Desc("预留字段7")
@Len(min = 1,max =200 )
public String Reserve7;
/**
* 预留
*/
@Desc("预留字段8")
@Len(min = 1,max =200 )
public String Reserve8;
/**
* 预留
*/
@Desc("预留字段9")
@Len(min = 1,max =200 )
public String Reserve9;
/**
* 预留
*/
@Len(min = 1,max =200 )
@Desc("预留字段10")
public String Reserve10;
public PaymentList2111 () {
}
public PaymentList2111 (Integer SeqNo ,String BalOfPayCode ,String PayAmt ,String BusTypeCode ,String BusTypeList ,String ActualPayerCode ,String ActualPayerName ,String IfPrePayment ,String PrePayerScale ,Integer AccountPeriod ,String CustState ,String CertificateNo ,String ContractNo ,String AddWord ,String Reserve7 ,String Reserve8 ,String Reserve9 ,String Reserve10 ){
this.SeqNo=SeqNo;
this.BalOfPayCode=BalOfPayCode;
this.PayAmt=PayAmt;
this.BusTypeCode=BusTypeCode;
this.BusTypeList=BusTypeList;
this.ActualPayerCode=ActualPayerCode;
this.ActualPayerName=ActualPayerName;
this.IfPrePayment=IfPrePayment;
this.PrePayerScale=PrePayerScale;
this.AccountPeriod=AccountPeriod;
this.CustState=CustState;
this.CertificateNo=CertificateNo;
this.ContractNo=ContractNo;
this.AddWord=AddWord;
this.Reserve7=Reserve7;
this.Reserve8=Reserve8;
this.Reserve9=Reserve9;
this.Reserve10=Reserve10;
}
}
\ No newline at end of file
package com.brilliance.rmb.report.model.cfx2112;
import com.brilliance.rmb.report.model.Desc;
import com.brilliance.rmb.report.model.Len;
import com.brilliance.rmb.report.model.Need;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlType(propOrder = { "SendOrgCode", "EntrustDate", "PackNo", "AllNum"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "BatchHead2112")
public class BatchHead2112 {
@Len(size =12)
@Desc("发起机构代码")
@Need
public String SendOrgCode;
/**
* 请求发起日期
*/
@Desc("委托日期")
@Need
public String EntrustDate;
/**
* 用于发起方唯一标识一个包的流水号,由发起方自定义
*/
@Desc("包流水号")
@Need
@Len(size =8)
public String PackNo;
/**
* 当前包中包含的交易总数,要求总笔数不大于1000
*/
@Desc("总笔数")
@Need
public Integer AllNum;
public BatchHead2112 () {
}
public BatchHead2112 (String SendOrgCode ,String EntrustDate ,String PackNo ,Integer AllNum ){
this.SendOrgCode=SendOrgCode;
this.EntrustDate=EntrustDate;
this.PackNo=PackNo;
this.AllNum=AllNum;
}
}
\ No newline at end of file
package com.brilliance.rmb.report.model.cfx2112;
import com.brilliance.rmb.report.model.Desc;
import com.brilliance.rmb.report.model.HEAD;
import com.brilliance.rmb.report.model.Need;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlType(propOrder = { "HEAD", "MSG"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "CFX")
public class Cfx2112 {
@Desc("报文头")
@Need
public HEAD HEAD;
@Desc("报文体")
@Need
public MSG MSG;
public Cfx2112 () {
}
public Cfx2112 (HEAD HEAD ,MSG MSG ){
this.HEAD=HEAD;
this.MSG=MSG;
}
}
\ No newline at end of file
package com.brilliance.rmb.report.model.cfx2112;
import com.brilliance.rmb.report.model.Desc;
import com.brilliance.rmb.report.model.Need;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import java.util.List;
@XmlType(propOrder = { "IncomeList2112"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "IncomeBody2112")
public class IncomeBody2112 {
@Desc("收入明细信息")
@Need
public List<IncomeList2112> IncomeList2112;
public IncomeBody2112 () {
}
public IncomeBody2112 (List<IncomeList2112> IncomeList2112 ){
this.IncomeList2112=IncomeList2112;
}
}
\ No newline at end of file
package com.brilliance.rmb.report.model.cfx2112;
import com.brilliance.rmb.report.model.Desc;
import com.brilliance.rmb.report.model.Len;
import com.brilliance.rmb.report.model.Need;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlType(propOrder = { "LevyNo", "OperType", "ActionDesc", "PayeeAcct", "PayerCountryCode", "PayerAcctType", "PayerAcct", "IfRefund", "OriPayLevyNo", "Reserve1", "Reserve2", "Reserve3", "Reserve4", "Reserve5", "Reserve6", "IncomeBody2112"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "IncomeDeclaration2112")
public class IncomeDeclaration2112 {
/**
* 跨境收入基本信息的申报号码
*/
@Len(size =24)
@Desc("申报号码")
@Need
public String LevyNo;
/**
* 详见附录A1 操作类型
*/
@Desc("操作类型")
@Len(size =1)
@Need
public String OperType;
/**
* 操作类型为2变更、3撤销时必填
*/
@Desc("变更/撤销原因")
@Len(min = 1,max =128 )
public String ActionDesc;
/**
* 无账户汇款情况下填写N/A
*/
@Len(min = 1,max =32 )
@Desc("收款人账号")
@Need
public String PayeeAcct;
/**
* 详见附录A1 国家(地区)代码;
*/
@Desc("付款人常驻国家(地区)代码")
@Len(size =3)
@Need
public String PayerCountryCode;
/**
* 详见附录A1 收付款人账户类型
*/
@Len(size =1)
@Desc("付款人账户类型")
@Need
public String PayerAcctType;
/**
* 仅“无账户”时填写N/A
*/
@Desc("付款人账号")
@Len(min = 1,max =32 )
@Need
public String PayerAcct;
/**
* 详见附录A1 是否标识
*/
@Len(size =1)
@Desc("是否退款")
@Need
public String IfRefund;
/**
* 退款必填,且原申报号码必须在跨境支出信息中存在。
*/
@Len(size =24)
@Desc("原支出申报号码")
public String OriPayLevyNo;
/**
* 预留
*/
@Len(min = 1,max =200 )
@Desc("预留字段1")
public String Reserve1;
/**
* 预留
*/
@Len(min = 1,max =200 )
@Desc("预留字段2")
public String Reserve2;
/**
* 预留
*/
@Len(min = 1,max =200 )
@Desc("预留字段3")
public String Reserve3;
/**
* 预留
*/
@Len(min = 1,max =200 )
@Desc("预留字段4")
public String Reserve4;
/**
* 预留
*/
@Len(min = 1,max =200 )
@Desc("预留字段5")
public String Reserve5;
/**
* 预留
*/
@Len(min = 1,max =200 )
@Desc("预留字段6")
public String Reserve6;
/**
* XML报文中节点,即信息数据域的标识
*/
@Desc("收入明细信息")
public IncomeBody2112 IncomeBody2112;
public IncomeDeclaration2112 () {
}
public IncomeDeclaration2112 (String LevyNo ,String OperType ,String ActionDesc ,String PayeeAcct ,String PayerCountryCode ,String PayerAcctType ,String PayerAcct ,String IfRefund ,String OriPayLevyNo ,String Reserve1 ,String Reserve2 ,String Reserve3 ,String Reserve4 ,String Reserve5 ,String Reserve6 ,IncomeBody2112 IncomeBody2112 ){
this.LevyNo=LevyNo;
this.OperType=OperType;
this.ActionDesc=ActionDesc;
this.PayeeAcct=PayeeAcct;
this.PayerCountryCode=PayerCountryCode;
this.PayerAcctType=PayerAcctType;
this.PayerAcct=PayerAcct;
this.IfRefund=IfRefund;
this.OriPayLevyNo=OriPayLevyNo;
this.Reserve1=Reserve1;
this.Reserve2=Reserve2;
this.Reserve3=Reserve3;
this.Reserve4=Reserve4;
this.Reserve5=Reserve5;
this.Reserve6=Reserve6;
this.IncomeBody2112=IncomeBody2112;
}
}
\ No newline at end of file
package com.brilliance.rmb.report.model.cfx2112;
import com.brilliance.rmb.report.model.Desc;
import com.brilliance.rmb.report.model.Len;
import com.brilliance.rmb.report.model.Need;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlType(propOrder = { "ListOperType", "SeqNo", "BalOfPayCode", "ReceAmt", "BusTypeCode", "BusTypeList", "ActualPayeeCode", "ActualPayeeName", "IfPreRece", "PrePayeeScale", "AccountPeriod", "CustState", "CertificateNo", "ContractNo", "AddWord", "Reserve7", "Reserve8", "Reserve9", "Reserve10"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "IncomeList2112")
public class IncomeList2112 {
/**
* 详见附录A1 操作类型
*/
@Len(size =1)
@Desc("明细操作类型")
@Need
public String ListOperType;
/**
* 同一申报号码的收入明细信息项下,该序号不能重复,修改删除时以此序号确定相关记录
*/
@Desc("序号")
@Need
public Integer SeqNo;
/**
* 详见附录A7国际收支交易编码(收入)
*/
@Desc("国际收支交易编码")
@Len(size =6)
@Need
public String BalOfPayCode;
@Desc("收款金额")
@Need
public String ReceAmt;
/**
* 详见附录A1 业务种类代码
*/
@Desc("业务种类代码")
@Len(size =6)
@Need
public String BusTypeCode;
/**
* 若业务种类代码填写100011大宗商品,则填写大宗商品明细分类(详见附录);若业务种类代码填写100021新型离岸,则填写新型离岸贸易明细分类(详见附录);若业务种类代码为600011资金池,则填写资金池明细分类(详见附录);600031境外借款,则填写境外借款资金来源分类(详见附录);若业务种类代码为700021债券通,则填写债券通明细分类(详见附录);若业务种类代码为700022CIBM,则填写CIBM投资人明细分类(详见附录);若业务种类代码为700041合格投资者时,填写合格投资者投资品明细分类(详见附录);若业务种类代码为700051境外存托凭证或700052中国存托凭证时,则填写存托凭证明细分类(详见附录);若业务种类代码为800041资产转让,则填写资产转让类型(详见附录);若业务种类代码为800071保证金,则填写保证金明细分类(详见附录);若业务种类代码为800081理财通,则填写理财通明细分类(详见附录);
*/
@Desc("业务种类明细分类")
@Len(size =8)
public String BusTypeList;
/**
* 业务种类代码为200012第三方支付且单笔金额大于3万时,填写实际收款的境内机构代码或个人身份证件号码,其他同“收款人机构代码或身份证件号码”
*/
@Desc("实际收款人代码")
@Len(min = 1,max =30 )
@Need
public String ActualPayeeCode;
/**
* 业务种类代码为200012第三方支付且单笔金额大于3万时,填写实际收款的境内机构名称或个人姓名,其他同“收款人名称”
*/
@Desc("实际收款人名称")
@Need
@Len(min = 1,max =128 )
public String ActualPayeeName;
/**
* 详见附录A1 是否标识
*/
@Len(size =1)
@Desc("是否预收款")
@Need
public String IfPreRece;
/**
* 预收款占合同金额的比例。按小数填写。为预收款时必填。
*/
@Desc("预收款比例")
@Len(min = 4,max =2 )
public String PrePayeeScale;
/**
* 预收与合同结清之间的预计时间差。单位“天”。为预收款时必填。
*/
@Desc("结账期")
public Integer AccountPeriod;
/**
* 预收款时必填,新增时默认填写0001。详见附录A1 物流状态
*/
@Len(size =4)
@Desc("物流状态")
public String CustState;
/**
* 对外直接投资时必填
*/
@Len(min = 1,max =32 )
@Desc("政府部门核准证书编号")
public String CertificateNo;
/**
* 当国际收支交易编码为融资类业务时必填。校验该编号在“跨境信贷融资业务信息”中存在
*/
@Len(size =24)
@Desc("融资合同备案号")
public String ContractNo;
@Desc("交易附言")
@Need
@Len(min = 1,max =128 )
public String AddWord;
/**
* 预留
*/
@Desc("预留字段7")
@Len(min = 1,max =200 )
public String Reserve7;
/**
* 预留
*/
@Desc("预留字段8")
@Len(min = 1,max =200 )
public String Reserve8;
/**
* 预留
*/
@Desc("预留字段9")
@Len(min = 1,max =200 )
public String Reserve9;
/**
* 预留
*/
@Len(min = 1,max =200 )
@Desc("预留字段10")
public String Reserve10;
public IncomeList2112 () {
}
public IncomeList2112 (String ListOperType ,Integer SeqNo ,String BalOfPayCode ,String ReceAmt ,String BusTypeCode ,String BusTypeList ,String ActualPayeeCode ,String ActualPayeeName ,String IfPreRece ,String PrePayeeScale ,Integer AccountPeriod ,String CustState ,String CertificateNo ,String ContractNo ,String AddWord ,String Reserve7 ,String Reserve8 ,String Reserve9 ,String Reserve10 ){
this.ListOperType=ListOperType;
this.SeqNo=SeqNo;
this.BalOfPayCode=BalOfPayCode;
this.ReceAmt=ReceAmt;
this.BusTypeCode=BusTypeCode;
this.BusTypeList=BusTypeList;
this.ActualPayeeCode=ActualPayeeCode;
this.ActualPayeeName=ActualPayeeName;
this.IfPreRece=IfPreRece;
this.PrePayeeScale=PrePayeeScale;
this.AccountPeriod=AccountPeriod;
this.CustState=CustState;
this.CertificateNo=CertificateNo;
this.ContractNo=ContractNo;
this.AddWord=AddWord;
this.Reserve7=Reserve7;
this.Reserve8=Reserve8;
this.Reserve9=Reserve9;
this.Reserve10=Reserve10;
}
}
\ No newline at end of file
package com.brilliance.rmb.report.model.cfx2112;
import com.brilliance.rmb.report.model.Desc;
import com.brilliance.rmb.report.model.Need;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import java.util.List;
@XmlType(propOrder = { "BatchHead2112", "IncomeDeclaration2112"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "MSG")
public class MSG {
@Desc("批量头")
@Need
public BatchHead2112 BatchHead2112;
@Desc("收入申报信息")
@Need
public List<IncomeDeclaration2112> IncomeDeclaration2112;
public MSG () {
}
public MSG (BatchHead2112 BatchHead2112 ,List<IncomeDeclaration2112> IncomeDeclaration2112 ){
this.BatchHead2112=BatchHead2112;
this.IncomeDeclaration2112=IncomeDeclaration2112;
}
}
\ No newline at end of file
package com.brilliance.rmb.report.model.format;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlValue;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
public class ActiveCurrencyAndAmount {
@XmlValue
@XmlJavaTypeAdapter(ActiveCurrencyAndAmountAdapter.class)
public String amount;
@XmlAttribute(name = "Ccy")
public String Ccy = "CNY";
public ActiveCurrencyAndAmount(String amount, String ccy) {
this.amount = amount;
this.Ccy = ccy;
}
public ActiveCurrencyAndAmount(String amount) {
this.amount = amount;
}
public ActiveCurrencyAndAmount() {
}
}
package com.brilliance.rmb.report.model.format;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.text.DecimalFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 对ActiveCurrencyAndAmount类型数据进行处理
* 表示货币符号和金额,其中金额的整数部分最多16位数字,小数部分固定2位数字。注:不带正负(即+-)号
*/
public class ActiveCurrencyAndAmountAdapter extends XmlAdapter<String, String> {
public static final String TAG_PATTERN = "^(?:/[A-Z0-9]{3}/){0,1}";
public static final ActiveCurrencyAndAmountAdapter instance = new ActiveCurrencyAndAmountAdapter();
final String regex = TAG_PATTERN + "((([1-9]{1}\\d{0,15})|([0]{1}))(\\.(\\d){2})?$)";
final String zfh = "(?<=" + TAG_PATTERN + ")([+-])";
final DecimalFormat decimalFormat = new DecimalFormat("###############0.00");
@Override
public String unmarshal(String v) throws Exception {
// TODO Auto-generated method stub
return v;
}
@Override
public String marshal(String v) throws Exception {
Pattern p = Pattern.compile(this.regex);
Matcher m = p.matcher(v);
if (m.find()) {
return v;
} else {
Pattern pattern = Pattern.compile(TAG_PATTERN);
Matcher matcher = pattern.matcher(v);
String tag = "";
if (matcher.find()) {
tag = matcher.group();
}
String amount = v.substring(tag.length());
//去掉正负号
amount = amount.replaceAll(zfh, "");
//格式化金额###############0.00
amount = decimalFormat.format(Double.parseDouble(amount));
return tag + amount;
}
}
}
package com.brilliance.rmb.report.model.format;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.text.DecimalFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 对AmountRate类型数据进行处理
* 表示金额比率,整数部分最多3位数字,小数部分固定5位数字
*/
public class AmountRateAdapter extends XmlAdapter<String, String> {
public static final String TAG_PATTERN = "^(?:/[A-Z0-9]{3}/){0,1}";
public static final AmountRateAdapter instance = new AmountRateAdapter();
final String regex = TAG_PATTERN + "((([1-9]{1}\\d{0,2})|([0]{1}))(\\.(\\d){5})?$)";
final DecimalFormat decimalFormat = new DecimalFormat("##0.00000");
@Override
public String unmarshal(String v) throws Exception {
return v;
}
@Override
public String marshal(String v) throws Exception {
Pattern p = Pattern.compile(this.regex);
Matcher m = p.matcher(v);
if (m.find()) {
return v;
} else {
Pattern pattern = Pattern.compile(TAG_PATTERN);
Matcher matcher = pattern.matcher(v);
String tag = "";
if (matcher.find()) {
tag = matcher.group();
}
String amount = v.substring(tag.length());
//格式化##0.00000
amount = decimalFormat.format(Double.parseDouble(amount));
return tag + amount;
}
}
}
package com.brilliance.rmb.report.model.format;
import cn.com.infosec.util.encoders.Base64;
import javax.xml.bind.annotation.adapters.XmlAdapter;
/**
* DATA标签的原报内容在发报时需要进行BASE64编码,收报时需BASE64解码处理
*/
public class BASE64Adapter extends XmlAdapter<String, String> {
public static final BASE64Adapter instance = new BASE64Adapter();
private static final String CHARSET = "UTF-8";
@Override
public String unmarshal(String v) throws Exception {
return new String(Base64.decode(v), CHARSET);
}
@Override
public String marshal(String v) throws Exception {
byte[] bytes = v.getBytes(CHARSET);
byte[] encode = Base64.encode(bytes);
return new String(encode, CHARSET);
}
}
package com.brilliance.rmb.report.model.format;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 对ISODateTime类型数据进行处理
* 2010-05-01T15:09:05,其中的"T"为日期和时间的分割符,是必需的
*/
public class ISODateTimeAdapter extends XmlAdapter<String, String> {
public static final String TAG_PATTERN = "^(?:/[A-Z0-9]{3}/){0,1}";
public static final ISODateTimeAdapter instance = new ISODateTimeAdapter();
final static String regex = "(?<=" + TAG_PATTERN + "\\d{4}-\\d{2}-\\d{2})(\\s)(?=\\d{2}:\\d{2}:\\d{2})";
final static String replace = "T";
@Override
public String unmarshal(String v) throws Exception {
// TODO Auto-generated method stub
return v;
}
@Override
public String marshal(String v) throws Exception {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(v);
if (m.find()) {
return v.replaceAll(regex, replace);
} else {
return v;
}
}
public static String convert(String v) {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(v);
if (m.find()) {
return v.replaceAll(regex, replace);
} else {
return v;
}
}
}
package com.brilliance.rmb.report.model.format;
import javax.xml.bind.annotation.adapters.XmlAdapter;
/**
* 去掉标签内容前后空字符串
*/
public class TrimAdapter extends XmlAdapter<String, String> {
public static final TrimAdapter instance = new TrimAdapter();
@Override
public String unmarshal(String v) throws Exception {
return v!=null?v.trim():v;
}
@Override
public String marshal(String v) throws Exception {
return v!=null?v.trim():v;
}
}
......@@ -43,18 +43,20 @@
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.infosec</groupId>
<artifactId>netsignapi</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${pom.basedir}/../lib/netsignapi.jar</systemPath>
</dependency>
<dependency>
<groupId>cn.com.infosec</groupId>
<artifactId>ISFJ_v2_0_139_20_BAISC_JDK15</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${pom.basedir}/../lib/ISFJ_v2_0_139_20_BAISC_JDK15.jar</systemPath>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.brilliance.rmb.report.framework;
import com.brilliance.rmb.report.framework.signature.Signature;
import com.brilliance.rmb.report.utils.Assert;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class Config {
final static Config instance = new Config();
private final String PATH = "cfg/efis-config.properties";
//###############通用参数####################
public String charset = "UTF-8";
//###############schema根路径###############
public String schema_location = "cfg/xsd/";
//###############数字签名实现类###############
public String sign_switch = "on";//on:开启加签、签签;off:关闭加签、验签
public Signature signature;
//###############自定义属性###############
private Map<String, String> custom = new HashMap<String, String>();
{
load();
}
private Config() {
}
public static Config getInstance() {
return instance;
}
private void load() {
try {
InputStream is;
ClassLoader classLoader = FilterCache.class.getClassLoader();
if (classLoader != null) {
is = classLoader.getResourceAsStream(PATH);
} else {
is = ClassLoader.getSystemResourceAsStream(PATH);
}
if (is == null) {
String isurl = Thread.currentThread().getContextClassLoader()
.getResource(PATH).getFile();
is = new FileInputStream(isurl);
}
Assert.notNull(is, "efis-config.properties文件没有找到");
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, "utf-8"));
String line = null;
Class<? extends Config> claz = this.getClass();
Field field;
Constructor<?> bestSignature = null;
Constructor<?> fallbackSignature = null;
while ((line = reader.readLine()) != null) {
final int ci = line.indexOf('#');
if (ci >= 0)
line = line.substring(0, ci);
line = line.trim();
if (line.length() > 0) {
String name = null;
int i = line.indexOf('=');
if (i > 0) {
name = line.substring(0, i).trim();
line = line.substring(i + 1).trim();
}
if (line.length() > 0) {
try {
if (name.endsWith("_imp")) {
if ("signature_imp".equals(name)) {
Class<?> instanceClaz = Class.forName(line);
Constructor<?>[] constructors = instanceClaz.getDeclaredConstructors();
for (Constructor constructor : constructors) {
if (constructor.getParameterTypes().length == 0) {
fallbackSignature = constructor;
} else if (constructor.getParameterTypes().length == 1 &&
Map.class.isAssignableFrom(constructor.getParameterTypes()[0])) {
bestSignature = constructor;
break;
}
}
} else {
field = claz.getField(name.replace("_imp", ""));
Class<?> instanceClaz = Class.forName(line);
Object instance = instanceClaz.newInstance();
field.set(this, instance);
}
} else {
field = claz.getField(name);
field.set(this, line);
custom.put(name, line);
}
} catch (Exception e) {
custom.put(name, line);
}
}
}
}
if (bestSignature != null) {
signature = (Signature) bestSignature.newInstance(custom);
} else {
signature = (Signature) fallbackSignature.newInstance();
}
} catch (Throwable t) {
IllegalStateException e = new IllegalStateException(
"Load Config failed: cfg/efis-config.properties).", t);
throw e;
}
}
public Map<String, String> getCustom() {
return custom;
}
@Override
public String toString() {
return "Config [PATH=" + PATH + ", charset=" + charset
+ ", schema_location=" + schema_location + ", signature="
+ signature + ", custom=" + custom + "]";
}
}
package com.brilliance.rmb.report.framework;
import com.brilliance.rmb.report.framework.vo.Result;
public interface Filter {
public static final String PACK = "pack";
public static final String UNPACK = "unpack";
public static final String DOSIGNATURE = "on";
public static final Config config = Config.getInstance();
Result invoke(Invoker invoker, Invocation invocation);
}
package com.brilliance.rmb.report.framework;
import com.brilliance.rmb.report.framework.annotation.Activate;
import com.brilliance.rmb.report.framework.annotation.ActivateComparator;
import com.brilliance.rmb.report.utils.Assert;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class FilterCache {
private final static String FILTER = "efis-filter.properties";
private final static ConcurrentMap<String, Filter> cachedInstances = new ConcurrentHashMap<String, Filter>();
private static Map<String, Class<?>> cachedClasses;
private static final Map<String, Activate> cachedActivates = new ConcurrentHashMap<String, Activate>();
private final static Class<?> type = Filter.class;
private final static String CHARSET = "utf-8";
public static List<Filter> getActivateFilter(String group) {
Map<String, Class<?>> classes = cachedClasses;
if (classes == null) {
classes = loadFilterClasses();
cachedClasses = classes;
}
List<Filter> exts = new ArrayList<Filter>();
for (Map.Entry<String, Activate> entry : cachedActivates.entrySet()) {
String name = entry.getKey();
Activate activate = entry.getValue();
if (isMatchGroup(group, activate.group())) {
Filter ext = getFilter(name);
exts.add(ext);
}
}
Collections.sort(exts, ActivateComparator.COMPARATOR);
return exts;
}
private static boolean isMatchGroup(String group, String[] groups) {
if (group == null || group.length() == 0) {
return true;
}
if (groups != null && groups.length > 0) {
for (String g : groups) {
if (group.equals(g)) {
return true;
}
}
}
return false;
}
public static Filter getFilter(String name) {
if (name == null || name.length() == 0)
throw new IllegalArgumentException("Filter name == null");
Filter instance = cachedInstances.get(name);
if (instance == null) {
instance = createFilter(name);
cachedInstances.putIfAbsent(name, instance);
}
return instance;
}
private static Filter createFilter(String name) {
Class<?> clazz = getFilterClasses().get(name);
if (clazz == null) {
throw new IllegalStateException("No such filter name " + name);
}
try {
return (Filter) clazz.newInstance();
} catch (Throwable t) {
throw new IllegalStateException("Filter instance(name: " + name
+ ") could not be instantiated: " + t.getMessage(), t);
}
}
private static Map<String, Class<?>> getFilterClasses() {
Map<String, Class<?>> classes = cachedClasses;
if (classes == null) {
classes = loadFilterClasses();
cachedClasses = classes;
}
return classes;
}
private static Map<String, Class<?>> loadFilterClasses() {
Map<String, Class<?>> filterClasses = new HashMap<String, Class<?>>();
try {
ClassLoader classLoader = FilterCache.class.getClassLoader();
InputStream is;
if (classLoader != null) {
is = classLoader.getResourceAsStream(FILTER);
} else {
is = ClassLoader.getSystemResourceAsStream(FILTER);
}
if (is == null) {
String isurl = Thread.currentThread().getContextClassLoader()
.getResource(FILTER).getFile();
is = new FileInputStream(isurl);
}
Assert.notNull(is, "efis-filter.properties文件没有找到");
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, CHARSET));
try {
String line = null;
while ((line = reader.readLine()) != null) {
final int ci = line.indexOf('#');
if (ci >= 0)
line = line.substring(0, ci);
line = line.trim();
if (line.length() > 0) {
try {
String name = null;
int i = line.indexOf('=');
if (i > 0) {
name = line.substring(0, i).trim();
line = line.substring(i + 1).trim();
}
if (line.length() > 0) {
Class<?> clazz = Class.forName(line, true,
classLoader);
if (!Filter.class.isAssignableFrom(clazz)) {
throw new IllegalStateException(
"Error when load filter class(interface: "
+ type
+ ", class line: "
+ clazz.getName()
+ "), class "
+ clazz.getName()
+ "is not subtype of interface.");
}
clazz.getConstructor();
if (name == null || name.length() == 0) {
name = clazz.getSimpleName();
if (name.endsWith(type.getSimpleName())) {
name = name
.substring(
0,
name.length()
- type.getSimpleName()
.length());
}
}
Activate activate = clazz
.getAnnotation(Activate.class);
if (activate != null) {
cachedActivates.put(name, activate);
}
Class<?> c = filterClasses.get(name);
if (c == null) {
filterClasses.put(name, clazz);
} else if (c != clazz) {
throw new IllegalStateException(
"Duplicate filter "
+ type.getName()
+ " name " + name
+ " on " + c.getName()
+ " and "
+ clazz.getName());
}
}
} catch (Throwable t) {
IllegalStateException e = new IllegalStateException(
"Failed to load filter class(interface: "
+ type + ", class line: "
+ line + ") in " + FILTER
+ ", cause: " + t.getMessage(),
t);
throw e;
}
}
}
} finally {
reader.close();
}
} catch (Throwable t) {
IllegalStateException e = new IllegalStateException(
"Exception when load filter class(interface: " + type
+ ", class file: " + FILTER + ") in " + FILTER,
t);
throw e;
}
} catch (Throwable t) {
IllegalStateException e = new IllegalStateException(
"Exception when load filter class(interface: " + type
+ ", description file: " + FILTER + ").", t);
throw e;
}
return filterClasses;
}
}
package com.brilliance.rmb.report.framework;
import com.brilliance.rmb.report.framework.exception.ConstructException;
import com.brilliance.rmb.report.framework.vo.MsgHeader;
import com.brilliance.rmb.report.framework.vo.MsgSignature;
import com.brilliance.rmb.report.framework.vo.Result;
import com.brilliance.rmb.report.model.Cfx;
import com.brilliance.rmb.report.model.MsgDocument;
import java.io.UnsupportedEncodingException;
import static com.brilliance.rmb.report.framework.Filter.DOSIGNATURE;
public class Invocation {
private String rawPacket;
private String signature;
private MsgHeader msgHeader;
private MsgSignature msgSignature;
private MsgDocument document;
private String charset;
private Class documentType;
private String action;
private Result errorResult;
private String mingWen;
private boolean sign = DOSIGNATURE.equals(Config.getInstance().sign_switch) ? true
: false;
public Invocation(byte[] raw, String charset, String action) {
if (raw == null || raw.length == 0) {
throw new ConstructException("字节数组不能为空");
}
this.charset = charset;
try {
this.rawPacket = new String(raw, charset);
} catch (UnsupportedEncodingException e) {
throw new ConstructException("不支持的字符编码", e);
}
this.action = action;
}
public Invocation(String rawPacket, String charset, String action) {
if (rawPacket == null || rawPacket.trim().equals("")) {
throw new NullPointerException("报文不能为空");
}
this.rawPacket = rawPacket;
this.charset = charset;
this.action = action;
}
public Invocation(String rawPacket, String charset, String action,
boolean sign) {
this(rawPacket, charset, action);
this.sign = sign;
}
public Invocation(Cfx elcs, String charset, String action, boolean sign) {
this(elcs, charset, action);
this.sign = sign;
}
public Invocation(Cfx elcs, String charset, String action) {
this.document = new MsgDocument(elcs);
this.charset = charset;
this.action = action;
}
public String getRawPacket() {
return rawPacket;
}
public void setRawPacket(String rawPacket) {
this.rawPacket = rawPacket;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public MsgDocument getDocument() {
return document;
}
public void setDocument(MsgDocument document) {
this.document = document;
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public Class<? extends Cfx> getDocumentType() {
return documentType;
}
public void setDocumentType(Class<? extends Cfx> documentType) {
this.documentType = documentType;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public MsgHeader getMsgHeader() {
return msgHeader;
}
public void setMsgHeader(MsgHeader msgHeader) {
this.msgHeader = msgHeader;
}
public MsgSignature getMsgSignature() {
return msgSignature;
}
public void setMsgSignature(MsgSignature msgSignature) {
this.msgSignature = msgSignature;
}
public Result getErrorResult() {
return errorResult;
}
public void setErrorResult(Result errorResult) {
if (this.errorResult != null) {
this.errorResult.combineResult(errorResult);
} else {
this.errorResult = errorResult;
}
}
public String getMingWen() {
return mingWen;
}
public void setMingWen(String mingWen) {
this.mingWen = mingWen;
}
public boolean isSign() {
return sign;
}
}
package com.brilliance.rmb.report.framework;
import com.brilliance.rmb.report.framework.vo.Result;
public interface Invoker {
Result invoke(Invocation invocation);
}
package com.brilliance.rmb.report.framework;
import com.brilliance.rmb.report.framework.vo.Msg;
import com.brilliance.rmb.report.framework.vo.Result;
/**
* 打包各模块到报文中
*/
public class PackResultInvoker implements Invoker {
@Override
public Result invoke(Invocation invocation) {
Msg msg = new Msg(invocation.getMsgHeader(), invocation.getSignature(),invocation.getMingWen(),
invocation.getDocument(),Config.getInstance().charset);
Result result = null;
if (invocation.getErrorResult() != null) {
result = invocation.getErrorResult();
result.setMsg(msg);
} else {
result = new Result(msg);
}
return result;
}
}
package com.brilliance.rmb.report.framework;
import com.brilliance.rmb.report.framework.vo.Msg;
import com.brilliance.rmb.report.framework.vo.Result;
/**
* 解包特殊处理部分
*/
public class UnPackResultInvoker implements Invoker {
@Override
public Result invoke(Invocation invocation) {
Msg msg = new Msg(invocation.getMsgHeader(), invocation.getSignature(), invocation.getMingWen(),
invocation.getDocument(), Config.getInstance().charset);
Result result = null;
if (invocation.getErrorResult() != null) {
result = invocation.getErrorResult();
result.setMsg(msg);
} else {
result = new Result(msg);
}
return result;
}
}
package rmb.report.framework.annotation;
package com.brilliance.rmb.report.framework.annotation;
import java.lang.annotation.*;
......
package rmb.report.framework.annotation;
package com.brilliance.rmb.report.framework.annotation;
import java.lang.annotation.*;
......
package rmb.report.framework.annotation;
package com.brilliance.rmb.report.framework.annotation;
import java.lang.reflect.Field;
import java.util.Comparator;
......
package rmb.report.framework.exception;
package com.brilliance.rmb.report.framework.exception;
public class ConstructException extends RuntimeException{
/**
......
package rmb.report.framework.exception;
package com.brilliance.rmb.report.framework.exception;
public class PacketException extends RuntimeException{
......
package rmb.report.framework.exception;
package com.brilliance.rmb.report.framework.exception;
public class SignException extends RuntimeException{
......
package com.brilliance.rmb.report.framework.filter;
import com.brilliance.rmb.report.framework.Filter;
import com.brilliance.rmb.report.framework.Invocation;
import com.brilliance.rmb.report.framework.Invoker;
import com.brilliance.rmb.report.framework.annotation.Activate;
import com.brilliance.rmb.report.framework.vo.Result;
import com.brilliance.rmb.report.utils.MsgUtil;
/**
* 销毁资源,防止资源泄漏
*/
@Activate(group = {Filter.PACK, Filter.UNPACK}, order = 500)
public class DestoryFilter implements Filter {
@Override
public Result invoke(Invoker next, Invocation invocation) {
try {
if (Filter.PACK.equals(invocation.getAction())) {
MsgUtil.msgtype.remove();
}
} catch (Exception e) {
String msg = Filter.UNPACK.equals(invocation.getAction()) ? "解包" : "打包";
return new Result(false, msg + "处理流程->校验报文时出现异常[" + e.getMessage()
+ "]", e);
}
return next.invoke(invocation);
}
}
package com.brilliance.rmb.report.framework.filter;
import com.alibaba.fastjson.JSONObject;
import com.brilliance.rmb.report.framework.Filter;
import com.brilliance.rmb.report.framework.Invocation;
import com.brilliance.rmb.report.framework.Invoker;
import com.brilliance.rmb.report.framework.annotation.Activate;
import com.brilliance.rmb.report.framework.vo.Result;
import com.brilliance.rmb.report.model.Cfx;
import com.brilliance.rmb.report.model.MsgDocument;
import com.brilliance.rmb.report.utils.FastJsonUtil;
import com.brilliance.rmb.report.utils.MsgUtil;
/**
* json串转Document对象
*/
@Activate(group = Filter.PACK, order = 1)
public class Json2DocumentFilter implements Filter {
@Override
public Result invoke(Invoker next, Invocation invocation) {
JSONObject rawObj = null;
Class<Cfx> claz = null;
if (((rawObj = isJson(invocation.getRawPacket())) != null)
&& rawObj.getString("mesgType") != null
&& !"".equals(rawObj.getString("mesgType"))) {
// 转报文bean
String msgType = rawObj.getString("mesgType");
try {
claz = MsgUtil.findClaz(msgType);
} catch (ClassNotFoundException e) {
return new Result(false, "打包处理流程->报文类型代码[" + msgType
+ "]对应的报文模型不存在", e);
}
MsgUtil.msgtype.set(claz);
invocation.setDocumentType(claz);
Cfx messageRoot = FastJsonUtil.toBean(invocation.getRawPacket(),
claz);
MsgDocument msgDocument = new MsgDocument(messageRoot);
invocation.setDocument(msgDocument);
return next.invoke(invocation);
} else if (invocation.getDocument().getMessageRoot() != null) {
invocation.setDocumentType(invocation.getDocument()
.getMessageRoot().getClass());
return next.invoke(invocation);
} else {
return new Result(false, "打包处理流程->报文类型代码不能为空,字段为[MesgType],请求数据为:["
+ invocation.getRawPacket() + "]");
}
}
private JSONObject isJson(String content) {
return JSONObject.parseObject(content);
}
}
package com.brilliance.rmb.report.framework.filter;
import com.brilliance.rmb.report.framework.Filter;
import com.brilliance.rmb.report.framework.Invocation;
import com.brilliance.rmb.report.framework.Invoker;
import com.brilliance.rmb.report.framework.annotation.Activate;
import com.brilliance.rmb.report.framework.vo.Result;
import com.brilliance.rmb.report.model.Cfx;
import com.brilliance.rmb.report.utils.XmlUtil;
/**
* 打包报文体
*/
@Activate(group = Filter.PACK, order = 20)
public class PackDocumentFilter implements Filter {
@Override
public Result invoke(Invoker next, Invocation invocation) {
try {
String document = XmlUtil.marshToXmlBinding(Cfx.class, invocation.getDocument().messageRoot, invocation.getDocument().getMessageRoot().getMsgType(), invocation.getCharset());
invocation.getDocument().setResult(document);
} catch (Exception e) {
return new Result(false, "打包处理流程->组报文体时出现异常[" + e.getMessage() + "]", e);
}
return next.invoke(invocation);
}
}
package com.brilliance.rmb.report.framework.filter;
import com.brilliance.rmb.report.framework.Filter;
import com.brilliance.rmb.report.framework.Invocation;
import com.brilliance.rmb.report.framework.Invoker;
import com.brilliance.rmb.report.framework.annotation.Activate;
import com.brilliance.rmb.report.framework.vo.Result;
import com.brilliance.rmb.report.model.Cfx;
import com.brilliance.rmb.report.utils.SignatureUtil;
/**
* 打包签名部分 暂不考虑
*/
@Activate(group = Filter.PACK, order = 80)
public class PackSignatureFilter implements Filter {
@Override
public Result invoke(Invoker next, Invocation invocation) {
Class<? extends Cfx> claz = invocation.getDocumentType();
// 生成加签要素序列
String mingWen = invocation.getDocument().getResult();
// 签名
String sign = "";
if (SignatureUtil.isSignByDocTyp(claz) && invocation.isSign()) {
try {
if (invocation.isSign()) {
sign = config.signature.sign(mingWen);
} else {
sign = mingWen;
}
} catch (Exception e) {
return new Result(false, "打包处理流程->编织签名部分时出现异常[" + e.getMessage()
+ "]", e);
}
}
invocation.setSignature(sign);
invocation.setMingWen(mingWen);
return next.invoke(invocation);
}
}
package com.brilliance.rmb.report.framework.filter;
import com.brilliance.rmb.report.framework.Config;
import com.brilliance.rmb.report.framework.Filter;
import com.brilliance.rmb.report.framework.Invocation;
import com.brilliance.rmb.report.framework.Invoker;
import com.brilliance.rmb.report.framework.annotation.Activate;
import com.brilliance.rmb.report.framework.vo.MsgHeader;
import com.brilliance.rmb.report.framework.vo.Result;
import com.brilliance.rmb.report.model.Cfx;
import com.brilliance.rmb.report.model.MsgDocument;
import com.brilliance.rmb.report.utils.MsgHeaderUtil;
import com.brilliance.rmb.report.utils.XmlUtil;
/**
* 解包通用处理,将报文转换为对象
*/
@Activate(group = Filter.UNPACK, order = 0)
public class UnPackComFilter implements Filter {
@Override
public Result invoke(Invoker next, Invocation invocation) {
MsgHeader msgHeader = null;
String rawPacket = "";
try {
// 整个报文
rawPacket = invocation.getRawPacket();
// 处理头部
msgHeader = MsgHeaderUtil.unpackMsgHeader(rawPacket);
invocation.setMsgHeader(msgHeader);
// 处理报文体
String msgType = MsgHeaderUtil.getMsgType(msgHeader.getMsgNo());
Cfx cfx = XmlUtil.unmarshToObjBinding(
Cfx.class, rawPacket, msgType, Config.getInstance().charset);
cfx.setMesgType(msgType);
MsgDocument msgDocument = new MsgDocument();
msgDocument.setMessageRoot(cfx);
msgDocument.setResult(rawPacket);
invocation.setDocument(msgDocument);
invocation.setDocumentType(cfx.getClass());
// 处理数字签名(暂不考虑)
invocation.setSignature("数字签名");
} catch (Exception e) {
if (e instanceof ClassNotFoundException) {
return new Result(false, "解包处理流程->解包通用处理不支持当前报文种类,报文头详细信息:" + msgHeader);
} else {
StringBuilder exstr = new StringBuilder("报文格式不符:");
exstr.append(rawPacket);
return new Result(false, "解包处理流程->解包通用处理出现异常[" + e
+ "]," + exstr.toString() + ",异常类型[" + e.getClass() + "]", e);
}
}
return next.invoke(invocation);
}
}
package com.brilliance.rmb.report.framework.filter;
import com.brilliance.rmb.report.framework.Config;
import com.brilliance.rmb.report.framework.Filter;
import com.brilliance.rmb.report.framework.Invocation;
import com.brilliance.rmb.report.framework.Invoker;
import com.brilliance.rmb.report.framework.annotation.Activate;
import com.brilliance.rmb.report.framework.vo.Result;
import com.brilliance.rmb.report.model.Cfx;
import com.brilliance.rmb.report.utils.SignatureUtil;
/**
* 对于打包:使用xsd进行报文体校验 对于解包:使用xsd进行报文体校验、对数字签名验签
*/
@Activate(group = {Filter.PACK, Filter.UNPACK}, order = 40)
public class ValidateDocumentFilter implements Filter {
@Override
public Result invoke(Invoker next, Invocation invocation) {
String xml = invocation.getDocument().getResult();
Class<? extends Cfx> claz = invocation.getDocumentType();
try {
// 打包处理流程->验证报文体是否正确
boolean xsdCheck = false;
if (Filter.PACK.equals(invocation.getAction())) {
xsdCheck = true;
}
if (xsdCheck) {
}
} catch (Exception e) {
String msg = Filter.UNPACK.equals(invocation.getAction()) ? "解包" : "打包";
return new Result(false, msg + "处理流程->校验报文时出现异常[" + e.getMessage()
+ "]", e);
}
// 解包处理流程->验证数字签名
if (Filter.UNPACK.equals(invocation.getAction()) && SignatureUtil.isSignByDocTyp(claz) && invocation.isSign()) {
String mingWen = invocation.getDocument().getResult();
try {
boolean flag = Config.getInstance().signature.verify(mingWen,
invocation.getSignature());
if (!flag) {
// invocation.setErrorResult(new Result(false, "解包处理流程->报文数字签名验签->验证错误"));
}
} catch (Exception e) {
}
}
return next.invoke(invocation);
}
}
package com.brilliance.rmb.report.framework.signature;
import org.bouncycastle.util.encoders.Base64;
import com.brilliance.rmb.report.framework.Config;
import java.util.Map;
/**
* 基于MD5加解签/Base64加解密默认实现(开发者可继承Signature父类自定义实现)
*/
public class DefaultSignature extends Signature {
public DefaultSignature(Map<String, String> custom) {
}
@Override
public String sign(String mingWen) throws Exception {
return new String(Base64.encode(mingWen.getBytes(Config.getInstance().charset)),Config.getInstance().charset);
}
@Override
public boolean verify(String mingWen, String sign) throws Exception {
String signd = new String(Base64.encode(mingWen.getBytes(Config.getInstance().charset)),Config.getInstance().charset);
return sign.equals(signd);
}
@Override
public String sign903(String mingWen) throws Exception {
return new String(mingWen.getBytes(Config.getInstance().charset), Config.getInstance().charset);
}
@Override
public String makeEnvelope(String origMsg) throws Exception {
return new String(Base64.encode(origMsg.getBytes(Config.getInstance().charset)), Config.getInstance().charset);
}
@Override
public String decryptEnvelop(String enc) throws Exception {
return new String(Base64.decode(enc), Config.getInstance().charset);
}
}
package com.brilliance.rmb.report.framework.signature;
import com.brilliance.rmb.report.framework.Invocation;
public abstract class Signature {
public static ThreadLocal<Invocation> invocation = new ThreadLocal<Invocation>();
/**
* 通用报文加签(非903报文)
*
* @param mingWen 待签名字符串
* @return 加签后的字符串
* @throws Exception
*/
public abstract String sign(String mingWen) throws Exception;
/**
* 通用报文验签(非903报文)
*
* @param mingWen 待校验字符串
* @param sign 签名字符串
* @return 验签成功返回true;失败返回false
* @throws Exception
*/
public abstract boolean verify(String mingWen, String sign) throws Exception;
/**
* 903报文加签
*
* @param mingWen 待签名字符串
* @return 加签后的字符串
* @throws Exception
*/
public String sign903(String mingWen) throws Exception {
return mingWen;
}
/**
* 处理收到的903报文
*
* @param mingWen 签名数据
* @param sign 数字签名
* @param chgTp 变更类型 CC00:新增 CC02:撤销
* @return 成功返回ture
* @throws Exception
*/
public boolean handle903(String mingWen, String sign, String chgTp) throws Exception {
return true;
}
/**
* 加密数字信封
*
* @param origMsg 待加密串
* @return 加密串
*/
public String makeEnvelope(String origMsg) throws Exception {
return origMsg;
}
/**
* 解密数字信封
*
* @param enc 待解密串
* @return 解密串
*/
public String decryptEnvelop(String enc) throws Exception {
return enc;
}
}
package com.brilliance.rmb.report.framework.vo;
import com.brilliance.rmb.report.model.MsgDocument;
public class Msg {
private MsgHeader header;
private MsgSignature signature;
private MsgDocument document;
private String charset;
private volatile String message;
private volatile String messageNoSign;
public Msg() {
}
public Msg(MsgHeader header, String signature, String rawSignature, MsgDocument msgDocument,
String charset) {
this.header = header;
this.signature = new MsgSignature(signature, rawSignature);
this.document = msgDocument;
this.charset = charset;
}
public MsgHeader getHeader() {
return header;
}
public void setHeader(MsgHeader header) {
this.header = header;
}
public MsgSignature getSignature() {
return signature;
}
public void setSignature(MsgSignature signature) {
this.signature = signature;
}
public MsgDocument getDocument() {
return document;
}
public void setDocument(MsgDocument document) {
this.document = document;
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
/**
* 获取报文字节数组
*
* @return
* @throws Exception
*/
public byte[] getMessageBytes() throws Exception {
return getMessage().getBytes(charset);
}
/**
* 获取报文字节数组
*
* @return
* @throws Exception
*/
public byte[] getMessageNoSignBytes() throws Exception {
return getMessageNoSign().getBytes(charset);
}
/**
* 获取报文(报文三部分组成:报文头+签名+报文体)
*
* @return
*/
public String getMessage() {
if (message == null || "".equals(message)) {
StringBuilder sb = new StringBuilder();
sb.append(document.getResult());
sb.append(signature.getResult());
message = sb.toString();
}
return message;
}
/**
* 获取报文(报文三部分组成:报文头+待签名串+报文体)
*
* @return
*/
public String getMessageNoSign() {
if (messageNoSign == null || "".equals(messageNoSign)) {
StringBuilder sb = new StringBuilder();
sb.append(document.getResult());
sb.append(signature.getResultNoSign());
messageNoSign = sb.toString();
}
return messageNoSign;
}
/**
* 获取报文头
*
* @return
*/
public String getMessageHeadPart() {
return header.getResult();
}
/**
* 获取报文签名部分
*
* @return
*/
public String getSignaturePart() {
return signature.getResult();
}
/**
* 获取报文体部分
*
* @return
*/
public String getDocumentPart() {
return document.getResult();
}
}
package com.brilliance.rmb.report.framework.vo;
import com.brilliance.rmb.report.model.Cfx;
import com.brilliance.rmb.report.model.HEAD;
public class MsgHeader {
private String VER;
private String SRC;
private String DES;
private String APP;
private String MsgNo;
private String MsgID;
private String MsgRef;
private String WorkDate;
private String Reserve;
private String result;
public MsgHeader(Cfx cfx) {
HEAD head = cfx.getHead();
VER = head.getVER();
SRC = head.getSRC();
DES = head.getDES();
APP = head.getAPP();
MsgNo = head.getMsgNo();
MsgID = head.getMsgID();
MsgRef = head.getMsgRef();
WorkDate = head.getWorkDate();
Reserve = head.getReserve();
}
public MsgHeader(String result) {
this.result = result;
}
public MsgHeader() {
}
public String getVER() {
return VER;
}
public void setVER(String VER) {
this.VER = VER;
}
public String getSRC() {
return SRC;
}
public void setSRC(String SRC) {
this.SRC = SRC;
}
public String getDES() {
return DES;
}
public void setDES(String DES) {
this.DES = DES;
}
public String getAPP() {
return APP;
}
public void setAPP(String APP) {
this.APP = APP;
}
public String getMsgNo() {
return MsgNo;
}
public void setMsgNo(String msgNo) {
MsgNo = msgNo;
}
public String getMsgID() {
return MsgID;
}
public void setMsgID(String msgID) {
MsgID = msgID;
}
public String getMsgRef() {
return MsgRef;
}
public void setMsgRef(String msgRef) {
MsgRef = msgRef;
}
public String getWorkDate() {
return WorkDate;
}
public void setWorkDate(String workDate) {
WorkDate = workDate;
}
public String getReserve() {
return Reserve;
}
public void setReserve(String reserve) {
Reserve = reserve;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getMesgType() {
return Cfx.CLASS_PREFIX + getMsgNo();
}
}
package com.brilliance.rmb.report.framework.vo;
import com.brilliance.rmb.report.framework.Config;
import com.brilliance.rmb.report.framework.exception.PacketException;
import java.io.UnsupportedEncodingException;
public class MsgSignature {
private String DigitalSignature;
private String rawSignature;
public MsgSignature() {
}
public MsgSignature(String signature) {
DigitalSignature = signature;
}
public MsgSignature(String DigitalSignature, String rawSignature) {
this.DigitalSignature = DigitalSignature;
this.rawSignature = rawSignature;
}
public String getDigitalSignature() {
return DigitalSignature;
}
public void setDigitalSignature(String digitalSignature) {
DigitalSignature = digitalSignature;
}
public String getRawSignature() {
return rawSignature;
}
public void setRawSignature(String rawSignature) {
this.rawSignature = rawSignature;
}
public String getResult() {
if (DigitalSignature != null && !DigitalSignature.trim().equals("")) {
return DigitalSignature;
}
return "";
}
public String getResultNoSign() {
if (DigitalSignature != null && !DigitalSignature.trim().equals("")) {
try {
return String.format("%08d", DigitalSignature.getBytes(Config.getInstance().charset).length) + DigitalSignature + "\r\n";
} catch (UnsupportedEncodingException e) {
throw new PacketException("不支持的字符集");
}
}
return "";
}
}
package com.brilliance.rmb.report.framework.vo;
import com.brilliance.rmb.report.framework.Config;
import com.brilliance.rmb.report.framework.exception.PacketException;
import com.brilliance.rmb.report.model.Cfx;
import com.brilliance.rmb.report.utils.FastJsonUtil;
import com.brilliance.rmb.report.utils.StringUtil;
import com.google.gson.Gson;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.util.Map;
public class Result {
private Msg msg;
private boolean isSuccess = true;
private String errMsg;
private Throwable throwable;
private boolean strict = true;
public Result() {
this.isSuccess = true;
}
public Result(boolean isSuccess) {
this.isSuccess = isSuccess;
}
public Result(Msg msg) {
this.isSuccess = true;
this.msg = msg;
}
public Result(boolean isSuccess, String errMsg) {
this.isSuccess = isSuccess;
this.errMsg = errMsg;
}
public Result(boolean isSuccess, String errMsg, Throwable throwable) {
this.isSuccess = isSuccess;
this.errMsg = errMsg;
this.throwable = throwable;
}
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
public Throwable getThrowable() {
return throwable;
}
public void setThrowable(Throwable throwable) {
this.throwable = throwable;
}
public Msg getMsg() {
validate();
return msg;
}
public void setMsg(Msg msg) {
this.msg = msg;
}
/**
* 获取字节数组形式的报文(报文三部分组成:报文头+签名+报文体)
*
* @return 字节数组形式的报文
* @throws Exception
*/
public byte[] getMessageBytes() throws Exception {
return getMsg().getMessageBytes();
}
/**
* 获取字节数组形式的报文(报文三部分组成:报文头+待签名串+报文体)
*
* @return 字节数组形式的报文
* @throws Exception
*/
public byte[] getMessageNoSignBytes() throws Exception {
return getMsg().getMessageNoSignBytes();
}
/**
* 获取字符串形式的报文(报文三部分组成:报文头+签名+报文体)
*
* @return 字符串形式的报文
*/
public String getMessage() {
return getMsg().getMessage();
}
/**
* 获取字符串形式的报文(报文三部分组成:报文头+待签名串+报文体)
*
* @return 字符串形式的报文
*/
public String getMessageNoSign() {
return getMsg().getMessageNoSign();
}
/**
* 获取字符串形式的报文签名域
*
* @return 字符串形式的报文签名域
*/
public String getSignature() {
return getMsg().getSignaturePart();
}
/**
* 获取字符串形式的报文体
*
* @return 字符串形式的报文体
*/
public String getBody() {
return getMsg().getDocumentPart();
}
/**
* 获取电证报文模型对象
*
* @return 电证报文模型对象
*/
public Cfx getElcsModel() {
return getMsg().getDocument().getMessageRoot();
}
/**
* 获取电证报文待加签串
*
* @return 电证报文待加签串
*/
public String getRawSignatureInfo() {
return getMsg().getSignature().getRawSignature();
}
/**
* 获取电证报文加签串
*
* @return 电证报文加签串
*/
public String getSignatureInfo() {
return getMsg().getSignature().getDigitalSignature();
}
/**
* 获取电证报文模型对象json串
* 修复
*
* @return 电证报文模型json串
*/
public String getElcsModelForJson() {
//改用google的gson包,json按照字段顺序排列
Gson gson = new Gson();
return gson.toJson(getElcsModel());
}
/**
* 获取电证报文模型扁平化结构
*
* @return 电证报文模型对象
* @throws Exception
*/
public Map<String, String> getElcsFlatHierarchy() throws Exception {
return getElcsModel().getFlatCfx();
}
/**
* 保存完整报文到本地文件
*
* @param path 文件路径
* @throws Exception
*/
public void saveMessageForXml(String path) throws Exception {
FileUtils.writeByteArrayToFile(new File(path), getMessageBytes());
}
public void saveMessageNoSign(String path) throws Exception {
FileUtils.writeByteArrayToFile(new File(path), getMessageNoSignBytes());
}
public void saveElcsModelForJson(String path) throws Exception {
FileUtils.writeStringToFile(new File(path), getElcsModelForJson(),
Config.getInstance().charset);
}
/**
* 保存报文模型扁平化结构到本地文件
*
* @param path 文件路径
* @throws Exception
*/
public void saveElcsFlatHierarchy(String path) throws Exception {
String content = FastJsonUtil.toJSONString(getElcsFlatHierarchy());
FileUtils.writeStringToFile(new File(path), content,
Config.getInstance().charset);
}
public void validate() {
if (!isSuccess && strict) {
if (throwable != null) {
throw new PacketException(errMsg, throwable);
}
throw new PacketException(errMsg);
}
}
public boolean isStrict() {
return strict;
}
public void setStrict(boolean strict) {
this.strict = strict;
}
public void combineResult(Result other) {
if (StringUtil.isNotEmpty(other.errMsg)) {
this.errMsg += "--->" + other.errMsg;
}
if (other.throwable != null) {
this.throwable = other.throwable;
}
}
}
package com.brilliance.rmb.report.utils;
public abstract class Assert {
protected Assert() {
}
public static void notNull(Object obj, String message) {
if (obj == null) {
throw new IllegalArgumentException(message);
}
}
public static void notNullByArray(Object[] obj, String message) {
if (obj == null || obj.length == 0) {
throw new IllegalArgumentException(message);
}
}
public static void state(boolean expression, String message) {
if (!expression) {
throw new IllegalStateException(message);
}
}
}
package rmb.report.utils;
package com.brilliance.rmb.report.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
......
package com.brilliance.rmb.report.utils;
import com.brilliance.rmb.report.framework.Config;
import com.brilliance.rmb.report.framework.vo.MsgHeader;
import com.brilliance.rmb.report.model.HEAD;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MsgHeaderUtil {
private static final Pattern pattern = Pattern.compile("<HEAD[\\w\\W]*?</HEAD>");
private static final String PREFIX = "cfx";
/**
* 解报文头工具类
*/
public static MsgHeader unpackMsgHeader(String raw) throws Exception {
MsgHeader msgHeader = new MsgHeader();
Matcher m = pattern.matcher(raw);
if (m.find()) {
String headerStr = m.group(0).trim();
if (StringUtil.isNotEmpty(headerStr)) {
HEAD head = XmlUtil.unmarshToObjBinding(
HEAD.class, headerStr, "HEAD", Config.getInstance().charset);
msgHeader.setMsgID(head.getMsgID());
msgHeader.setMsgNo(head.getMsgNo());
msgHeader.setMsgRef(head.getMsgRef());
msgHeader.setAPP(head.getAPP());
msgHeader.setDES(head.getDES());
msgHeader.setReserve(head.getReserve());
msgHeader.setSRC(head.getSRC());
msgHeader.setVER(head.getVER());
msgHeader.setWorkDate(head.getWorkDate());
msgHeader.setResult(headerStr);
}
}
return msgHeader;
}
public static String getMsgType(String msgNo) {
return PREFIX + msgNo;
}
}
package com.brilliance.rmb.report.utils;
import com.brilliance.rmb.report.framework.*;
import com.brilliance.rmb.report.framework.vo.Result;
import com.brilliance.rmb.report.model.Cfx;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.util.List;
public class MsgUtil {
private final static Invoker PACK;
private final static Invoker UNPACK;
private final static Config config = Config.getInstance();
private static final String BASE_PACKAGE = "com.brilliance.rmb.report.model.";
public static ThreadLocal<Class<? extends Cfx>> msgtype = new ThreadLocal<>();
static {
PACK = buildInvokerChain(new PackResultInvoker(), Filter.PACK);
UNPACK = buildInvokerChain(new UnPackResultInvoker(), Filter.UNPACK);
}
/**
* 利用dzxt-bean提供的报文模型对象和utf-8编码进行打包
*
* @param elcs 报文模型对象
* @return 返回打包结果对象
* @throws Exception
*/
public static Result packMessage(Cfx elcs) {
return packMessage(elcs, config.charset);
}
/**
* 利用dzxt-bean提供的报文模型对象和自定义编码进行打包
*
* @param elcs dzxt-bean提供的报文模型对象
* @param charset 编码
* @return 返回打包结果对象
* @throws Exception
*/
public static Result packMessage(Cfx elcs, String charset) {
Assert.notNull(PACK, "打包流程为空,请联系管理员");
Result result = PACK.invoke(new Invocation(elcs, charset, Filter.PACK));
return result;
}
/**
* 利用符合电证报文结构的json字符串和utf-8编码进行打包
*
* @param rawReqMessage 符合电证报文结构的json串
* @return 返回打包结果对象
*/
public static Result packMessage(String rawReqMessage) {
return packMessage(rawReqMessage, config.charset);
}
/**
* 利用dzxt-bean提供的报文模型对象和utf-8编码进行不加签打包
*
* @param elcs 报文模型对象
* @return 返回打包结果对象
*/
public static Result packNoSignMessage(Cfx elcs) {
Assert.notNull(PACK, "打包流程为空,请联系管理员");
Result result = PACK.invoke(new Invocation(elcs, config.charset,
Filter.PACK, false));
return result;
}
/**
* 利用符合电证报文结构的json字符串和utf-8编码进行不加签打包
*
* @param rawReqMessage 符合电证报文结构的json串
* @return 返回打包结果对象
*/
public static Result packNoSignMessage(String rawReqMessage) {
Assert.notNull(PACK, "打包流程为空,请联系管理员");
Result result = PACK.invoke(new Invocation(rawReqMessage, config.charset,
Filter.PACK, false));
return result;
}
/**
* 利用符合电证报文结构的json字符串和自定义编码进行打包
*
* @param rawReqMessage 符合电证报文结构的json串
* @param charset 编码
* @return 返回打包结果对象
* @throws Exception
*/
public static Result packMessage(String rawReqMessage, String charset) {
Assert.notNull(PACK, "打包流程为空,请联系管理员");
Result result = PACK.invoke(new Invocation(rawReqMessage, charset,
Filter.PACK));
return result;
}
/**
* 利用复合电证报文结构的字节数组和utf-8编码进行打包
*
* @param rawReqMessage 复合电证报文结构的字节数组
* @return 返回打包结果对象
* @throws Exception
*/
public static Result packMessage(byte[] rawReqMessage) {
return packMessage(rawReqMessage, config.charset);
}
/**
* 利用复合电证报文结构的字节数组和自定义编码进行打包
*
* @param rawReqMessage 复合电证报文结构的字节数组
* @param charset 编码
* @return 返回打包结果对象
* @throws Exception
*/
public static Result packMessage(byte[] rawReqMessage, String charset) {
Assert.notNull(PACK, "打包流程为空,请联系管理员");
Result result = PACK.invoke(new Invocation(rawReqMessage, charset,
Filter.PACK));
return result;
}
/**
* 利用符合电证报文结构的json字符串和utf-8编码进行解包
*
* @param resMessage 符合电证报文结构的json字符串
* @return 返回解包结果对象
* @throws Exception
*/
public static Result unPackMessage(String resMessage) {
return unPackMessage(resMessage, config.charset);
}
/**
* 利用符合电证报文结构的json字符串和自定义编码进行非验签解包
*
* @param resMessage 符合电证报文结构的json字符串
* @return 返回解包结果对象
*/
public static Result unPackNoSignMessage(String resMessage) {
Assert.notNull(UNPACK, "解包流程为空,请联系管理员");
Result result = UNPACK.invoke(new Invocation(resMessage, config.charset,
Filter.UNPACK, false));
return result;
}
/**
* 利用符合电证报文结构的json字符串和自定义编码进行解包
*
* @param resMessage 符合电证报文结构的json字符串
* @param charset 编码
* @return 返回解包结果对象
*/
public static Result unPackMessage(String resMessage, String charset) {
Assert.notNull(UNPACK, "解包流程为空,请联系管理员");
Result result = UNPACK.invoke(new Invocation(resMessage, charset,
Filter.UNPACK));
return result;
}
/**
* 利用符合电证报文结构的json字节数组和utf-8编码进行解包
*
* @param resMessage 符合电证报文结构的json字节数组
* @return 返回解包结果对象
* @throws Exception
*/
public static Result unPackMessage(byte[] resMessage) throws Exception {
return unPackMessage(resMessage, config.charset);
}
/**
* 利用符合电证报文结构的json字节数组和自定义编码进行解包
*
* @param resMessage 符合电证报文结构的json字节数组
* @param charset 编码
* @return 返回解包结果对象
* @throws Exception
*/
public static Result unPackMessage(byte[] resMessage, String charset)
throws Exception {
Assert.notNull(UNPACK, "解包流程为空,请联系管理员");
Result result = UNPACK.invoke(new Invocation(resMessage, charset,
Filter.UNPACK));
return result;
}
/**
* 根据电证报文文件和utf-8编码进行解包
*
* @param file 电证报文文件
* @return 返回解包结果对象
* @throws Exception
*/
public static Result unPackNoSignMessage(File file) throws Exception {
return unPackNoSignMessage(FileUtils.readFileToString(file, config.charset));
}
/**
* 根据电证报文文件和utf-8编码进行解包
*
* @param file 电证报文文件
* @return 返回解包结果对象
* @throws Exception
*/
public static Result unPackMessage(File file) throws Exception {
return unPackMessage(file, config.charset);
}
/**
* 根据电证报文文件和自定义编码进行解包
*
* @param file 电证报文文件
* @return 返回解包结果对象
* @throws Exception
*/
public static Result unPackMessage(File file, String charset) throws Exception {
return unPackMessage(FileUtils.readFileToString(file, charset), config.charset);
}
private static Invoker buildInvokerChain(final Invoker invoker, String group) {
Invoker last = invoker;
List<Filter> filters = FilterCache.getActivateFilter(group);
if (filters.size() > 0) {
for (int i = filters.size() - 1; i >= 0; i--) {
final Filter filter = filters.get(i);
final Invoker next = last;
last = new Invoker() {
public Result invoke(Invocation invocation) {
return filter.invoke(next, invocation);
}
};
}
}
return last;
}
public static Class<Cfx> findClaz(String msgType) throws ClassNotFoundException {
String className = BASE_PACKAGE + msgType.replaceAll("\\.", "_") + "."
+ msgType.substring(0, 1).toUpperCase()
+ msgType.substring(1).replaceAll("\\.", "_");
return (Class<Cfx>) Class.forName(className);
}
}
package rmb.report.utils;
package com.brilliance.rmb.report.utils;
import org.bouncycastle.util.encoders.Base64;
......
package com.brilliance.rmb.report.utils;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import javax.xml.bind.*;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Source;
import javax.xml.transform.sax.SAXSource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.StringWriter;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class XmlUtil {
private static final ConcurrentHashMap<Class<?>, JAXBContext> jaxbContextMap = new ConcurrentHashMap<Class<?>, JAXBContext>();
private static final Map<String, Class<?>> commonClassCache = new ConcurrentHashMap<String, Class<?>>();
private static final String basePth = "com.brilliance.rmb.report.model";
private static final String headPth = "com.brilliance.rmb.report.model.HEAD";
private static SAXParserFactory sax = SAXParserFactory.newInstance();
public static ClassLoader getDefaultClassLoader() {
ClassLoader cl = null;
try {
cl = Thread.currentThread().getContextClassLoader();
} catch (Throwable ex) {
}
if (cl == null) {
cl = XmlUtil.class.getClassLoader();
if (cl == null) {
try {
cl = ClassLoader.getSystemClassLoader();
} catch (Throwable ex) {
}
}
}
return cl;
}
private static Class getMsgClaz(String msgTyp) throws ClassNotFoundException {
Assert.state(StringUtil.isNotEmpty(msgTyp), "报文类型不能为空");
Class msgClaz = commonClassCache.get(msgTyp);
if (msgClaz == null) {
String rawmsgTyp = msgTyp.replaceAll("\\.", "_");
if ("HEAD".equalsIgnoreCase(msgTyp)) {
msgClaz = Class.forName(headPth, false, getDefaultClassLoader());
} else {
String bigFsgTyp = rawmsgTyp.substring(0, 1).toUpperCase() + rawmsgTyp.substring(1);
StringBuilder sb = new StringBuilder(basePth);
sb.append(".").append(rawmsgTyp).append(".").append(bigFsgTyp);
msgClaz = Class.forName(sb.toString(), false, getDefaultClassLoader());
}
commonClassCache.put(msgTyp, msgClaz);
}
return msgClaz;
}
/**
* 将JAXB实现对象转换成XML格式的字符串
*/
public static <T> String marshToXmlBinding(Class<T> tclz, T t, String msgTyp, String encoding) throws Exception {
Assert.notNull(t, "待转换对象不能为空");
Class msgTypClaz = getMsgClaz(msgTyp);
JAXBContext jc = jaxbContextMap.get(msgTypClaz);
if (jc == null) {
jc = JAXBContext.newInstance(tclz, msgTypClaz);
jaxbContextMap.put(msgTypClaz, jc);
}
Marshaller u = jc.createMarshaller();
// XML内容格式化
// 指定是否使用换行和缩排对已编组 XML 数据进行格式化的属性名称。
u.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
u.setProperty(Marshaller.JAXB_ENCODING, encoding);
// 为了移除xml中的standalone属性
u.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
StringWriter sw = new StringWriter();
sw.write("<?xml version=\"1.0\" encoding=\"" + encoding + "\" ?>\n");
u.marshal(t, sw);
String xmlstr = sw.toString();
return xmlstr;
}
/**
* 将XML格式的字节数组转换成JAXB实现对象
*/
@SuppressWarnings("unchecked")
public static <T> T unmarshToObjBinding(Class<T> tclz, byte[] bytes, String msgTyp)
throws Exception {
Assert.notNull(bytes, "待转换xml字节流不能为空");
Class msgTypClaz = getMsgClaz(msgTyp);
JAXBContext jc = jaxbContextMap.get(msgTypClaz);
if (jc == null) {
jc = JAXBContext.newInstance(tclz, msgTypClaz);
jaxbContextMap.put(msgTypClaz, jc);
}
Unmarshaller un = jc.createUnmarshaller();
sax.setNamespaceAware(false);
XMLReader xmlReader = sax.newSAXParser().getXMLReader();
Source source = new SAXSource(xmlReader, new InputSource(
new ByteArrayInputStream(bytes)));
Object obj = un.unmarshal(source);
if (JAXBElement.class.isAssignableFrom(obj.getClass())) {
obj = (T) JAXBIntrospector.getValue(obj);
}
return (T) obj;
}
/**
* 将XML格式的字符串转换成JAXB实现对象
*/
public static <T> T unmarshToObjBinding(Class<T> tclz, String xmlstr, String msgTyp, String encoding) throws Exception {
Assert.notNull(xmlstr, "待转换xml字符串不能为空");
return unmarshToObjBinding(tclz, xmlstr.getBytes(encoding), msgTyp);
}
/**
* 将XML格式的文件转换成JAXB实现对象
*/
@SuppressWarnings("unchecked")
public static <T> T unmarshToObjBinding(Class<T> tclz, File file)
throws Exception {
Assert.notNull(file, "带转为对象不能为空");
String msgTyp = file.getName();
msgTyp = msgTyp.indexOf(".xml") != -1 ? msgTyp.substring(0, msgTyp.indexOf(".xml")) : msgTyp;
Class msgTypClaz = getMsgClaz(msgTyp);
JAXBContext jc = jaxbContextMap.get(msgTypClaz);
if (jc == null) {
jc = JAXBContext.newInstance(tclz, msgTypClaz);
jaxbContextMap.put(msgTypClaz, jc);
}
Unmarshaller un = jc.createUnmarshaller();
sax.setNamespaceAware(false);
XMLReader xmlReader = sax.newSAXParser().getXMLReader();
Source source = new SAXSource(xmlReader, new InputSource(
new FileInputStream(file)));
Object obj = un.unmarshal(source);
if (JAXBElement.class.isAssignableFrom(obj.getClass())) {
obj = (T) JAXBIntrospector.getValue(obj);
}
return (T) obj;
}
}
\ No newline at end of file
package rmb.report.utils;
package com.brilliance.rmb.report.utils;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
......
#############COMMON################
#编码方式(必须设置一个,ELCS为UTF-8)
charset=GBK
#############签名相关配置#############
#on:开启加签、验签;off:关闭加签、验签、加密、解密
sign_switch=on
#签名自定义实现类
signature_imp=com.brilliance.rmb.report.framework.signature.DefaultSignature
#############自定义xsd文件所在目录的路径【相对路径或绝对路径】(默认在classpath的cfg/xsd/目录下)#############
#schema_location=cfg/xsd/
\ No newline at end of file
json2bean=com.brilliance.rmb.report.framework.filter.Json2DocumentFilter
packdocument=com.brilliance.rmb.report.framework.filter.PackDocumentFilter
packsignature=com.brilliance.rmb.report.framework.filter.PackSignatureFilter
validatedocument=com.brilliance.rmb.report.framework.filter.ValidateDocumentFilter
unpackcom=com.brilliance.rmb.report.framework.filter.UnPackComFilter
destroyres=com.brilliance.rmb.report.framework.filter.DestoryFilter
\ No newline at end of file
package com.brilliance;
import com.brilliance.rmb.report.framework.vo.Result;
import com.brilliance.rmb.report.utils.MsgUtil;
import org.junit.Test;
import java.io.File;
import java.net.URL;
public class MsgTest {
@Test
public void ccms_903_003_01Test() {
msgTest("2102.xml");
}
protected void msgTest(String path) {
try {
URL resource = this.getClass().getClassLoader().getResource(path);
Result resResult = MsgUtil.unPackMessage(new File(resource.getFile()));
if (resResult.isSuccess()) {
Result result = MsgUtil.packMessage(resResult.getElcsModelForJson());
String body = result.getBody();
String message = result.getMessage();
String messageNoSign = result.getMessageNoSign();
String rawSignatureInfo = result.getRawSignatureInfo();
String signature = result.getSignature();
String signatureInfo = result.getSignatureInfo();
if (!result.isSuccess()) {
System.out.println(result.getErrMsg());
} else {
System.out.println(result.getMessage());
System.out.println(result.getSignatureInfo());
}
} else {
//收到报文,当校验失败时,依旧想获取报文,将结构模式设置为非严格模式即可
System.out.println(resResult.getErrMsg());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<CFX>
<HEAD>
<VER>1.0</VER>
<SRC>402100000001</SRC>
<DES>100000000000</DES>
<APP>RCPMIS</APP>
<MsgNo>2101</MsgNo>
<MsgID>20051024200722000440</MsgID>
<MsgRef>20051024200722000440</MsgRef>
<WorkDate>20200722</WorkDate>
<Reserve/>
</HEAD>
<MSG>
<BatchHead2101>
<SendOrgCode>102100009980</SendOrgCode>
<EntrustDate>20200722</EntrustDate>
<PackNo>00000001</PackNo>
<AllNum>1</AllNum>
</BatchHead2101>
<Income2101>
<LevyNo>110112001003200722010001</LevyNo>
<OperType>1</OperType>
<ActionDesc>String</ActionDesc>
<BankOrgCode>000000000000</BankOrgCode>
<PayeeName>境内收款主体</PayeeName>
<PayeeAttr>2001</PayeeAttr>
<PayeeOrgCode>123456789123456789</PayeeOrgCode>
<PayerName>境外付款主体</PayerName>
<PayBankCode>123456789012</PayBankCode>
<AllAmt>100.00</AllAmt>
<PayeeDate>20200721</PayeeDate>
<BalanceMode>MT</BalanceMode>
<PayeeCNY>CNY</PayeeCNY>
<BankTraNo>123456</BankTraNo>
<AddWord>交易</AddWord>
<Reserve1></Reserve1>
<Reserve2></Reserve2>
<Reserve3></Reserve3>
<Reserve4></Reserve4>
<Reserve5></Reserve5>
<Reserve6></Reserve6>
</Income2101>
</MSG>
</CFX>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment