近期在对接海关的订单出口报文,从网上找了挺多的案例,下面做一个记录
1、文件目录结构如下图所示
2、各文件代码
2.1、NameSpace类
/**
* xml 命名空间
*/
public class NameSpace {
/**
* order 订单节点
*/
public static final String NAMESPACE_CEB_URI = "http://www.chinaport.gov.cn/ceb";
/**
* dep终端节点报文
*/
public static final String NAMESPACE_DXP_URI = "http://www.chinaport.gov.cn/dxp";
/**
* xsi规范
*/
public static final String NAMESPACE_XSI_URI = "http://www.w3.org/2001/XMLSchema-instance";
/**
* 签名节点xml
*/
public static final String NAMESPACE_DS_URL = "http://www.w3.org/2000/09/xmldsig#";
}
2.2、xml工作空间类 package-info.java
@XmlSchema(
xmlns = {
@XmlNs(prefix = "ceb", namespaceURI = NAMESPACE_CEB_URI),
@XmlNs(prefix = "xsi", namespaceURI = NAMESPACE_XSI_URI)
}
)
package com.ruoyi.online.request.order;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlSchema;
2.3、订单出口报文CEB303Message
import lombok.Data;
import javax.xml.bind.annotation.*;
/**
* 海关出口订单报文
*/
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "CEB303Message" , namespace = NAMESPACE_CEB_URI)
public class CEB303Message {
@XmlElement(name = "Order", namespace = NAMESPACE_CEB_URI)
private Order order;
@XmlAttribute(name = "guid")
private String guid;
@XmlAttribute(name = "version")
private String version;
@XmlElement(name = "BaseTransfer", namespace = NAMESPACE_CEB_URI)
private BaseTransfer baseTransfer;
//@XmlElement(name = "BaseSubscribe", namespace = NAMESPACE_CEB_URI)
//private BaseSubscribe baseSubscribe;
//
//@XmlElement(name = "ExtendMessage", namespace = NAMESPACE_CEB_URI)
//private ExtendMessage extendMessage;
}
2.4、订单业务节点类
import lombok.Data;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
/**
* 订单业务节点
*/
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Order ", namespace = NAMESPACE_CEB_URI)
public class Order {
@XmlElement(name = "OrderHead", namespace = NAMESPACE_CEB_URI)
private OrderHead orderHead;
@XmlElement(name = "OrderList", namespace = NAMESPACE_CEB_URI)
private List<OrderList> orderList;
}
#订单头类
import lombok.Data;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.math.BigDecimal;
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "OrderHead ", namespace = NAMESPACE_CEB_URI)
public class OrderHead {
/**
* 系统唯一序号 企业系统生成36位唯一序号 (英文字母大写)
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String guid;
/**
* 报送类型 企业报送类型。1-新增 2-变 更 3-删除。
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String appType;
/**
* 报送时间 格式:YYYYMMDDhhmmss。
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String appTime;
/**
* 报送状态 企业报送状态。1-暂存,2-申 报。填写2时,Signature节点必须 填写。
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String appStatus;
/**
* 订单类型
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String orderType;
/**
* 订单编号
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String orderNo;
/**
* 电商平台代码
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String ebpCode;
/**
* 电商平台名称
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String ebpName;
/**
* 电商
* 企业代码
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String ebcCode;
/**
* 电商企业名称
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String ebcName;
/**
* 商品金额
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private BigDecimal goodsValue;
/**
* 运杂费
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private BigDecimal freight;
/**
* 币制
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String currency;
/**
* 备注
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String note;
}
#订单列表
import lombok.Data;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.math.BigDecimal;
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "OrderList ", namespace = NAMESPACE_CEB_URI)
public class OrderList {
/**
* 序号 从1开始递增
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private Integer gnum;
/**
* 企业商品货号
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String itemNo;
/**
* 企业商品名称
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String itemName;
/**
* 企业商品描述
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String itemDescribe;
/**
* 条形码 否
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String barCode;
/**
* 计量单位
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String unit;
/**
* 币制
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String currency;
/**
* 数量
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private Integer qty;
/**
* 单价
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private BigDecimal price;
/**
* 总价
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private BigDecimal totalPrice;
/**
* 备注
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String note;
}
2.5、基础报文传输实体
import lombok.Data;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "BaseTransfer ", namespace = NAMESPACE_CEB_URI)
public class BaseTransfer {
/**
* 传输企业代码 报文传输的企业代码(需要与接入客户端的企 业身份一致)
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String copCode;
/**
* 传输企业名称
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String copName;
/**
* 报文传输模式 默认为DXP;指中国电子口岸数据交换平台
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String dxpMode;
/**
* 报文传输编号 向中国电子口岸数据中心申请数据交换平台 的用户编号
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String dxpId;
/**
* 备注
*/
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String note;
}
3、将出口订单实体转化为xml 报文工具类 JaxbUtils
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
/**
* java2xml 工具类
*/
public class JaxbUtils {
/**
* JavaBean转换成xml
* 默认编码UTF-8
*
* @param obj
* @return
*/
public static String convertToXml(Object obj) {
return convertToXml(obj, "UTF-8");
}
/**
* JavaBean转换成xml
*
* @param obj
* @param encoding
* @return
*/
public static String convertToXml(Object obj, String encoding) {
String result = null;
try {
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
//格式化xml格式
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
//去掉生成xml的默认报文头
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
StringWriter writer = new StringWriter();
// 由于不能优雅的去掉 standalone="yes" 所以只能去掉整个头部,然后手动插入一个符合条件的头部 该行为不优雅需要进行升级
writer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n");
marshaller.marshal(obj, writer);
result = writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* xml转换成JavaBean
*
* @param xml
* @param c
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T converyToJavaBean(String xml, Class<T> c) {
T t = null;
try {
JAXBContext context = JAXBContext.newInstance(c);
Unmarshaller unmarshaller = context.createUnmarshaller();
t = (T) unmarshaller.unmarshal(new StringReader(xml));
} catch (Exception e) {
e.printStackTrace();
}
return t;
}
}