-- 只是把代码贴上来了,有时间整理下思路
公司的接口又臭又长,同事提供了一个思路,采用xml进行不涉及业务的参数的校验。
可以在excel上编辑,然后生成xml,校验器会自动对每个参数进行长度、数值、正则、必填等校验。解放双手,
公司不怎么提倡创新,估计只有这一个项目会使用吧,不过有十几个接口,够用了。。。
请求->Business->校验公共参数-》初始化校验器->校验非业务->校验业务。。。
首先定义参数的属性
RemoteParam
然后书写校验器
RemoteParamValidator
准备xml文件
spicii-1...
准备dtd约束(可以忽略)
rules.dtd
接口抽象类公共调用
AbstractN9ServerBusiness
package com.nstc.aims.model;
import com.nstc.util.CastUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.xml.sax.Attributes;
/**
* <p>Title: RemoteParam.java</p>
* <p>Description: 接口参数</p>
* <p>Company: 北京九恒星科技股份有限公司</p>
*
* @author luhao
* @since 2020-03-14 11:13
*/
public class RemoteParam {
private String name;
private String remark;
private Integer length;
//小数位数
private Integer decimalDigits;
//类型 NUMBER/NUMBER(X,X)/INTEGER/VARCHAR2(XX)/DATE
private String type;
//必填
private Integer require;
private String reg;
private String fieldName;
private final static String NAME_TAG = "name";
private final static String REMARK_TAG = "remark";
private final static String TYPE_TAG = "type";
private final static String REQUIRE_TAG = "require";
private final static String REG_TAG = "reg";
private final static String FIELD_NAME = "fieldName";
private final static Integer YES = 1;
private final static String INTEGER_REG = "^-?\\d+$";
private final static String DATE_REG = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|" +
"((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|" +
"((0[48]|[2468][048]|[3579][26])00))-02-29)$";
private String getDoubleReg() {
return "^[-\\+]?\\d{1," + length + "}(\\.\\d{0," + decimalDigits + "})?|\\.\\d{1," + decimalDigits + "}$";
}
public RemoteParam(Attributes attributes) {
name = attributes.getValue(NAME_TAG);
remark = attributes.getValue(REMARK_TAG);
type = attributes.getValue(TYPE_TAG);
require = CastUtil.toInteger(attributes.getValue(REQUIRE_TAG));
reg = CastUtil.toNotEmptyString(attributes.getValue(REG_TAG));
fieldName = CastUtil.toNotEmptyString(attributes.getValue(FIELD_NAME));
setLength(type);
}
public void setLength(String type) {
if ("D".equals(type)) {
length = 10;
decimalDigits = null;
} else if (type.startsWith("C")) {
length = CastUtil.toInteger(type.replace("C", ""));
decimalDigits = null;
} else if (type.startsWith("N") && type.contains(",")) {
String[] strArr = type.replace("N", "").split(",");
length = CastUtil.toInteger(strArr[0]);
decimalDigits = CastUtil.toInteger(strArr[1]);
} else if (type.startsWith("N") && !type.contains(",")) {
length = CastUtil.toInteger(type.replace("N", ""));
decimalDigits = null;
}
}
public void validate(Object obj, String sign) {
if (obj == null) {
Validate.isTrue(!YES.equals(require), notice(sign) + "不能为空!");
}
String value = (String) obj;
if (StringUtils.isBlank(value)) {
Validate.isTrue(!YES.equals(require), notice(sign) + "不能为空!");
} else {
if (type.startsWith("C")) {
Validate.isTrue(value.length() <= length, notice(sign) + "长度不可大于" + length + ":" + obj);
} else if ("N".equals(type) && decimalDigits == null) {
Validate.isTrue(value.matches(INTEGER_REG), notice(sign) + "不满足整数规则!" + ":" + obj);
Validate.isTrue(value.length() <= length, notice(sign) + "长度不可大于" + length + ":" + obj);
} else if (decimalDigits != null) {
Validate.isTrue(value.matches(getDoubleReg()), notice(sign) + "必须为浮点数类型,且整数位不可超过" + length + ",小数位不可超过" + decimalDigits + ":" + obj);
} else if ("D".equals(type)) {
Validate.isTrue(value.matches(DATE_REG), notice(sign) + "不符合日期格式!" + ":" + obj);
}
if (StringUtils.isNotBlank(reg)) {
Validate.isTrue(value.matches(reg), notice(sign) + "参数值不合法!" + ":" + obj);
}
}
}
/**
* 提示信息
* @param sign 标记错误的未知
* @return
*/
private String notice(String sign){
return sign + remark + "(" + name + ")";
}
@Override
public String toString() {
return "RemoteParam{" +
"name='" + name + '\'' +
", remark='" + remark + '\'' +
", length=" + length +
", decimalDigits=" + decimalDigits +
", type='" + type + '\'' +
", require=" + require +
", reg='" + reg + '\'' +
", fieldName='" + fieldName + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Integer getLength() {
return length;
}
public void setLength(Integer length) {
this.length = length;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Integer getRequire() {
return require;
}
public void setRequire(Integer require) {
this.require = require;
}
public String getReg() {
return reg;
}
public void setReg(String reg) {
this.reg = reg;
}
public Integer getDecimalDigits() {
return decimalDigits;
}
public void setDecimalDigits(Integer decimalDigits) {
this.decimalDigits = decimalDigits;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
}
package com.nstc.aims.service.remote.n9server;
import com.nstc.aims.constants.SpicRemoteIIConstants;
import com.nstc.aims.model.RemoteParam;
import com.nstc.aims.option.SpicServerRemoteIIEnum;
import com.nstc.aims.util.ResourceLoader;
import com.nstc.util.CastUtil;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.Validate;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>Title: RemoteParamValidator.java</p>
* <p>Description: 接口参数校验器</p>
* <p>Company: 北京九恒星科技股份有限公司</p>
*
* @author luhao
* @since 2020-03-14 11:16
*/
public class RemoteParamValidator extends DefaultHandler {
private HashMap<String, List<RemoteParam>> remoteParamsMap;
private List<RemoteParam> remoteParamList;
private RemoteParam remoteParam;
private final static String RULES = "rules";
private final static String LIST_TAG = "remoteParams";
private final static String PARAM_TAG = "remoteParam";
public final static String RULES_DIR = "AIMS-CFG" + File.separator + "SPIC_REMOTE_RULES" + File.separator;
private static RemoteParamValidator remoteParamValidator = null;
private RemoteParamValidator() {
}
/**
* 构建保存模型
*
* @param map
* @param spicServerRemoteIIEnum
* @return
*/
public Object buildModel(Map<String, Object> map, SpicServerRemoteIIEnum spicServerRemoteIIEnum) {
Validate.notNull(map, "参数列表为空!");
List<RemoteParam> remoteParams = remoteParamsMap.get(spicServerRemoteIIEnum.getCode());
if (remoteParams == null) {
init();
}
Validate.notNull(remoteParams, "初始化校验器失败!接口:" + spicServerRemoteIIEnum);
Object model = null;
try {
model = spicServerRemoteIIEnum.getClazz().newInstance();
for (RemoteParam param : remoteParams) {
//Field field = spicServerRemoteIIEnum.getClazz().getDeclaredField(param.getFieldName());
//field.setAccessible(true);
Object value = null;
if (param.getType().startsWith("D")) {
value = CastUtil.toDate(map.get(param.getName()));
} else if ((param.getType().startsWith("N") && param.getDecimalDigits() == null)) {
value = CastUtil.toInteger(map.get(param.getName()));
} else if (param.getType().startsWith("N") && param.getDecimalDigits() != null) {
value = CastUtil.toDouble(map.get(param.getName()));
} else {
value = CastUtil.toNotEmptyString(map.get(param.getName()));
}
PropertyUtils.setProperty(model,param.getFieldName(),value);
//field.set(model, value);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return model;
}
public static RemoteParamValidator getInstance() {
if (remoteParamValidator == null) {
remoteParamValidator = new RemoteParamValidator();
remoteParamValidator.init();
}
return remoteParamValidator;
}
/**
* 校验Map类型的参数
*
* @param interfaceKey
* @param map
* @param sign
*/
public void validate(String interfaceKey, Map<String, Object> map, String sign) {
Validate.notEmpty(map, "参数列表不可为空!");
List<RemoteParam> rules = rules(interfaceKey);
Validate.notNull(rules, "无法找到接口" + interfaceKey);
if (map.containsKey(SpicRemoteIIConstants.DATA_LIST)) {
List<Map<String, Object>> list = (List) (map.get(SpicRemoteIIConstants.DATA_LIST));
validate(interfaceKey, list);
} else {
for (RemoteParam param : rules) {
param.validate(map.get(param.getName()), sign);
}
}
}
/**
* 校验List类型的参数
*
* @param intefaceKey
* @param list
*/
public void validate(String intefaceKey, List<Map<String, Object>> list) {
Validate.noNullElements(list, "参数列表不可为空!");
for (int i = 0; i < list.size(); i++) {
Map<String, Object> map = list.get(i);
validate(intefaceKey, map, "第" + (i + 1) + "行");
}
}
private List<RemoteParam> rules(String interfaceKey) {
List<RemoteParam> rules = remoteParamsMap.get(interfaceKey);
if (rules == null) {
init();
}
rules = remoteParamsMap.get(interfaceKey);
Validate.notNull(rules, "未定义的接口:" + interfaceKey);
return rules;
}
/**
* 初始化
*/
public void init() {
//1.获取SAXParserFactory实例
SAXParserFactory factory = SAXParserFactory.newInstance();
//2.获取SAXparser实例
SAXParser saxParser = null;
try {
saxParser = factory.newSAXParser();
File dir = new File(ResourceLoader.getResource(RemoteParamValidator.RULES_DIR).getPath());
if (dir != null && dir.isDirectory()) {
File[] files = dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".xml");
}
});
for (File file : files) {
saxParser.parse(file, remoteParamValidator);
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if (RULES.equals(qName)) {
remoteParamsMap = remoteParamsMap == null ? new HashMap<String, List<RemoteParam>>() : remoteParamsMap;
} else if (LIST_TAG.equals(qName)) {
remoteParamList = new ArrayList<RemoteParam>();
remoteParamsMap.put(attributes.getValue(0), remoteParamList);
} else if (PARAM_TAG.equals(qName)) {
remoteParam = new RemoteParam(attributes);
remoteParamList.add(remoteParam);
}
}
public HashMap<String, List<RemoteParam>> getRemoteParamsMap() {
return remoteParamsMap;
}
}
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE rules SYSTEM "rules.dtd">
<rules>
<remoteParams name="SPICII-1-1">
<remoteParam name="ACCOUNTNO" remark="账号" type="C32" require="1" reg="" fieldName="accountNo"/>
<remoteParam name="APPLYID" remark="账户申请流水号" type="N38" require="" reg="" fieldName="applyId"/>
<remoteParam name="CLTNO" remark="单位编号" type="C32" require="1" reg="" fieldName="cltNo"/>
<remoteParam name="CLT_NAME" remark="单位名称" type="C64" require="1" reg="" fieldName="cltName" />
<remoteParam name="ASSBANKNAME" remark="合作金融网点名称" type="C128" require="1" reg="" fieldName="assBankName" />
<remoteParam name="ISABROAD" remark="境内外" type="C1" require="" reg="0|1" fieldName="isAbroad" />
<remoteParam name="AREAID" remark="区域编码" type="N38" require="" reg="" fieldName="areaId" />
<remoteParam name="OPENACCOUNTDATE" remark="开户日期" type="D" require="1" reg="" fieldName="openAccountDate" />
<remoteParam name="ACCOUNTNAME" remark="户名" type="C128" require="1" reg="" fieldName="accountName" />
<remoteParam name="MEMORYNAME" remark="助记名" type="C128" require="" reg="" fieldName="memoryName" />
<remoteParam name="CURRENCYNO" remark="币种" type="C3" require="1" reg="" fieldName="currencyNo" />
<remoteParam name="CTNAME" remark="账户性质" type="C32" require="1" reg="" fieldName="type" />
<remoteParam name="NATURENAME" remark="账户用途" type="C32" require="1" reg="" fieldName="natureName" />
<remoteParam name="FOREIGNTYPE" remark="外汇业务类型" type="N1" require="" reg="1|2" fieldName="foreignType" />
<remoteParam name="ASSOCIATEFLAG" remark="联网方式" type="C1" require="1" reg="0|1|2" fieldName="associateFlag" />
<remoteParam name="ARRDESS" remark="单位/项目地址" type="C256" require="1" reg="" fieldName="arrdess" />
<remoteParam name="CNREMARK" remark="备注" type="C500" require="" reg="" fieldName="cnreMark" />
<remoteParam name="ACNTSTATE" remark="账户状态" type="N2" require="1" reg="0|1|-1|-2" fieldName="acntState" />
<remoteParam name="EACCOUNT" remark="实体账户账号" type="C32" require="" reg="" fieldName="eAccount" />
<remoteParam name="PUBLIC_TELEPHONE" remark="对公电话" type="C20" require="" reg="" fieldName="publicTelephone" />
<remoteParam name="CUSTOMER_MANAGER" remark="客户经理" type="C60" require="" reg="" fieldName="customerManager" />
<remoteParam name="CM_TELEPHONE" remark="客户经理电话" type="C20" require="" reg="" fieldName="cmTelephone" />
<remoteParam name="CM_MAIL" remark="客户经理邮箱" type="C60" require="" reg="" fieldName="cmMail" />
<remoteParam name="IS_DEDUCT" remark="是否扣减账户:0不是;1是" type="N1" require="" reg="0|1" fieldName="isDeduct" />
<remoteParam name="IS_ESCROWACCOUNT" remark="是否监管账户(0-否 1-是)" type="N1" require="" reg="0|1" fieldName="isEscrowAccount" />
<remoteParam name="NEED_ONLINE" remark="是否申请上线" type="N1" require="" reg="0|1" fieldName="needOnline" />
<remoteParam name="CONTACT_PERSON" remark="联系人" type="C32" require="1" reg="" fieldName="contactPerson" />
<remoteParam name="CONTACT_TEL" remark="联系人电话" type="C32" require="1" reg="" fieldName="contactTel" />
<remoteParam name="BASIC_ACCOUNT_NO" remark="基本户账户" type="C32" require="" reg="" fieldName="basicAccountNo" />
<remoteParam name="BASIC_ACCOUNT_BANKNAME" remark="基本户开户行" type="C64" require="" reg="" fieldName="basicAccountBankname" />
<remoteParam name="AUTHORIZED_PERSON_NAME" remark="被授权人姓名" type="C32" require="1" reg="" fieldName="authorizedPersonName" />
<remoteParam name="AUTHORIZED_PERSON_ID" remark="被授权人身份证号" type="C32" require="1" reg="" fieldName="authorizedPersonId" />
<remoteParam name="LEGAL_PERSON" remark="法人姓名" type="C32" require="" reg="" fieldName="legalPerson" />
<remoteParam name="LEGAL_ID_CARD" remark="法人身份证号" type="C32" require="" reg="" fieldName="legalIdCard" />
<remoteParam name="NAMES_SEAL" remark="印鉴人名章名称" type="C100" require="" reg="" fieldName="namesSeal" />
<remoteParam name="FINANCIAL_SEAL" remark="印鉴财务章名称" type="C128" require="" reg="" fieldName="financialSeal" />
<remoteParam name="OFFICIAL_SEAL" remark="公章名称" type="C128" require="" reg="" fieldName="officialSeal" />
<remoteParam name="ADMIN_AREA" remark="行政区划" type="C32" require="" reg="" fieldName="adminArea" />
<remoteParam name="ACTUAL_OFFICE_ADDRESS" remark="实际办公地址" type="C100" require="1" reg="" fieldName="actualOfficeAddress" />
<remoteParam name="IS_SEAL_LEGAL_PERSON" remark="预留印鉴是否为法人" type="N1" require="1" reg="0|1" fieldName="isSealLegalPerson" />
<remoteParam name="BELONG_FTA" remark="是否属于自贸区" type="N1" require="1" reg="0|1" fieldName="belongFta" />
<remoteParam name="IS_OPEN_REMIND" remark="是否开通提醒" type="N1" require="1" reg="0|1" fieldName="isOpenRemind" />
<remoteParam name="SMS_REMIND" remark="是否短信提醒" type="N1" require="1" reg="0|1" fieldName="smsRemind" />
<remoteParam name="TEL_REMIND" remark="是否电话提醒" type="N1" require="1" reg="0|1" fieldName="telRemind" />
<remoteParam name="LARGE_AMOUNT_REMIND" remark="是否大额提醒" type="N1" require="" reg="0|1" fieldName="largeAmountRemind" />
<remoteParam name="DUE_DATE" remark="账户到期日" type="D" require="" reg="" fieldName="dueDate" />
</remoteParams>
<remoteParams name="SPICII-1-2">
<remoteParam name="ACCOUNTNO" remark="账号" type="C32" require="1" reg="" fieldName="accountNo" />
<remoteParam name="CHANGE_REASON" remark="变更原因" type="C128" require="1" reg="" fieldName="changeReason" />
<remoteParam name="CHANGE_DATE" remark="变更日期" type="D" require="1" reg="" fieldName="changeDate" />
<remoteParam name="CHANGE_APPLY_ID" remark="变更申请ID" type="N38" require="1" reg="" fieldName="changeApplyId" />
<remoteParam name="CLTNO" remark="单位编号" type="C32" require="" reg="" fieldName="cltNo" />
<remoteParam name="CLT_NAME" remark="单位名称" type="C64" require="" reg="" fieldName="cltName" />
<remoteParam name="ASSBANKNAME" remark="合作金融网点名称" type="C128" require="" reg="" fieldName="assBankName" />
<remoteParam name="ISABROAD" remark="境内外" type="C1" require="" reg="0|1" fieldName="isAbroad" />
<remoteParam name="AREAID" remark="区域编码" type="N38" require="" reg="" fieldName="areaId" />
<remoteParam name="OPENACCOUNTDATE" remark="开户日期" type="D" require="" reg="" fieldName="openAccountDate" />
<remoteParam name="ACCOUNTNAME" remark="户名" type="C128" require="" reg="" fieldName="accountName" />
<remoteParam name="MEMORYNAME" remark="助记名" type="C128" require="" reg="" fieldName="memoryName" />
<remoteParam name="CURRENCYNO" remark="币种" type="C3" require="" reg="" fieldName="currencyNo" />
<remoteParam name="CTNAME" remark="账户性质" type="C32" require="" reg="" fieldName="type" />
<remoteParam name="NATURENAME" remark="账户用途" type="C32" require="" reg="" fieldName="natureName" />
<remoteParam name="FOREIGNTYPE" remark="外汇业务类型" type="N38" require="" reg="1|2" fieldName="foreignType" />
<remoteParam name="ASSOCIATEFLAG" remark="联网方式" type="C1" require="" reg="0|1|2" fieldName="associateFlag" />
<remoteParam name="ARRDESS" remark="单位/项目地址" type="C256" require="" reg="" fieldName="arrdess" />
<remoteParam name="CNREMARK" remark="备注" type="C500" require="" reg="" fieldName="cnreMark" />
<remoteParam name="ACNTSTATE" remark="账户状态" type="N38" require="" reg="0|1|-1|-2" fieldName="acntState" />
<remoteParam name="EACCOUNT" remark="实体账户账号" type="C32" require="" reg="" fieldName="eAccount" />
<remoteParam name="PUBLIC_TELEPHONE" remark="对公电话" type="C20" require="" reg="" fieldName="publicTelephone" />
<remoteParam name="CUSTOMER_MANAGER" remark="客户经理" type="C60" require="" reg="" fieldName="customerManager" />
<remoteParam name="CM_TELEPHONE" remark="客户经理电话" type="C20" require="" reg="" fieldName="cmTelephone" />
<remoteParam name="CM_MAIL" remark="客户经理邮箱" type="C60" require="" reg="" fieldName="cmMail" />
<remoteParam name="IS_DEDUCT" remark="是否扣减账户:0不是;1是" type="N38" require="" reg="0|1" fieldName="isDeduct" />
<remoteParam name="IS_ESCROWACCOUNT" remark="是否监管账户(0-否 1-是)" type="N38" require="" reg="0|1" fieldName="isEscrowAccount" />
<remoteParam name="NEED_ONLINE" remark="是否申请上线" type="N38" require="" reg="0|1" fieldName="needOnline" />
<remoteParam name="CONTACT_PERSON" remark="联系人" type="C32" require="" reg="" fieldName="contactPerson" />
<remoteParam name="CONTACT_TEL" remark="联系人电话" type="C32" require="" reg="" fieldName="contactTel" />
<remoteParam name="BASIC_ACCOUNT_NO" remark="基本户账户" type="C32" require="" reg="" fieldName="basicAccountNo" />
<remoteParam name="BASIC_ACCOUNT_BANKNAME" remark="基本户开户行" type="C64" require="" reg="" fieldName="basicAccountBankname" />
<remoteParam name="AUTHORIZED_PERSON_NAME" remark="被授权人姓名" type="C32" require="" reg="" fieldName="authorizedPersonName" />
<remoteParam name="AUTHORIZED_PERSON_ID" remark="被授权人身份证号" type="C32" require="" reg="" fieldName="authorizedPersonId" />
<remoteParam name="LEGAL_PERSON" remark="法人姓名" type="C32" require="" reg="" fieldName="legalPerson" />
<remoteParam name="LEGAL_ID_CARD" remark="法人身份证号" type="C32" require="" reg="" fieldName="legalIdCard" />
<remoteParam name="NAMES_SEAL" remark="印鉴人名章名称" type="C100" require="" reg="" fieldName="namesSeal" />
<remoteParam name="FINANCIAL_SEAL" remark="印鉴财务章名称" type="C128" require="" reg="" fieldName="financialSeal" />
<remoteParam name="OFFICIAL_SEAL" remark="公章名称" type="C128" require="" reg="" fieldName="officialSeal" />
<remoteParam name="ADMIN_AREA" remark="行政区划" type="C32" require="" reg="" fieldName="adminArea" />
<remoteParam name="ACTUAL_OFFICE_ADDRESS" remark="实际办公地址" type="C100" require="" reg="" fieldName="actualOfficeAddress" />
<remoteParam name="IS_SEAL_LEGAL_PERSON" remark="预留印鉴是否为法人" type="N38" require="" reg="0|1" fieldName="isSealLegalPerson" />
<remoteParam name="BELONG_FTA" remark="是否属于自贸区" type="N38" require="" reg="0|1" fieldName="belongFta" />
<remoteParam name="IS_OPEN_REMIND" remark="是否开通提醒" type="N38" require="" reg="0|1" fieldName="isOpenRemind" />
<remoteParam name="SMS_REMIND" remark="是否短信提醒" type="N38" require="" reg="0|1" fieldName="smsRemind" />
<remoteParam name="TEL_REMIND" remark="是否电话提醒" type="N38" require="" reg="0|1" fieldName="telRemind" />
<remoteParam name="LARGE_AMOUNT_REMIND" remark="是否大额提醒" type="N38" require="" reg="0|1" fieldName="largeAmountRemind" />
<remoteParam name="DUE_DATE" remark="账户到期日" type="D" require="" reg="" fieldName="dueDate" />
</remoteParams>
<remoteParams name="SPICII-1-3">
<remoteParam name="ACCOUNTNO" remark="账号" type="C32" require="1" reg="" fieldName="accountNo" />
<remoteParam name="APPLYID" remark="销户申请流水号" type="N38" require="1" reg="" fieldName="applyId" />
<remoteParam name="CANCELDATE" remark="销户日期" type="D" require="1" reg="" fieldName="cancelDate" />
<remoteParam name="CANCELREMARK" remark="销户备注" type="C500" require="" reg="" fieldName="cancelRemark" />
<remoteParam name="CANCELREASON" remark="销户原因" type="C500" require="" reg="" fieldName="cancelReason" />
</remoteParams>
<remoteParams name="SPICII-1-4">
<remoteParam name="ACCOUNTNO" remark="账号" type="C32" require="1" reg="" fieldName="accountNo" />
<remoteParam name="CLTNO" remark="单位编号" type="C32" require="" reg="" fieldName="cltNo" />
<remoteParam name="CLT_NAME" remark="单位名称" type="C64" require="" reg="" fieldName="cltName" />
<remoteParam name="ASSBANKNAME" remark="合作金融网点名称" type="C128" require="" reg="" fieldName="assBankName" />
<remoteParam name="ISABROAD" remark="境内外" type="C1" require="" reg="0|1" fieldName="isAbroad" />
<remoteParam name="AREAID" remark="区域编码" type="N38" require="" reg="" fieldName="areaId" />
<remoteParam name="OPENACCOUNTDATE" remark="开户日期" type="D" require="" reg="" fieldName="openAccountDate" />
<remoteParam name="ACCOUNTNAME" remark="户名" type="C128" require="" reg="" fieldName="accountName" />
<remoteParam name="MEMORYNAME" remark="助记名" type="C128" require="" reg="" fieldName="memoryName" />
<remoteParam name="CURRENCYNO" remark="币种" type="C3" require="" reg="" fieldName="currencyNo" />
<remoteParam name="CTNAME" remark="账户性质" type="C32" require="" reg="" fieldName="type" />
<remoteParam name="NATURENAME" remark="账户用途" type="C32" require="" reg="" fieldName="natureName" />
<remoteParam name="FOREIGNTYPE" remark="外汇业务类型" type="N38" require="" reg="1|2" fieldName="foreignType" />
<remoteParam name="ASSOCIATEFLAG" remark="联网方式" type="C1" require="" reg="0|1|2" fieldName="associateFlag" />
<remoteParam name="ARRDESS" remark="单位/项目地址" type="C256" require="" reg="" fieldName="arrdess" />
<remoteParam name="CNREMARK" remark="备注" type="C500" require="" reg="" fieldName="cnreMark" />
<remoteParam name="ACNTSTATE" remark="账户状态" type="N38" require="" reg="0|1|-1|-2" fieldName="acntState" />
<remoteParam name="EACCOUNT" remark="实体账户账号" type="C32" require="" reg="" fieldName="eAccount" />
<remoteParam name="PUBLIC_TELEPHONE" remark="对公电话" type="C20" require="" reg="" fieldName="publicTelephone" />
<remoteParam name="CUSTOMER_MANAGER" remark="客户经理" type="C60" require="" reg="" fieldName="customerManager" />
<remoteParam name="CM_TELEPHONE" remark="客户经理电话" type="C20" require="" reg="" fieldName="cmTelephone" />
<remoteParam name="CM_MAIL" remark="客户经理邮箱" type="C60" require="" reg="" fieldName="cmMail" />
<remoteParam name="IS_DEDUCT" remark="是否扣减账户:0不是;1是" type="N38" require="" reg="0|1" fieldName="isDeduct" />
<remoteParam name="IS_ESCROWACCOUNT" remark="是否监管账户(0-否 1-是)" type="N38" require="" reg="0|1" fieldName="isEscrowAccount" />
<remoteParam name="NEED_ONLINE" remark="是否申请上线" type="N38" require="" reg="0|1" fieldName="needOnline" />
<remoteParam name="CONTACT_PERSON" remark="联系人" type="C32" require="" reg="" fieldName="contactPerson" />
<remoteParam name="CONTACT_TEL" remark="联系人电话" type="C32" require="" reg="" fieldName="contactTel" />
<remoteParam name="BASIC_ACCOUNT_NO" remark="基本户账户" type="C32" require="" reg="" fieldName="basicAccountNo" />
<remoteParam name="BASIC_ACCOUNT_BANKNAME" remark="基本户开户行" type="C64" require="" reg="" fieldName="basicAccountBankname" />
<remoteParam name="AUTHORIZED_PERSON_NAME" remark="被授权人姓名" type="C32" require="" reg="" fieldName="authorizedPersonName" />
<remoteParam name="AUTHORIZED_PERSON_ID" remark="被授权人身份证号" type="C32" require="" reg="" fieldName="authorizedPersonId" />
<remoteParam name="LEGAL_PERSON" remark="法人姓名" type="C32" require="" reg="" fieldName="legalPerson" />
<remoteParam name="LEGAL_ID_CARD" remark="法人身份证号" type="C32" require="" reg="" fieldName="legalIdCard" />
<remoteParam name="NAMES_SEAL" remark="印鉴人名章名称" type="C100" require="" reg="" fieldName="namesSeal" />
<remoteParam name="FINANCIAL_SEAL" remark="印鉴财务章名称" type="C128" require="" reg="" fieldName="financialSeal" />
<remoteParam name="OFFICIAL_SEAL" remark="公章名称" type="C128" require="" reg="" fieldName="officialSeal" />
<remoteParam name="ADMIN_AREA" remark="行政区划" type="C32" require="" reg="" fieldName="adminArea" />
<remoteParam name="ACTUAL_OFFICE_ADDRESS" remark="实际办公地址" type="C100" require="" reg="" fieldName="actualOfficeAddress" />
<remoteParam name="IS_SEAL_LEGAL_PERSON" remark="预留印鉴是否为法人" type="N38" require="" reg="0|1" fieldName="isSealLegalPerson" />
<remoteParam name="BELONG_FTA" remark="是否属于自贸区" type="N38" require="" reg="0|1" fieldName="belongFta" />
<remoteParam name="IS_OPEN_REMIND" remark="是否开通提醒" type="N38" require="" reg="0|1" fieldName="isOpenRemind" />
<remoteParam name="SMS_REMIND" remark="是否短信提醒" type="N38" require="" reg="0|1" fieldName="smsRemind" />
<remoteParam name="TEL_REMIND" remark="是否电话提醒" type="N38" require="" reg="0|1" fieldName="telRemind" />
<remoteParam name="LARGE_AMOUNT_REMIND" remark="是否大额提醒" type="N38" require="" reg="0|1" fieldName="largeAmountRemind" />
<remoteParam name="DUE_DATE" remark="账户到期日" type="D" require="" reg="" fieldName="dueDate" />
</remoteParams>
</rules>
<?xml version="1.0" encoding="utf-8" ?>
<!ELEMENT rules (remoteParams+)>
<!ELEMENT remoteParams (remoteParam+)>
<!ELEMENT remoteParam EMPTY>
<!ATTLIST remoteParams
name ID #REQUIRED
>
<!ATTLIST remoteParam
name CDATA #REQUIRED
remark CDATA #REQUIRED
type CDATA #REQUIRED
require CDATA #REQUIRED
reg CDATA #IMPLIED
fieldName CDATA #IMPLIED
>
package com.nstc.aims.service.remote.n9server;
import com.nstc.aims.constants.SpicCommonConstants;
import com.nstc.aims.constants.SpicRemoteIIConstants;
import com.nstc.aims.controller.builder.RemoteLogBuilder;
import com.nstc.aims.model.RemoteLog;
import com.nstc.aims.option.SpicServerRemoteIIEnum;
import com.nstc.aims.service.ServerLocator;
import com.nstc.aims.service.remote.server.AbstractExternalBaseServiceImpl;
import com.nstc.framework.core.Profile;
import com.nstc.framework.web.util.FrameworkUtil;
import com.nstc.smartform.pub.business.BaseBusiness;
import com.nstc.util.CastUtil;
import com.nstc.util.StringUtils;
import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
/**
* <p>Title: AbstractN9ServerBusiness.java</p>
* <p>Description: G6集团账户服务端接口 抽象类</p>
* <p>Company: 北京九恒星科技股份有限公司</p>
*
* @author luhao
* @since 2020-03-12 15:06
*/
public abstract class AbstractN9ServerBusiness extends BaseBusiness {
public static boolean DEBUG_MOD = true;
/**
* 入参
*/
private Map<String, Object> attituteMap;
private Profile profile;
private String successMsg = "调用成功!";
private RemoteLog remoteLog;
private static final Logger logger = LoggerFactory.getLogger(AbstractExternalBaseServiceImpl.class);
/**
* 接口类型
*/
protected SpicServerRemoteIIEnum spicServerRemoteIIEnum;
/**
* 获取服务类门面
*
* @return
*/
public ServerLocator getServiceLocator() {
return (ServerLocator) FrameworkUtil.getServiceLocator(SpicCommonConstants.AIMS);
}
/**
* 远程接口服务基础实现类,在此完成以下功能
* 1 解析参数
* 2 统一获取异常,返回结果
* 3 组装返回结果样式
*
* @return
*/
public void execute() {
//SPIC-INTERFACE-ENTRY
logger.info("====== aims remote spic interface entry======");
result = new HashMap();
try {
// 校验公共参数
validateCommonParam();
// 初始化接口信息
init();
// 调用前参数合法性校验
validateParam();
//调用前业务校验
validateAndBuildBuss();
// 各个接口实现类实现此接口进行业务处理
doExecute();
result.put(SpicCommonConstants.RET_CODE, SpicCommonConstants.SUCCESS);
result.put(SpicCommonConstants.RET_MSG, successMsg);
} catch (IllegalArgumentException ae) {
result.put(SpicCommonConstants.RET_CODE, SpicCommonConstants.FAILED);
result.put(SpicCommonConstants.RET_MSG, ae.getMessage());
} catch (RuntimeException e) {
e.printStackTrace();
String msg = e.getMessage();
if (StringUtils.isBlank(msg)) {
String erroinfo = e.getStackTrace() == null ? "" : ":" + e.getStackTrace()[0];
msg = e.getClass().getSimpleName() + erroinfo;
}
result.put(SpicCommonConstants.RET_CODE, SpicCommonConstants.FAILED);
result.put(SpicCommonConstants.RET_MSG, msg);
} finally {
unbindResource();
}
// 日志参数组装
remoteLog = RemoteLogBuilder.buildLog(getAttituteMap(),
result.get(SpicCommonConstants.RET_CODE), result.get(SpicCommonConstants.RET_MSG));
getServiceLocator().getRemoteService().saveRemoteLog(remoteLog);
setResult(result);
logger.info("======aims remote spic interface result:" + result + "======");
logger.info("======aims remote spic interface end======");
}
protected abstract void validateAndBuildBuss();
/**
* 公共参数校验
*/
private void validateCommonParam() {
Map map = bizEvent.getAttributes();
Validate.notEmpty(map, "参数列表不能为空!");
Validate.notNull(map.get(SpicRemoteIIConstants.CLIENT_SOURCE), SpicRemoteIIConstants.CLIENT_MESSAGE + SpicRemoteIIConstants.NULL_ERRO_MESSAGE);
Validate.notNull(map.get(SpicRemoteIIConstants.CLIENT_MESSAGE), SpicRemoteIIConstants.CLIENT_MESSAGE + SpicRemoteIIConstants.NULL_ERRO_MESSAGE);
Validate.notNull(map.get(SpicRemoteIIConstants.CLIENT_INPUTOR), SpicRemoteIIConstants.CLIENT_MESSAGE + SpicRemoteIIConstants.NULL_ERRO_MESSAGE);
Validate.notNull(map.get(SpicRemoteIIConstants.CLIENT_CLTNO), SpicRemoteIIConstants.CLIENT_CLTNO + SpicRemoteIIConstants.NULL_ERRO_MESSAGE);
Validate.notNull(map.get(SpicRemoteIIConstants.SYNC_TYPE), SpicRemoteIIConstants.CLIENT_MESSAGE + SpicRemoteIIConstants.NULL_ERRO_MESSAGE);
Validate.notNull(map.get(SpicRemoteIIConstants.DATA_LIST), SpicRemoteIIConstants.CLIENT_MESSAGE + SpicRemoteIIConstants.NULL_ERRO_MESSAGE);
}
/**
* 执行业务动作
*/
protected abstract void doExecute();
/**
* 参数合法性校验
*/
private void validateParam() {
RemoteParamValidator remoteParamValidator = RemoteParamValidator.getInstance();
if (DEBUG_MOD) {
long t1 = System.currentTimeMillis();
remoteParamValidator.init();
long t2 = System.currentTimeMillis();
logger.info("调试阶段接口参数校验器初始化耗时:" + (t2 - t1));
}
remoteParamValidator.validate(spicServerRemoteIIEnum.getCode(), getAttituteMap(), "");
}
/**
* 初始化
*/
public void init() {
initProfile();
bindResource();
setSpicServerRemoteIIEnum();
logger.info("====== aims remote spic interface init complet ======");
}
/**
* 设置接口类型
*/
protected void setSpicServerRemoteIIEnum() {
String code = CastUtil.toNotEmptyString(getAttituteMap().get(SpicRemoteIIConstants.SYNC_TYPE));
spicServerRemoteIIEnum = SpicServerRemoteIIEnum.getSpicRemoteEnum(code);
Validate.notNull(spicServerRemoteIIEnum, "无法获得" + SpicRemoteIIConstants.SYNC_TYPE);
}
/**
* 初始化Profile
*/
public void initProfile() {
profile = null;
if (getCaller() == null || getCaller().getProfile() == null) {
profile = new Profile();
} else {
profile = getCaller().getProfile();
}
//此处可以获得N9的用户和单位
profile.setUserNo(CastUtil.toNotNullString(getAttituteMap().get(SpicRemoteIIConstants.CLIENT_INPUTOR)));
String cltNo = CastUtil.toNotNullString(getAttituteMap().get(SpicRemoteIIConstants.CLIENT_CLTNO));
profile.setCustNo(cltNo);
// profile.setUserNo("机制");
// profile.setCustName("机制");
}
/**
* 绑定线程变量
*/
public void bindResource() {
com.nstc.framework.util.ThreadResources.bindResource(profile.getClass().getName(), profile);
com.nstc.framework.util.ThreadResources.bindResource("CurThreadAppNo", SpicCommonConstants.AIMS);
com.nstc.waf.util.ThreadResources.bindResource(profile.getClass().getName(), profile);
com.nstc.waf.util.ThreadResources.bindResource("CurThreadAppNo", SpicCommonConstants.AIMS);
}
/**
* 解绑线程变量
*/
private void unbindResource() {
if (profile != null) {
com.nstc.framework.util.ThreadResources.unbindResource(profile.getClass().getName());
com.nstc.framework.util.ThreadResources.unbindResource("CurThreadAppNo");
com.nstc.waf.util.ThreadResources.unbindResource(profile.getClass().getName());
com.nstc.waf.util.ThreadResources.unbindResource("CurThreadAppNo");
}
}
public Profile getProfile() {
return profile;
}
public Map<String, Object> getAttituteMap() {
if (attituteMap == null) {
attituteMap = bizEvent.getAttributes();
}
return attituteMap;
}
public void onSuccess() {
}
public void onFailure() {
onSuccess();
}
public String getSuccessMsg() {
return successMsg;
}
public void setSuccessMsg(String successMsg) {
this.successMsg = successMsg;
}
}
一个基于js的dtd约束文件的检查工具
<html>
<head>
<script language="javascript">
for (var i = 1; i <= 9; i++) {
checkXml("SPICII-" + i + ".xml");
}
function checkXml(path) {
// 创建xml文档解析器对象
var xmldoc = new ActiveXObject("Microsoft.XMLDOM");
// 开启xml校验
xmldoc.validateOnParse = "true";
// 装载xml文档,即指定校验哪个XML文件
xmldoc.load(path);
document.writeln(path + ":" + "<br>");
document.writeln("\t错误信息:" + xmldoc.parseError.reason + "<br>");
document.writeln("\t错误行号:" + xmldoc.parseError.line + "<br>");
document.writeln("<br />")
}
</script>
</head>
<body>
</body>
</html>