这篇文章说明的改动点:
引入包:lombok, fastjson, commons-lang3 |
AbcInterfaceType: 新增枚举-农行接口类型 |
XmlUtil: 优化代码,增加对IO流的关闭 |
SocketClient: 重命名为SocketClientUtil,优化代码,返回值由Map改成SocketResponseDTO,去掉有关农行的代码,明确此工具类职责,加强可复用性 |
AbcConfig: 农行配置类,把所有农行配置信息注入该类 |
引入包:lombok, fastjson, commons-lang3
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<properties>
<commons-lang3.version>3.12.0</commons-lang3.version>
<fastjson.version>1.2.83</fastjson.version>
<lombok.version>1.18.24</lombok.version>
</properties>
XmlUtil: 优化代码,增加对IO流的关闭
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.*;
public class XmlUtil {
/**
* 将String类型的xml转换成对象
*/
public static Object convertXmlStrToObject(Class clazz, String xmlValue) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(clazz);
// 进行将Xml转成对象的核心接口
Unmarshaller unmarshal = context.createUnmarshaller();
try(
StringReader stringReader = new StringReader(xmlValue);
BufferedReader bufferedReader = new BufferedReader(stringReader);
) {
Object xmlObject = unmarshal.unmarshal(bufferedReader);
return xmlObject;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* Object 转 xml字符串
* @param obj 待转换对象
* @return String
* @throws JAXBException
*/
public static String objectToXml(Object obj) throws JAXBException {
Marshaller marshaller = objectToMarshaller(obj);
return objectToXml(obj, marshaller);
}
/**
* Object 转 xml字符串
* @param obj 待转换对象
* @param marshaller
* @return String
* @throws JAXBException
*/
private static String objectToXml(Object obj, Marshaller marshaller) throws JAXBException {
try (
StringWriter writer = new StringWriter();
BufferedWriter bufferedwriter = new BufferedWriter(writer);
){
marshaller.marshal(obj, bufferedwriter);
return writer.toString();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* Object 转 xml字符串
* @param obj 待转换对象
* @param isFormat 是否需要格式化xml内容
* @param isDelHead 是否删除头部的 < ?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
* @return String
* @throws JAXBException
*/
public static String objectToXml(Object obj, boolean isFormat, boolean isDelHead) throws JAXBException {
Marshaller marshaller = objectToMarshaller(obj);
if (isFormat) {
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
}
String xmlResult = objectToXml(obj, marshaller);
if (isDelHead) {
return xmlResult.replaceAll("\\<\\?xml.*\\?>", "");
}
return xmlResult;
}
private static Marshaller objectToMarshaller(Object obj) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(obj.getClass());
return context.createMarshaller();
}
}
AbcConfig: 农行配置类,把所有农行配置信息注入该类
之前我是在application.yml配置文件配置后,AbcErpToIctSocket工具类用@value引入,但是配置有点多,一个个引入,有点乱也不方便管理和使用,这次改成把配置都注入一个配置类里面,以后使用注入这个配置类就行。
application.yml
abc:
ict:
host: ICT连接地址
port: ICT端口
contract-no: 你的94合约号
nv-oucher-type: 你的94合约号类型
file-upload-path: D:/ABC-ICT/data(上传的文件存放地址,一定是放在ICT目录里面的data文件夹里)
file-download-path: D:/ABC-ICT/detail(接口应答返回的文件存放地址,一定是放在ICT目录里面的detail文件夹里)
message-charset: GBK(报文编码)
file-charset: GBK(请求或相应文件编码)
AbcConfig
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "abc.ict")
@Data
public class AbcConfig {
// IP
private String host;
// 端口
private int port;
// 94合约号
private String nvContractNo;
// 94账号业务种类代码
private String nvOucherType;
// 上传农行银企通平台报文文件存放目录
private String fileUploadPath;
// 下载农行银企通平台报文文件存放目录
private String fileDownloadPath;
// 报文编码
private String messageCharset;
// 文件编码
private String fileCharset;
}
SocketClient: 重命名为SocketClientUtil,优化代码,返回值由Map改成SocketResponseDTO,去掉有关农行的代码,明确此工具类职责,加强可复用性
这个看我另一篇文章就可以了,代码都一样
java socket客户端请求并获取响应数据http://t.csdnimg.cn/9Hkt8
AbcInterfaceType: 新增枚举-农行接口类型
此枚举相当于一个字典一样,统筹农行接口请求对象class、响应对象class、请求文件对象class、响应文件对象class、请求文件的字段间隔符、响应文件的字段间隔符。
typeOf方法,作用是用请求对象动态获取具体枚举类型。
import com.example.demo.dto.request.*;
import com.example.demo.dto.response.*;
import org.apache.commons.lang3.StringUtils;
/**
* 农行企业银行-接口类型
* */
public enum AbcInterfaceType {
// 查询单账户余额
CQRA06(CQRA06ReqDTO.class, CQRA06RespDTO.class, null, null, null, null),
// 查询账户明细(新全量)
CQRC09(CQRC09ReqDTO.class, CQRC09RespDTO.class, null, CQRC09RespDTO.FileObject.class, null, "\\|"),
// 汇兑-单笔对公|对私
CFRT02(CFRT02ReqDTO.class, CFRT02RespDTO.class, null, null, null, null),
// 查询金融交易处理状态
CQRT71(CQRT71ReqDTO.class, CQRT71RespDTO.class, null, null, null, null),
// 本行汇总批量代发(实时)
IBAF04(IBAF04ReqDTO.class, IBAF04RespDTO.class, IBAF04ReqDTO.FileObject.class, null, "|_|", null),
// 他行汇总批量代发
IBBF23(IBBF23ReqDTO.class, IBBF23RespDTO.class, IBBF23ReqDTO.FileObject.class, null, "|_|", null),
// 批平台处理结果查询
IBAQ06(IBAQ06ReqDTO.class, IBAQ06RespDTO.class, null, null, null, "\\|\\_\\|");
// 请求对象class
private Class<? extends AbstractRequest> requestClass;
// 应答对象class
private Class<? extends AbstractResponse> responseClass;
// 请求对象文件对象class
private Class<? extends RequestBaseFile> requestFileClass;
// 应答对象文件对象class
private Class<? extends ResponseBaseFile> responseFileClass;
// 请求文件内容字段间隔符
private String requestFileDelimiter;
// 响应文件内容字段间隔符
private String responseFileDelimiter;
<T extends AbstractRequest, R extends AbstractResponse, QF extends RequestBaseFile,
RF extends ResponseBaseFile> AbcInterfaceType(Class<T> requestClass,
Class<R> responseClass, Class<QF> requestFileClass, Class<RF> responseFileClass,
String requestFileDelimiter, String responseFileDelimiter) {
this.requestClass = requestClass;
this.responseClass = responseClass;
this.requestFileClass = requestFileClass;
this.responseFileClass = responseFileClass;
this.requestFileDelimiter = requestFileDelimiter;
this.responseFileDelimiter = responseFileDelimiter;
}
public static AbcInterfaceType typeOf(RequestBaseEntity requestBaseEntity) {
for (AbcInterfaceType cctransCode : AbcInterfaceType.values()) {
if (cctransCode.requestClass.isInstance(requestBaseEntity)) {
return cctransCode;
}
}
String errorMsg = new StringBuffer("不存在对应的交易类型, class:").append(requestBaseEntity.getClass()).toString();
throw new RuntimeException(errorMsg);
}
/**
* 获取应答报文对象的文件对象class
* */
public Class<? extends ResponseBaseFile> getResponseFileClass(String transType) {
if (!this.equals(AbcInterfaceType.IBAQ06)) {
return responseFileClass;
}
// IBAQ06得特殊处理,因为查询IBAF04和IBBF23的结果时,根据前面交易类型的不同,返回的文件格式也不一样
if (StringUtils.equals(transType, AbcInterfaceType.IBAF04.name())) {
return IBAQ06RespDTO.IBAF04FileObject.class;
} else if (StringUtils.equals(transType, AbcInterfaceType.IBBF23.name())) {
return IBAQ06RespDTO.IBBF23FileObject.class;
}
return null;
}
public Class<? extends AbstractRequest> getRequestClass() {
return requestClass;
}
public Class<? extends AbstractResponse> getResponseClass() {
return responseClass;
}
public Class<? extends RequestBaseFile> getRequestFileClass() {
return requestFileClass;
}
public String getRequestFileDelimiter() {
return requestFileDelimiter;
}
public String getResponseFileDelimiter() {
return responseFileDelimiter;
}
}
码字不易,于你有利,勿忘点赞