作者 朱兆平

增加金二验放规则及金二放行指令

package com.sy.controller;
import com.sy.handle.G2FeedBackHandel;
import com.sy.response.ResultJson;
import com.sy.service.X82Service;
import com.sy.service.router.MessageRouterG2;
import com.sy.utils.G2ThreadPoolFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.concurrent.ThreadPoolExecutor;
@RestController
@RequestMapping("/g2")
@Slf4j
public class G2ResponseController {
@Autowired
X82Service x82Service;
@Autowired
MessageRouterG2 messageRouterG2;
@PostMapping("/response")
public ResultJson response(@RequestParam("response") String response){
try {
//初始化线程池
ThreadPoolExecutor threadPool = G2ThreadPoolFactory.instance("G2FeedBack");
log.info("接收到金二验放回执报文,{},开始解密", response);
G2FeedBackHandel g2FeedBackHandel = new G2FeedBackHandel();
g2FeedBackHandel.setFeedBack(response);
g2FeedBackHandel.setX82Service(x82Service);
g2FeedBackHandel.setMessageRouterG2(messageRouterG2);
threadPool.execute(g2FeedBackHandel);
}catch (Exception e){
return new ResultJson("200","接收回执成功",e.getMessage());
}
return new ResultJson("200","接收回执成功");
}
}
... ...
... ... @@ -17,7 +17,7 @@ import org.springframework.context.ApplicationContext
* 金二通知验放规则
* todo:需要改造成验放型.返回true false,某些业务类型需要强制走金二验放,海关智能卡口配置端也是根据通道进行配置的
*/
class G2Notice extends Script implements ChannelCheckScript {
class G2Notice extends Script {
private final Logger log = LoggerFactory.getLogger(getClass());
@Override
Object run() {
... ... @@ -25,7 +25,7 @@ class G2Notice extends Script implements ChannelCheckScript {
}
Boolean check(ExecuteParams executeParams) {
void check(ExecuteParams executeParams) {
try{
/**
* X21通道信息与流转信息比对
... ... @@ -35,19 +35,19 @@ class G2Notice extends Script implements ChannelCheckScript {
GatherInfo info = (GatherInfo) executeParams.get("GatherInfo");
LandBusinessTypeList landBusinessTypeList = (LandBusinessTypeList) executeParams.get("ChanelFormInfo");
if (landBusinessTypeList!=null){
rightChnelCheck(landBusinessTypeList.getBusinesstype(),info);
cacheWithSeqno(info);
log.info("[G2-ROUTER-CACHE]-车辆[{}]流转已缓存[SEQNO]:{}",info.getVename(),info.getSeqno());
//将X21报文发给三宝,让三宝发给金二
sendToSample(info);
record(info,true,"已转金二验放-[SEQN]:"+info.getSeqno(),null);
}else {
/**
* 对应进出场申请数据
*/
log.error("[G2]-X21与流转信息核碰失败,未有流转缓存或者二维码对碰不成功");
CommandClient.Client(info,"未找到通道对应申报信息,或二维码信息不一致");
record(info,false,"[FormCheck]-未找到通道对应申报信息",null);
record(info,true,"金二验放失败,未有相关通道流转申请信息",null);
CommandClient.Client(info,"金二验放失败,未有相关通道流转申请信息");
}
}catch (Exception e){
e.printStackTrace();
log.error("[LockNoticeCheck-ERR]:",e);
return false;
}
}
... ... @@ -58,76 +58,7 @@ class G2Notice extends Script implements ChannelCheckScript {
return context;
}
void rightChnelCheck(String businessType,GatherInfo info){
LandRouterConfig landRouterConfig = new LandRouterConfig();
landRouterConfig.setBusinessType(businessType);
landRouterConfig.setAreaId(info.getAreaid());
ApplicationContext context = getContext();
LandRouterConfigDao landRouterConfigDao = context.getBean(LandRouterConfigDao.class);
//查询此场站此业务类型有无金二业务配置
List<LandRouterConfig> routerConfigs = landRouterConfigDao.selectByBussType(landRouterConfig);
//有金二与业务类型绑定
if (!routerConfigs.isEmpty()){
/**
* 路由配置的卡口 是进出卡口都有 还是只有进或者出
* 根据X21过的通道类型(进卡口/出卡口)来判定,对应流转申报业务类型 的 进出卡口业务是否有金二通道配置
*/
boolean anyMatch = routerConfigs.stream().anyMatch({router-> router.getChanelType().equals(info.getIetype())});
/**
* 有对应卡口进出类型的配置
* 继续判定
* 1 通道是否走对. 走对 将X21报文给金二,由三宝转成X81
* 2 没走对 返回 走错通道.业务结束.
*/
if (anyMatch){
//是否走对通道的判定
for (LandRouterConfig routerConfig : routerConfigs) {
if (routerConfig.getChanelId().equals(info.getChnlno())){
/**
* 查找到金二与通道的验放配置
*/
log.info("[G2-ROUTER]-车辆[{}]流转为金二业务,转金二处理",info.getVename());
//缓存X21,用来接收海关的x82指令核对.收到X22指令后进行核销此缓存.走金二验放的才缓存
cacheWithSeqno(info);
log.debug("[G2-ROUTER-CACHE]-车辆[{}]流转已缓存[SEQNO]:{}",info.getVename(),info.getSeqno());
//将X21报文发给三宝,让三宝发给金二
sendToSample(info);
record(info,true,"已转金二验放-[SEQN]:"+info.getSeqno(),null);
log.info("[G2]>>为[金二业务],已将[{}]过卡信息发送与金二",info.getVename());
return;
}
}
/**
* 没适配上 为走错通道,走错通道直接给指令,不走本地验放.
* 为提高抬杆效率
*/
//todo:走错通道的回执指令处理
log.info("[rightChnelCheck]-走错通道");
CommandClient.Client(info,"G2-走错通道,未找到通道对应申报信息,或二维码信息不一致");
record(info,false,"走错通道-[SEQN]:"+info.getSeqno(),null);
}
/**
* 有对应卡口进出类型的配置.
* 说明没有金二配置
* 走本地
*/
else{
//没有金二配置,走本地
// X21Local(info);
log.info("[G2Notice-CHECK]-通道[{}]没有G2配置",info.getChnlno())
}
}else {
//没有金二配置,走本地
// X21Local(info);
log.info("[G2Notice-CHECK]-通道[{}]没有G2配置",info.getChnlno())
}
}
void record(GatherInfo info, boolean result, String reason, LandBusinessTypeList landBusinessTypeList){
ApplicationContext context = getContext();
... ...
package com.sy.groovy
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONArray
import com.alibaba.fastjson.JSONObject
import com.sy.model.G2X81Template
import com.sy.model.GatherInfo
import com.sy.model.LandBusinessTypeList
import com.sy.model.LandRoadVe
import com.sy.response.ResultJson
import com.sy.service.CommandLogService
import com.sy.service.RedisService
import com.sy.service.feigin.G2X81FeignService
import com.sy.service.feigin.StationManageFeignService
import com.sy.socket.CommandClient
import org.apache.commons.lang.StringUtils
import org.basis.enhance.groovy.entity.ExecuteParams
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.context.ApplicationContext
import java.nio.charset.Charset
import java.text.SimpleDateFormat
/**
* 金二特殊区域验放
* 必须返回false 为异步验放 由X82判定抬杆 ,验放排序放最后
* todo:需要改造成验放型.返回true false,某些业务类型需要强制走金二验放,海关智能卡口配置端也是根据通道进行配置的
*/
class G2X81Notice extends Script implements ChannelCheckScript{
private final Logger log = LoggerFactory.getLogger(getClass());
@Override
Object run() {
return null
}
/**
* 此接口不做抬杆判定,只做报文通知,返回只有false
*/
Boolean check(ExecuteParams executeParams) {
try{
/**
* X21通道信息与流转信息比对
* 1. 从缓存获取车辆进出场申请信息,有流转信息再进行通道对碰.
* 无流转信息则说明缓存失效或者二维码不对.
*/
GatherInfo info = (GatherInfo) executeParams.get("GatherInfo");
LandRoadVe ve = (LandRoadVe) executeParams.get("LandRoadVe");
ApplicationContext context = getContext();
G2X81FeignService g2X81FeignService = context.getBean(G2X81FeignService.class);
if (info!=null){
//缓存X21 的 seqn 需要作为异步X82回执验放时用到的信息
cacheWithSeqno(info);
log.info("[G2-X81-CACHE]-车辆[{}]特殊区域流转已缓存[SEQNO]:{}",info.getVename(),info.getSeqno());
//将X21报文转换成X81格式
String xmlStr = x22TransToX81(info,ve);
//调用本地X81申报接口
ResultJson g2ResultJson = g2X81FeignService.send(xmlStr);
log.info("[G2-X81-API-RSP]-金二通知接口返回,code:{},message:{},err:{}",g2ResultJson.getCode(),g2ResultJson.getMsg(),g2ResultJson.getError());
if ("200".equals(g2ResultJson.getCode())){
record(info,true,"已转金二验放-[SEQN]:"+info.getSeqno(),null);
log.info("[G2-ROUTER-SUCCESS]-已转金二验放路由成功-规则验放成功-需要忽略下方报错,SEQNO:{}",info.getSeqno());
}else{
log.error("[G2-X81-API-ERR]-金二路由接口访问出错")
}
}else {
record(info,true,"金二验放失败,未有相关通道流转申请信息",null);
CommandClient.Client(info,"金二验放失败,未有相关通道流转申请信息");
}
}catch (Exception e){
e.printStackTrace();
log.error("[G2-ROUTER-ERR]:",e);
}
return false;
}
// 获取spring容器
ApplicationContext getContext() {
// 获取spring IOC容器
ApplicationContext context = applicationContext;
return context;
}
void record(GatherInfo info, boolean result, String reason, LandBusinessTypeList landBusinessTypeList){
ApplicationContext context = getContext();
CommandLogService commandLogService = context.getBean(CommandLogService.class);
commandLogService.commandlog(info,result,reason,landBusinessTypeList,null,0.0,0.0,0.0,0.0);
}
String x22TransToX81(GatherInfo gatherInfo,LandRoadVe ve){
log.info("[SEQN]-处理X21报文:{}",gatherInfo.getSeqno());
//当前时间作为X81申报时间
final SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
final String startTime = sdf.format(new Date());
//金二场站ID与通道ID替换
ApplicationContext context = getContext();
StationManageFeignService stationManageFeignService = context.getBean(StationManageFeignService.class);
ResultJson resultJson = stationManageFeignService.getChanels(gatherInfo.getChnlno(),1,1);
if ("200".equals(resultJson.getCode())){
JSONObject jsonObject = resultJson.getData();
int total = jsonObject.getInteger("total");
if (total>0){
JSONArray jsonArray = jsonObject.getJSONArray("list");
JSONObject chanel = jsonArray.getJSONObject(0);
String channelG2 = chanel.getString("channelG2");
log.info("[G2-CHANNEL]-{}",channelG2);
JSONObject yard = chanel.getJSONObject("yard");
String stationG2 = yard.getString("stationIdG2");
log.info("[G2-YARD]-{}",stationG2);
log.info("[G2-TEMPLATE]-{}",G2X81Template.template)
String x81XML= G2X81Template.template.replace("#{ie_flag}",gatherInfo.getIetype())
.replace("#{area_id}",stationG2)
.replace("#{chnl_no}",channelG2)
.replace("#{session_id}",gatherInfo.getSeqno())
.replace("#{ve_license_no}",gatherInfo.getVename())
.replace("#{gross_wt}",gatherInfo.getGrosswt().toString())
.replace("#{rfid_id}",gatherInfo.getCarecno())
.replace("#{ve_wt}",ve.getSelfWt())
.replace("#{operate_time}",startTime);
log.info("[X21-TO-X81]-{}",x81XML);
String mqXMLStr = mqXMLMake(x81XML,gatherInfo.getSeqno(),startTime);
log.info("[X21-TO-X81]-加密后的报文为:{}",mqXMLStr)
return mqXMLStr;
}else {
throw new Exception("未获取到通道金二配置信息")
}
}else {
log.error("场站管理服务接口访问失败")
}
return "";
}
String mqXMLMake(String xmlStr,String copMsgId,String creatTime){
String base64EncodeToString = Base64.getEncoder().encodeToString(xmlStr.getBytes(Charset.forName("utf-8")));
log.info("[SEND-BASE64-ENCODE]-{}",base64EncodeToString)
return G2X81Template.mq_template.replace("#{CopMsgId}",copMsgId)
.replace("#{CreatTime}",creatTime)
.replace("#{Data}",base64EncodeToString);
}
void cacheWithSeqno(GatherInfo info){
ApplicationContext context = getContext();
RedisService redisService = context.getBean(RedisService.class);
if (info!=null && StringUtils.isNotEmpty(info.getSeqno())) {
redisService.set(info.getSeqno(), JSON.toJSONString(info),60*60*24*3);
}
}
}
... ...
package com.sy.handle;
import com.sy.model.DxpMsg;
import com.sy.model.GatherInfo;
import com.sy.model.X82Feedback;
import com.sy.service.X82Service;
import com.sy.service.router.MessageRouterG2;
import com.sy.socket.CommandClient;
import com.sy.utils.Base64Tool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class G2FeedBackHandel extends Thread {
private String feedBack;
private X82Service x82Service;
private MessageRouterG2 messageRouterG2;
public X82Service getX82Service() {
return x82Service;
}
public void setX82Service(X82Service x82Service) {
this.x82Service = x82Service;
}
public MessageRouterG2 getMessageRouterG2() {
return messageRouterG2;
}
public void setMessageRouterG2(MessageRouterG2 messageRouterG2) {
this.messageRouterG2 = messageRouterG2;
}
public String getFeedBack() {
return feedBack;
}
public void setFeedBack(String feedBack) {
this.feedBack = feedBack;
}
@Override
public void run() {
try {
DxpMsg dxpMsg = x82Service.analysis(feedBack);
String data = dxpMsg.getData();
//解密BASE64 得到X82报文
String x82Str = Base64Tool.decodeUtf8ToUtf8(data);
//解析报文
X82Feedback x82Feedback = x82Service.x82Analysis(x82Str);
String seqno = x82Feedback.getSessionId();
GatherInfo gatherInfo = x82Service.readCacheWithSeqno(seqno);
//todo: X82Feedback 与 X21 实体类转换
if (StringUtils.isNotEmpty(x82Feedback.getChannelNo())){
if (gatherInfo!=null){
//得到sessionid ,申报出去的X81sessionId=seqno ,一去一回sessionId一样
if (x82Service.X82ReleaseCheck(x82Feedback)){
//放行及核销
messageRouterG2.route(gatherInfo,x82Feedback.getOpHint());
}else{
log.info("[G2-CHECK-FAILD]-金二验放失败,不予放行");
messageRouterG2.faild(gatherInfo,x82Feedback.getOpHint());
}
}else {
GatherInfo gatherInfo1 = x82Service.X82FeedBackToX21GatherInfo(x82Feedback);
messageRouterG2.faild(gatherInfo1,x82Feedback.getOpHint());
}
}else {
log.error("[G2-FEEDBACK-XML-ERR]-金二验放未知错误,源报文:{},解密报文:{}",feedBack,x82Str);
}
}catch (Exception e){
log.error("金二回执处理线程出错",e);
}
}
}
... ...
package com.sy.model;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import java.util.List;
@XStreamAlias("DxpMsg")
public class DxpMsg {
@XStreamAlias("TransInfo")
private TransInfo transInfo;
@XStreamAlias("Data")
private String data;
@XStreamAlias("AddInfo")
private AddInfo addInfo;
public TransInfo getTransInfo() {
return transInfo;
}
public void setTransInfo(TransInfo transInfo) {
this.transInfo = transInfo;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public AddInfo getAddInfo() {
return addInfo;
}
public void setAddInfo(AddInfo addInfo) {
this.addInfo = addInfo;
}
}
class TransInfo{
@XStreamAlias("CopMsgId")
private String copMsgId;
@XStreamAlias("SenderId")
private String senderId;
@XStreamAlias("ReceiverIds")
private ReceiverIds receiverIds;
@XStreamAlias("CreatTime")
private String creatTime;
@XStreamAlias("MsgType")
private String msgType;
public String getCopMsgId() {
return copMsgId;
}
public void setCopMsgId(String copMsgId) {
this.copMsgId = copMsgId;
}
public String getSenderId() {
return senderId;
}
public void setSenderId(String senderId) {
this.senderId = senderId;
}
public ReceiverIds getReceiverIds() {
return receiverIds;
}
public void setReceiverIds(ReceiverIds receiverIds) {
this.receiverIds = receiverIds;
}
public String getCreatTime() {
return creatTime;
}
public void setCreatTime(String creatTime) {
this.creatTime = creatTime;
}
public String getMsgType() {
return msgType;
}
public void setMsgType(String msgType) {
this.msgType = msgType;
}
}
class ReceiverIds{
@XStreamImplicit(itemFieldName = "ReceiverId")
private List<String> receiverId;
public List<String> getReceiverId() {
return receiverId;
}
public void setReceiverId(List<String> receiverId) {
this.receiverId = receiverId;
}
}
class AddInfo{
@XStreamAlias("FileName")
private String fileName;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}
... ...
package com.sy.model;
/**
* 金二X81报文xml模板
*/
public class G2X81Template {
/**
* 金二X81报文封装模板
*/
public static final String template= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<GATHER_INFO xmlns=\"http://rpb.customs.gov.cn/common/FrontEndSchemas/\"\n" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
" xsi:schemaLocation=\"http://rpb.customs.gov.cn/common/FrontEndSchemas/\">\n" +
" <I_E_FLAG>#{ie_flag}</I_E_FLAG>\n" +
" <AREA_ID>#{area_id}</AREA_ID>\n" +
" <CHNL_NO>#{chnl_no}</CHNL_NO>\n" +
" <GETHER_MODE>A</GETHER_MODE>\n" +
" <SESSION_ID>#{session_id}</SESSION_ID>\n" +
" <IC_INFO>\n" +
" <IC_ID></IC_ID>\n" +
" <IC_NO></IC_NO>\n" +
" <IC_TYPE></IC_TYPE>\n" +
" <IC_EXTENDED_CONTENT></IC_EXTENDED_CONTENT>\n" +
" </IC_INFO>\n" +
" <FORM_INFO>\n" +
" <FORM_TYPE></FORM_TYPE>\n" +
" <FORM_ID></FORM_ID>\n" +
" </FORM_INFO>\n" +
" <VE_LICENSE_NO>#{ve_license_no}</VE_LICENSE_NO>\n" +
" <GROSS_WT>#{gross_wt}</GROSS_WT>\n" +
" <VE_RFID>\n" +
" <RFID_ID>#{rfid_id}</RFID_ID>\n" +
" <VE_LICENSE_NO>#{ve_license_no}</VE_LICENSE_NO>\n" +
" <VE_CUSTOMS_NO></VE_CUSTOMS_NO>\n" +
" <VE_WT>#{ve_wt}</VE_WT>\n" +
" <VE_COMPANY></VE_COMPANY>\n" +
" <VE_PERFORMANCE>1</VE_PERFORMANCE>\n" +
" </VE_RFID>\n" +
" <OPERATE_TIME>#{operate_time}</OPERATE_TIME>\n" +
"</GATHER_INFO>\n";
private static final String demo="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<GATHER_INFO xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://rpb.customs.gov.cn/common/FrontEndSchemas/\">\n" +
"<I_E_FLAG>I</I_E_FLAG>\n" +
"<AREA_ID>5301HG</AREA_ID>\n" +
"<CHNL_NO>53010HITest101</CHNL_NO>\n" +
"<GETHER_MODE>B</GETHER_MODE>\n" +
"<SESSION_ID>20180130173410733</SESSION_ID>\n" +
" <VE_RFID>\n" +
"<RFID_ID>E0040000BA0EE801</RFID_ID>\n" +
"</VE_RFID>\n" +
"<OPERATOR_ID>5399990</OPERATOR_ID>\n" +
"<OPERATE_TIME>2016-11-24 11:31:52</OPERATE_TIME>\n" +
"</GATHER_INFO>";
/**
* 发送报文封装模板
*/
public static final String mq_template = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
"<DxpMsg xmlns=\"http://www.chinaport.gov.cn/dxp\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ver=\"1.0\">\n" +
" <TransInfo>\n" +
" <CopMsgId>#{CopMsgId}</CopMsgId>\n" +
" <SenderId>GDXPKK0000000002</SenderId>\n" +
" <MsgType>JCKK</MsgType>\n" +
" <CreatTime>#{CreatTime}</CreatTime>\n" +
" <ReceiverIds>\n" +
" <ReceiverId>GJCKK00000000001</ReceiverId>\n" +
" </ReceiverIds>\n" +
" </TransInfo>\n" +
" <Data>#{Data}</Data>\n" +
"</DxpMsg>";
}
... ...
package com.sy.model;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("GATHER_FEEDBACK")
public class X82Feedback {
@XStreamAlias("AREA_ID")
// 区域ID
private String areaId;
@XStreamAlias("CHNL_NO")
// 渠道号
private String channelNo;
@XStreamAlias("SESSION_ID")
// 会话ID
private String sessionId;
@XStreamAlias("RELLIST_TYPE")
// 关联列表类型
private String relListType;
@XStreamAlias("RELLIST_ID_TYPE")
// 关联列表ID类型
private String relListIdType;
@XStreamAlias("RELLIST_ID")
// 关联列表ID
private String relListId;
@XStreamAlias("FEEDBACK_TIME")
// 反馈时间
private String feedbackTime;
@XStreamAlias("CHECK_RESULT")
// 检查结果
private String checkResult;
@XStreamAlias("INSTRUCTION")
// 指令
private String instruction;
@XStreamAlias("PROC_ERROR_CODE")
// 处理错误代码
private int procErrorCode;
@XStreamAlias("PROC_ERROR_DESCRIPTION")
// 处理错误描述
private String procErrorDescription;
@XStreamAlias("TECH_ERROR_CODE")
// 技术错误代码
private int techErrorCode;
@XStreamAlias("TECH_ERROR_DESCRIPTION")
// 技术错误描述
private String techErrorDescription;
@XStreamAlias("IC_INFO")
// IC信息
private ICInfo icInfo;
@XStreamAlias("VE_INFO")
// 车辆信息
private VEInfo veInfo;
@XStreamAlias("CONTA_ID")
// 货柜ID
private String contaId;
@XStreamAlias("ESEAL_ID")
// 电子封条ID
private String eSealId;
@XStreamAlias("SEAL_ID")
// 封条ID
private String sealId;
@XStreamAlias("FORM_INFO")
// 表单信息
private FormInfo formInfo;
@XStreamAlias("PACK_NO")
// 包裹数量
private int packNo;
@XStreamAlias("DECL_PACK")
// 申报包裹数量
private int declPack;
@XStreamAlias("DECL_GOODS_WEIGHT")
// 申报货物重量
private double declGoodsWeight;
@XStreamAlias("OP_HINT")
// 操作提示
private String opHint;
@XStreamAlias("LED_HINT")
// LED提示
private String ledHint;
@XStreamAlias("EXTENDED_CONTENT")
// 扩展内容
private String extendedContent;
public String getAreaId() {
return areaId;
}
public void setAreaId(String areaId) {
this.areaId = areaId;
}
public String getChannelNo() {
return channelNo;
}
public void setChannelNo(String channelNo) {
this.channelNo = channelNo;
}
public String getSessionId() {
return sessionId;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public String getRelListType() {
return relListType;
}
public void setRelListType(String relListType) {
this.relListType = relListType;
}
public String getRelListIdType() {
return relListIdType;
}
public void setRelListIdType(String relListIdType) {
this.relListIdType = relListIdType;
}
public String getRelListId() {
return relListId;
}
public void setRelListId(String relListId) {
this.relListId = relListId;
}
public String getFeedbackTime() {
return feedbackTime;
}
public void setFeedbackTime(String feedbackTime) {
this.feedbackTime = feedbackTime;
}
public String getCheckResult() {
return checkResult;
}
public void setCheckResult(String checkResult) {
this.checkResult = checkResult;
}
public String getInstruction() {
return instruction;
}
public void setInstruction(String instruction) {
this.instruction = instruction;
}
public int getProcErrorCode() {
return procErrorCode;
}
public void setProcErrorCode(int procErrorCode) {
this.procErrorCode = procErrorCode;
}
public String getProcErrorDescription() {
return procErrorDescription;
}
public void setProcErrorDescription(String procErrorDescription) {
this.procErrorDescription = procErrorDescription;
}
public int getTechErrorCode() {
return techErrorCode;
}
public void setTechErrorCode(int techErrorCode) {
this.techErrorCode = techErrorCode;
}
public String getTechErrorDescription() {
return techErrorDescription;
}
public void setTechErrorDescription(String techErrorDescription) {
this.techErrorDescription = techErrorDescription;
}
public ICInfo getIcInfo() {
return icInfo;
}
public void setIcInfo(ICInfo icInfo) {
this.icInfo = icInfo;
}
public VEInfo getVeInfo() {
return veInfo;
}
public void setVeInfo(VEInfo veInfo) {
this.veInfo = veInfo;
}
public String getContaId() {
return contaId;
}
public void setContaId(String contaId) {
this.contaId = contaId;
}
public String geteSealId() {
return eSealId;
}
public void seteSealId(String eSealId) {
this.eSealId = eSealId;
}
public String getSealId() {
return sealId;
}
public void setSealId(String sealId) {
this.sealId = sealId;
}
public FormInfo getFormInfo() {
return formInfo;
}
public void setFormInfo(FormInfo formInfo) {
this.formInfo = formInfo;
}
public int getPackNo() {
return packNo;
}
public void setPackNo(int packNo) {
this.packNo = packNo;
}
public int getDeclPack() {
return declPack;
}
public void setDeclPack(int declPack) {
this.declPack = declPack;
}
public double getDeclGoodsWeight() {
return declGoodsWeight;
}
public void setDeclGoodsWeight(double declGoodsWeight) {
this.declGoodsWeight = declGoodsWeight;
}
public String getOpHint() {
return opHint;
}
public void setOpHint(String opHint) {
this.opHint = opHint;
}
public String getLedHint() {
return ledHint;
}
public void setLedHint(String ledHint) {
this.ledHint = ledHint;
}
public String getExtendedContent() {
return extendedContent;
}
public void setExtendedContent(String extendedContent) {
this.extendedContent = extendedContent;
}
}
@XStreamAlias("IC_INFO")
class ICInfo {
@XStreamAlias("IC_ID")
// IC ID
private String icId;
@XStreamAlias("IC_NO")
// IC编号
private String icNo;
@XStreamAlias("IC_TYPE")
// IC类型
private String icType;
@XStreamAlias("IC_EXTENDED_CONTENT")
// IC扩展内容
private String icExtendedContent;
public String getIcId() {
return icId;
}
public void setIcId(String icId) {
this.icId = icId;
}
public String getIcNo() {
return icNo;
}
public void setIcNo(String icNo) {
this.icNo = icNo;
}
public String getIcType() {
return icType;
}
public void setIcType(String icType) {
this.icType = icType;
}
public String getIcExtendedContent() {
return icExtendedContent;
}
public void setIcExtendedContent(String icExtendedContent) {
this.icExtendedContent = icExtendedContent;
}
}
@XStreamAlias("VE_INFO")
class VEInfo {
@XStreamAlias("VE_CUSTOMS_NO")
// 车辆海关编号
private String veCustomsNo;
@XStreamAlias("VE_LICENSE_NO")
// 车辆牌照号码
private String veLicenseNo;
@XStreamAlias("VE_LICENSE_NO2")
// 车辆牌照号码2
private String veLicenseNo2;
@XStreamAlias("DR_CUSTOMS_NO")
// 驾驶员海关编号
private String drCustomsNo;
@XStreamAlias("DR_NAME")
// 驾驶员姓名
private String drName;
@XStreamAlias("TRAILER_ID")
// 拖车ID
private String trailerId;
@XStreamAlias("WEIGHT_DIFF")
// 重量差异
private double weightDiff;
@XStreamAlias("CHANNEL_WEIGHT")
// 渠道重量
private double channelWeight;
@XStreamAlias("GROSS_WEIGHT")
// 毛重
private double grossWeight;
@XStreamAlias("VEHICLE_WEIGHT")
// 车辆重量
private double vehicleWeight;
public String getVeCustomsNo() {
return veCustomsNo;
}
public void setVeCustomsNo(String veCustomsNo) {
this.veCustomsNo = veCustomsNo;
}
public String getVeLicenseNo() {
return veLicenseNo;
}
public void setVeLicenseNo(String veLicenseNo) {
this.veLicenseNo = veLicenseNo;
}
public String getVeLicenseNo2() {
return veLicenseNo2;
}
public void setVeLicenseNo2(String veLicenseNo2) {
this.veLicenseNo2 = veLicenseNo2;
}
public String getDrCustomsNo() {
return drCustomsNo;
}
public void setDrCustomsNo(String drCustomsNo) {
this.drCustomsNo = drCustomsNo;
}
public String getDrName() {
return drName;
}
public void setDrName(String drName) {
this.drName = drName;
}
public String getTrailerId() {
return trailerId;
}
public void setTrailerId(String trailerId) {
this.trailerId = trailerId;
}
public double getWeightDiff() {
return weightDiff;
}
public void setWeightDiff(double weightDiff) {
this.weightDiff = weightDiff;
}
public double getChannelWeight() {
return channelWeight;
}
public void setChannelWeight(double channelWeight) {
this.channelWeight = channelWeight;
}
public double getGrossWeight() {
return grossWeight;
}
public void setGrossWeight(double grossWeight) {
this.grossWeight = grossWeight;
}
public double getVehicleWeight() {
return vehicleWeight;
}
public void setVehicleWeight(double vehicleWeight) {
this.vehicleWeight = vehicleWeight;
}
}
@XStreamAlias("FORM_INFO")
class FormInfo {
@XStreamAlias("FORM_TYPE")
// 表单类型
private String formType;
@XStreamAlias("FORM_ID")
// 表单ID
private String formId;
@XStreamAlias("MASTER_CUSTOMS_CODE")
// 主管海关代码
private String masterCustomsCode;
public String getFormType() {
return formType;
}
public void setFormType(String formType) {
this.formType = formType;
}
public String getFormId() {
return formId;
}
public void setFormId(String formId) {
this.formId = formId;
}
public String getMasterCustomsCode() {
return masterCustomsCode;
}
public void setMasterCustomsCode(String masterCustomsCode) {
this.masterCustomsCode = masterCustomsCode;
}
}
... ...
... ... @@ -44,6 +44,12 @@ public interface EnginCheckService {
void pass(GatherInfo info,ExecuteParams executeParams);
/**
* 不放行
* @param info
*/
void passFaild(GatherInfo info,String reason,ExecuteParams executeParams);
/**
* 记录已进出区信息
*/
void record(GatherInfo info,ExecuteParams executeParams);
... ...
package com.sy.service;
import com.sy.model.DxpMsg;
import com.sy.model.GatherInfo;
import com.sy.model.X82Feedback;
public interface X82Service {
/**
* 解析被封装的X82金二验放回执报文,并获取到DATA base64加密后的报体内容.
* @param response
*/
DxpMsg analysis(String response);
X82Feedback x82Analysis(String xml);
Boolean X82ReleaseCheck(X82Feedback var);
GatherInfo readCacheWithSeqno(String seqno);
/**
* 将X82的报文实体类转换成X21GatherInfo 实体,用来做最终验放参数用
* @param var X82Feedback实体类
* @return X21 GatherInfo 实体类
*/
GatherInfo X82FeedBackToX21GatherInfo(X82Feedback var);
}
... ...
package com.sy.service.feigin;
import com.sy.model.LockFeignResponse;
import com.sy.model.NoticeLock;
import com.sy.response.ResultJson;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
/**
* @author mrz
*/
@Component
@Slf4j
public class G2X81FeignFallBackFactory implements FallbackFactory<G2X81FeignService> {
@Override
public G2X81FeignService create(Throwable throwable) {
log.error("调用金二X81通知接口异常",throwable);
return new G2X81FeignService() {
@Override
public ResultJson send(String message) {
return new ResultJson("400","金二X81申报接口访问失败");
}
};
}
}
... ...
package com.sy.service.feigin;
import com.sy.model.LockFeignResponse;
import com.sy.model.NoticeLock;
import com.sy.response.ResultJson;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 金二报文发送接口
* @author mrz
*/
@FeignClient(name = "SEND-IBMMQ-SERVIER",fallbackFactory = G2X81FeignFallBackFactory.class)
public interface G2X81FeignService {
@PostMapping("/ibm/mq/sendMsg")
ResultJson send(@RequestParam("message") String message);
}
... ...
package com.sy.service.feigin;
import com.sy.response.ResultJson;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @author mrz
*/
@Component
@Slf4j
public class StationManageFallBackFactory implements FallbackFactory<StationManageFeignService> {
@Override
public StationManageFeignService create(Throwable throwable) {
log.error("调用场站管理接口异常",throwable);
return new StationManageFeignService() {
@Override
public ResultJson getChanels(String channel, int pageNum, int pageSize) {
return new ResultJson("410","场站管理服务接口访问失败");
}
};
}
}
... ...
package com.sy.service.feigin;
import com.sy.response.ResultJson;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 金二报文发送接口
* @author mrz
*/
@FeignClient(name = "STATION-MANAGE",fallbackFactory = StationManageFallBackFactory.class)
public interface StationManageFeignService {
@GetMapping("/bayonet/page")
ResultJson getChanels(@RequestParam(value = "channel") String channel,@RequestParam(value = "pageNum") int pageNum,@RequestParam(value = "pageSize") int pageSize);
}
... ...
... ... @@ -209,11 +209,10 @@ public class EnginCheckServiceImpl implements EnginCheckService {
}
log.info(String.format("开始发送指令:车牌%s,场站%s,通道%s,重量%s",info.getVename(),info.getAreaid(),info.getChnlno(),info.getGrosswt()));
boolean flag = false;
if (check) {
CommandClient.Client(info, PERMITTHOUGH);
log.info("=============>>>>>>>>放行报文发送成功<<<<<<<<<==============");
flag = true;
record(info,executeParams);
//总进出车次计数
... ... @@ -233,6 +232,11 @@ public class EnginCheckServiceImpl implements EnginCheckService {
sendBw(info,true,PERMITTHOUGH,executeParams);
}
@Override
public void passFaild(GatherInfo info,String reason,ExecuteParams executeParams) {
sendBw(info,false,reason,executeParams);
}
/**
* 记录进出区信息
*/
... ...
package com.sy.service.impl;
import com.alibaba.fastjson.JSON;
import com.sy.model.DxpMsg;
import com.sy.model.GatherInfo;
import com.sy.model.X82Feedback;
import com.sy.service.CommandLogService;
import com.sy.service.RedisService;
import com.sy.service.X82Service;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
@Service
@Slf4j
public class X82ServiceImpl implements X82Service {
@Autowired
private RedisService redisService;
@Autowired
private CommandLogService commandLogService;
@Override
public DxpMsg analysis(String response) {
XStream xstream = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("_-", "_")));
xstream.processAnnotations(DxpMsg.class);
//对xstream对象设置默认的安全防护
XStream.setupDefaultSecurity(xstream);
//对xstream对象设置默认的安全防护时,允许设置类
xstream.allowTypes(new Class[]{DxpMsg.class});
return (DxpMsg) xstream.fromXML(response);
}
@Override
public X82Feedback x82Analysis(String xml) {
XStream xstream = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("_-", "_")));
xstream.processAnnotations(X82Feedback.class);
//对xstream对象设置默认的安全防护
XStream.setupDefaultSecurity(xstream);
//对xstream对象设置默认的安全防护时,允许设置类
xstream.allowTypes(new Class[]{X82Feedback.class});
return (X82Feedback) xstream.fromXML(xml);
}
@Override
public Boolean X82ReleaseCheck(X82Feedback var) {
log.info("[X82-Result]金二验放结果-{}-{}",var.getCheckResult(),var.getOpHint());
if ("Y".equals(var.getCheckResult().trim()) || "1".equals(var.getCheckResult().trim())) {
return true;
}
return false;
}
/**
* 根据seqno 获取缓存的X21信息
* @param seqno
* @return x21的gatherInfo
*/
@Override
public GatherInfo readCacheWithSeqno(String seqno){
if (StringUtils.isNotEmpty(seqno)) {
String X21_GatherInfo = redisService.get(seqno);
if (StringUtils.isNotEmpty(X21_GatherInfo)){
GatherInfo gatherInfo = JSON.parseObject(X21_GatherInfo, GatherInfo.class);
return gatherInfo;
}
}
return null;
}
@Override
public GatherInfo X82FeedBackToX21GatherInfo(X82Feedback var) {
GatherInfo gatherInfo = new GatherInfo();
gatherInfo.setAreaid(var.getAreaId());
gatherInfo.setChnlno(var.getChannelNo());
gatherInfo.setSeqno(var.getSessionId());
return gatherInfo;
}
public static class DateConverter implements Converter {
private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSXXX";
private final SimpleDateFormat dateFormat;
public DateConverter() {
this.dateFormat = new SimpleDateFormat(DATE_FORMAT);
}
@Override
public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext context) {
// Not used for unmarshalling
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
String dateString = reader.getValue();
try {
return dateFormat.parse(dateString);
} catch (ParseException e) {
throw new IllegalArgumentException("Error parsing date string: " + dateString, e);
}
}
@Override
public boolean canConvert(Class aClass) {
return aClass.equals(Date.class);
}
}
}
... ...
package com.sy.service.router;
import com.sy.bwAssist.Message;
import com.sy.model.GatherInfo;
/**
* 卡口业务报文处理路由
* 处理接收的卡口报文X22与X21,
* 并根据路由表,决定X21报文是否发送给金二,由金二验放处理,并本地记录.还是不发金二本地验放处理
* 集中核销流转申请.
* @author mrz
*/
public interface MessageRouterG2 {
/**
* X82报文实体路由处理
*/
void route(GatherInfo gatherInfo,String reason);
/**
* 不放行处理
*/
void faild(GatherInfo gatherInfo,String reason);
}
... ...
package com.sy.service.router;
import com.sy.bwAssist.Message;
import com.sy.model.GatherInfo;
import com.sy.service.CommandLogService;
import com.sy.service.EnginCheckService;
import lombok.extern.slf4j.Slf4j;
import org.basis.enhance.groovy.entity.ExecuteParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Slf4j
@Service("X82")
public class MessageRouterX82 implements MessageRouterG2 {
@Autowired
private EnginCheckService enginCheckService;
@Autowired
private CommandLogService commandLogService;
@Override
public void route(GatherInfo gatherInfo,String reason) {
log.info("[G2-SUCCESS]-金二验放通过,下放最终抬杆指令.");
enginCheck(gatherInfo,reason);
}
@Override
public void faild(GatherInfo gatherInfo,String reason) {
commandLogService.commandlog(gatherInfo,false,"金二验放失败,原因:"+reason,null,null,0.0,0.0,0.0,0.0);
ExecuteParams executeParams = enginCheckService.makeParaByGagherInfo(gatherInfo);
enginCheckService.passFaild(gatherInfo,reason,executeParams);
log.info("[G2-FEEDBACK-CHECK-FAILD]-{}",reason);
}
public void enginCheck(GatherInfo gatherInfo,String reason){
commandLogService.commandlog(gatherInfo,true,"金二验放通过"+reason,null,null,0.0,0.0,0.0,0.0);
ExecuteParams executeParams = enginCheckService.makeParaByGagherInfo(gatherInfo);
enginCheckService.pass(gatherInfo,executeParams);
enginCheckService.formRelease(gatherInfo,executeParams);
log.info("引擎验放完结");
}
}
... ...
package com.sy.utils;
import lombok.extern.slf4j.Slf4j;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
@Slf4j
public class Base64Tool {
public static String encodeUtf8ToUtf8(String content){
String encodeToString = Base64.getEncoder().encodeToString(content.getBytes(StandardCharsets.UTF_8));
log.info("[BASE64-ENCODE] = {}" , encodeToString);
return encodeToString;
}
public static String decodeUtf8ToUtf8(String encodeStr){
byte[] base64decodedBytes = Base64.getDecoder().decode(encodeStr);
String resoult = new String(base64decodedBytes, StandardCharsets.UTF_8);
log.info("[BASE64-DECODE]={}",resoult);
return resoult;
}
}
... ...
package com.sy.utils;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class G2ThreadPoolFactory {
private static ThreadPoolExecutor threadPool;
public static ThreadPoolExecutor instance(String busstype){
if (threadPool==null){
XMLThreadFactory xmlThreadFactory = new XMLThreadFactory(busstype);
threadPool = new ThreadPoolExecutor(10, 200,
1L, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(4000),
xmlThreadFactory,
new ThreadPoolExecutor.AbortPolicy());
}
return threadPool;
}
}
... ...
package com.sy;
import com.sy.model.G2X81Template;
import lombok.extern.slf4j.Slf4j;
import org.junit.runner.RunWith;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Base64;
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class Base64Test {
@Test
public void base64Encode(){
String encode = "<?xml version='1.0' encoding='UTF-8'?><GATHER_FEEDBACK xmlns=\"http://rpb.customs.gov.cn/common/FrontEndSchemas/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema\"><AREA_ID>4604000006</AREA_ID><CHNL_NO>46040012232</CHNL_NO><SESSION_ID>20220630184441000028</SESSION_ID><FEEDBACK_TIME>2023-08-20 15:07:16</FEEDBACK_TIME><CHECK_RESULT>1</CHECK_RESULT><OP_HINT>海关放行</OP_HINT></GATHER_FEEDBACK>";
String encodeToString = Base64.getEncoder().encodeToString(encode.getBytes(Charset.forName("utf-8")));
System.out.println("encodeToString = " + encodeToString);
}
@Test
public void base64Decode(){
String testcode = "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48R0FUSEVSX0ZFRURCQUNLIHhtbG5zPSJodHRwOi8vcnBiLmN1c3RvbXMuZ292LmNuL2NvbW1vbi9Gcm9udEVuZFNjaGVtYXMvIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIj48QVJFQV9JRD40NjA0MDAwMDA2PC9BUkVBX0lEPjxDSE5MX05PPjQ2MDQwMDEyMjMyPC9DSE5MX05PPjxTRVNTSU9OX0lEPjIwMjIwNjMwMTg0NDQxMDAwMDI4PC9TRVNTSU9OX0lEPjxGRUVEQkFDS19USU1FPjIwMjMtMDgtMjAgMTU6MDc6MTY8L0ZFRURCQUNLX1RJTUU+PENIRUNLX1JFU1VMVD4wPC9DSEVDS19SRVNVTFQ+PE9QX0hJTlQ+55S15a2Q6L2m54mMOjrkuI3mlL7ooYzvvJrmib7kuI3liLDlr7nlupTnmoTmoLjmlL7ljZXvvIzkuI3kuojmlL7ooYw8L09QX0hJTlQ+PC9HQVRIRVJfRkVFREJBQ0s+";
byte[] base64decodedBytes = Base64.getDecoder().decode(testcode);
try {
System.out.println("解密后的信息为:"+new String(base64decodedBytes, "utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
@Test
public void replaceTest(){
String x81XML= G2X81Template.template.replace("#{ie_flag1}","I")
.replace("#{area_id}","stationG2")
.replace("#{chnl_no}","channelG2")
.replace("#{session_id}","123")
.replace("#{ve_license_no}","豫A61CR7")
.replace("#{rfid_id}","AFFC231321")
.replace("#{ve_wt}","1234.2")
.replace("#{operate_time}","2023-07-23 12:01:32");
System.out.println("x81XML = " + x81XML);
}
}
... ...
package com.sy;
import com.sy.model.DxpMsg;
import com.sy.model.X82Feedback;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class X82Test {
static String dxpmsg="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<DxpMsg ver=\"1.0\" xmlns=\"http://www.chinaport.gov.cn/dxp\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
"\t<TransInfo>\n" +
"\t\t<CopMsgId>256afcf4887d49a2840ec24b78ed1755</CopMsgId>\n" +
"\t\t<SenderId>GJCKK00000000001</SenderId>\n" +
"\t\t<ReceiverIds>\n" +
"\t\t\t<ReceiverId>GDXPKK0000000002</ReceiverId>\n" +
"\t\t</ReceiverIds>\n" +
"\t\t<CreatTime>2022-08-17T15:00:52</CreatTime>\n" +
"\t\t<MsgType>JCKK</MsgType>\n" +
"\t</TransInfo>\n" +
"\t<Data>4lxLiQICAAAiNDYwNDYwMDAwMDQ2MDQ2MDEwMTFJ/////9oBAAA8Q09NTUFORF9JTkZPIEFSRUFfSUQ9IjQ2MDQ2MDAwMDAiIENITkxfTk89IjQ2MDQ2MDEwMTEiIElfRV9UWVBFPSJJIiBTRVFfTk89IjIwMjIwODE3MTQ0MjE1NjEwMDEwIj4KICAgIDxDSEVDS19SRVNVTFQ+MTEwMDAwMDAwMDAwMDAwMDAwMDA8L0NIRUNLX1JFU1VMVD4KICAgIDxPUF9ISU5UPrbByKGyu7W9tP3R6brLyv2+3TwvT1BfSElOVD4KICAgIDxHUFM+CiAgICAgICAgPFZFX05BTUU+PC9WRV9OQU1FPgogICAgICAgIDxHUFNfSUQ+PC9HUFNfSUQ+CiAgICAgICAgPE9SSUdJTl9DVVNUT01TPjwvT1JJR0lOX0NVU1RPTVM+CiAgICAgICAgPERFU1RfQ1VTVE9NUz48L0RFU1RfQ1VTVE9NUz4KICAgIDwvR1BTPgogICAgPFNFQUw+CiAgICAgICAgPEVTRUFMX0lEPjwvRVNFQUxfSUQ+CiAgICAgICAgPFNFQUxfS0VZPjwvU0VBTF9LRVk+CiAgICA8L1NFQUw+CiAgICA8Rk9STV9JRD48L0ZPUk1fSUQ+CjwvQ09NTUFORF9JTkZPPgr//w==</Data>\n" +
"\t<AddInfo>\n" +
"\t\t<FileName>20220817150050391844.dat</FileName>\n" +
"\t</AddInfo>\n" +
"</DxpMsg>";
static String x82 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<GATHER_FEEDBACK xmlns=\"http://rpb.customs.gov.cn/common/FrontEndSchemas/\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" +
" <AREA_ID>123</AREA_ID>\n" +
" <CHNL_NO>456</CHNL_NO>\n" +
" <SESSION_ID>789</SESSION_ID>\n" +
" <RELLIST_TYPE>TypeA</RELLIST_TYPE>\n" +
" <RELLIST_ID_TYPE>IDType1</RELLIST_ID_TYPE>\n" +
" <RELLIST_ID>001</RELLIST_ID>\n" +
" <FEEDBACK_TIME>2022-07-15T14:23:51.4679206+08:00</FEEDBACK_TIME>\n" +
" <CHECK_RESULT>Y</CHECK_RESULT>\n" +
" <INSTRUCTION>设备A:操作</INSTRUCTION>\n" +
" <PROC_ERROR_CODE>100</PROC_ERROR_CODE>\n" +
" <PROC_ERROR_DESCRIPTION>Error description</PROC_ERROR_DESCRIPTION>\n" +
" <TECH_ERROR_CODE>200</TECH_ERROR_CODE>\n" +
" <TECH_ERROR_DESCRIPTION>Technical error</TECH_ERROR_DESCRIPTION>\n" +
" <IC_INFO>\n" +
" <IC_ID>IC001</IC_ID>\n" +
" <IC_NO>123456</IC_NO>\n" +
" <IC_TYPE>TypeA</IC_TYPE>\n" +
" <IC_EXTENDED_CONTENT>Extended content for IC card</IC_EXTENDED_CONTENT>\n" +
" </IC_INFO>\n" +
" <VE_INFO>\n" +
" <VE_CUSTOMS_NO>7890123</VE_CUSTOMS_NO>\n" +
" <VE_LICENSE_NO>ABC123</VE_LICENSE_NO>\n" +
" <VE_LICENSE_NO2>XYZ987</VE_LICENSE_NO2>\n" +
" <DR_CUSTOMS_NO>4567890</DR_CUSTOMS_NO>\n" +
" <DR_NAME>John Doe</DR_NAME>\n" +
" <TRAILER_ID>Trailer001</TRAILER_ID>\n" +
" <WEIGHT_DIFF>0.5</WEIGHT_DIFF>\n" +
" <CHANNEL_WEIGHT>1000.0</CHANNEL_WEIGHT>\n" +
" <GROSS_WEIGHT>2000.0</GROSS_WEIGHT>\n" +
" <VEHICLE_WEIGHT>1000.0</VEHICLE_WEIGHT>\n" +
" </VE_INFO>\n" +
" <CONTA_ID>Container001</CONTA_ID>\n" +
" <ESEAL_ID>ESeal001</ESEAL_ID>\n" +
" <SEAL_ID>Seal001</SEAL_ID>\n" +
" <FORM_INFO>\n" +
" <FORM_TYPE>TypeA</FORM_TYPE>\n" +
" <FORM_ID>Form001</FORM_ID>\n" +
" <MASTER_CUSTOMS_CODE>MasterCode</MASTER_CUSTOMS_CODE>\n" +
" </FORM_INFO>\n" +
" <PACK_NO>10</PACK_NO>\n" +
" <DECL_PACK>12</DECL_PACK>\n" +
" <DECL_GOODS_WEIGHT>5000.0</DECL_GOODS_WEIGHT>\n" +
" <OP_HINT>Operation hint message</OP_HINT>\n" +
" <LED_HINT>LED hint message</LED_HINT>\n" +
" <EXTENDED_CONTENT>Extended content</EXTENDED_CONTENT>\n" +
"</GATHER_FEEDBACK>\n";
public static void main(String[] args) {
System.out.println(x82);
// DxpMsg analysis = analysis(dxpmsg);
X82Feedback x82Feedback = x82analysis(x82);
System.out.println("OK");
}
static DxpMsg analysis(String str) {
XStream xstream = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("_-", "_")));
xstream.processAnnotations(DxpMsg.class);
//对xstream对象设置默认的安全防护
XStream.setupDefaultSecurity(xstream);
//对xstream对象设置默认的安全防护时,允许设置类
xstream.allowTypes(new Class[]{DxpMsg.class});
return (DxpMsg) xstream.fromXML(str);
}
static X82Feedback x82analysis(String str) {
XStream xstream = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("_-", "_")));
// 注册自定义转换器
xstream.registerConverter(new DateConverter());
xstream.processAnnotations(X82Feedback.class);
//对xstream对象设置默认的安全防护
XStream.setupDefaultSecurity(xstream);
//对xstream对象设置默认的安全防护时,允许设置类
xstream.allowTypes(new Class[]{X82Feedback.class});
return (X82Feedback) xstream.fromXML(str);
}
public static class DateConverter implements Converter {
private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSXXX";
private final SimpleDateFormat dateFormat;
public DateConverter() {
this.dateFormat = new SimpleDateFormat(DATE_FORMAT);
}
@Override
public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext context) {
// Not used for unmarshalling
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
String dateString = reader.getValue();
try {
return dateFormat.parse(dateString);
} catch (ParseException e) {
throw new IllegalArgumentException("Error parsing date string: " + dateString, e);
}
}
@Override
public boolean canConvert(Class aClass) {
return aClass.equals(Date.class);
}
}
}
... ...