1.建立命名空间
/**
* package-info.java
* 放在和实体同一个包路径下
*/
@XmlSchema(
xmlns = {
@XmlNs(prefix = "ceb", namespaceURI = NAMESPACE_CEB_URI),
@XmlNs(prefix = "xsi", namespaceURI = NAMESPACE_XSI_URI)
}
)
package com.jiubang.order.domain.xml;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlSchema;
import static com.jiubang.order.domain.xml.NameSpace.NAMESPACE_CEB_URI;
import static com.jiubang.order.domain.xml.NameSpace.NAMESPACE_XSI_URI;
2.命名空间文件NameSpace
package com.jiubang.order.domain.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#";
}
3.定义xml对象CEB311Message
package com.jiubang.order.domain.xml;
import javax.xml.bind.annotation.*;
import static com.jiubang.order.domain.xml.NameSpace.NAMESPACE_CEB_URI;
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "CEB311Message", namespace = NAMESPACE_CEB_URI)
public class CEB311Message {
@XmlElement(name = "Order", namespace = NAMESPACE_CEB_URI)
private Order order;
@XmlAttribute(name = "guid")
private String guid;
@XmlAttribute(name = "version")
private String version;
}
4.定义其中对象Order
package com.jiubang.order.domain.xml;
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 static com.jiubang.order.domain.xml.NameSpace.NAMESPACE_CEB_URI;
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;
}
5. orderHead对象
package com.jiubang.order.domain.xml;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import static com.jiubang.order.domain.xml.NameSpace.NAMESPACE_CEB_URI;
@Data
public class OrderHead {
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String guid;// 1-系统唯一序号-guid-C36-是-企业系统生成36位唯一序号(英文字母大写)。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String appType;// 2-报送类型-appType-C1-是-企业报送类型。1-新增
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String appTime;// 3-报送时间-appTime-C14-是-企业报送时间。格式:YYYYMMDDhhmmss。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String appStatus;// 4-业务状态-appStatus-C..3-是-业务状态:1-暂存,2-申报,默认为2。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String orderType;// 5-订单类型-orderType-C1-是-电子订单类型:I进口
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String orderNo;// 6-订单编号-orderNo-C..60-是-交易平台的订单编号,同一交易平台的订单编号应唯一。订单编号长度不能超过60位。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String ebpCode;// 7-电商平台代码-ebpCode-C..18-是-电商平台的海关注册登记编号;电商平台未在海关注册登记,由电商企业发送订单的,以中国电子口岸发布的电商平台标识编号为准。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String ebpName;// 8-电商平台名称-ebpName-C..100-是-电商平台的海关注册登记名称;电商平台未在海关注册登记,由电商企业发送订单的,以中国电子口岸发布的电商平台名称为准。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String ebcCode;// 9-电商企业代码-ebcCode-C..18-是-电商企业的海关注册登记编号。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String ebcName;// 10-电商企业名称-ebcName-C..100-是-电商企业的海关注册登记名称。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String goodsValue;// 11-商品价格-goodsValue-N16,2-是-商品实际成交价,含非现金抵扣金额。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String freight;// 12-运杂费-freight-N16,2-是-不包含在商品价格中的运杂费,无则填写"0"。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String currency;// 13-币制-海关标准的参数代码 《JGS-20 海 关业务代码集》- 货币代码。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String note;// 14-备注-freight-N16,2-是-不包含在商品价格中的运杂费,无则填写"0"。
}
注意:如果不使用@Data注解,手动getset,会抛出属性名重复异常,在get方法使用注解
@XmlTransient即可
6.OrderList对象
package com.jiubang.order.domain.xml;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import static com.jiubang.order.domain.xml.NameSpace.NAMESPACE_CEB_URI;
@Data
public class OrderList {
@XmlElement(namespace = NAMESPACE_CEB_URI)
private Integer gnum;// 1-商品序号-gnum-N2-是-从1开始的递增序号。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String itemNo;// 2-企业商品货号-itemNo-C..30-是-电商企业自定义的商品货号(SKU)。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String itemName;// 3-企业商品名称-itemName-C..250-是-交易平台销售商品的中文名称。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String itemDescribe;// 4-企业商品描述-itemDescribe-C..1000-否-交易平台销售商品的描述信息。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String barCode;// 5-条形码-barCode-C..50-否-国际通用的商品条形码,一般由前缀部分、制造厂商代码、商品代码和校验码组成。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String unit;// 6-单位-unit-C3-是-填写海关标准的参数代码,参照《JGS-20 海关业务代码集》- 计量单位代码。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String qty;// 7-数量-qty-N16,2-是-商品实际数量。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String price;// 8-单价-price-N16,2-是-商品单价。赠品单价填写为“0”。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String totalPrice;// 9-总价-totalPrice-N16,2-是-商品总价,等于单价乘以数量。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String currency;// 10-币制-currency-C3-是-限定为人民币,填写“142”。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String country;// 11-原产国-country-C3-是-填写海关标准的参数代码,参照《JGS-20 海关业务代码集》-国家(地区)代码表。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String note;// 12-备注-note-C..1000-否-促销活动,商品单价偏离市场价格的,可以在此说明。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String gcode;// 13-商品编码-gcode-C10-是-按商品分类编码规则确定的进出口商品的商品编号,分为商品编号和附加编号,其中商品编号栏应填报《中华人民共和国进出口税则》8位税则号列,附加编号应填报商品编号,附加编号第9、10位。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String gmodel;// 14-商品规格型号-gmodel-C..250-是-满足海关归类、审价以及监管的要求为准。包括:品牌、规格、型号等。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String qty1;// 15-法定数量-qty1-N19,5-是-按照商品编码规则对应的法定计量单位的实际数量填写。
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String unit1;// 16-法定计量单位-unit1-C3-是-海关标准的参数代码 《JGS-20 海关业务代码集》- 计量单位代码
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String unit2;// 17-第二法定单位-unit2-C3-否-海关标准的参数代码 《JGS-20 海关业务代码集》- 计量单位代码
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String qty2;// 18-第二法定数量-qty2-N19,5-否-
@XmlElement(namespace = NAMESPACE_CEB_URI)
private String gname;// 19-商品名称-gname-C..250-是-商品名称应据实填报,与电子订单一致。
}
7.生成xml与文件的方法对象
@GetMapping(value = "/test")
public void test() {
CEB311Message ceb311Message = new CEB311Message();
ceb311Message.setGuid("556E1CFD-EDED-46B1-946C-B8022E42FC94");
ceb311Message.setVersion("1.0");
Order order = new Order();
OrderHead orderHead = new OrderHead();
orderHead.setGuid("556E1CFD-EDED-46B1-946C-B8022E42FC94");
order.setOrderHead(orderHead);
List<OrderList> orderList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
OrderList orderItem = new OrderList();
orderItem.setCurrency(i + "");
orderItem.setCountry(i + "");
orderList.add(orderItem);
}
order.setOrderList(orderList);
ceb311Message.setOrder(order);
String str = JaxbUtil.convertToXml(ceb311Message);
System.out.println("set send xml success!");
System.out.println(str);
writeXml(str);
}
str为生成的报文xml格式字符串
8.于本地生成xml文件
public void writeXml(String str) {
File file = new File("D:\\123pri\\123.xml");
try (FileOutputStream fop = new FileOutputStream(file)) {
if (!file.exists()) {
file.createNewFile();
}
byte[] bytes = str.getBytes();
fop.write(bytes);
fop.flush();
fop.close();
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
}
}
9.转换工具类
package com.jiubang.order.util;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;
public class JaxbUtil {
/**
* 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();
writer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n "); // 由于不能优雅的去掉 standalone="yes" 所以只能去掉整个头部,然后手动插入一个符合条件的头部 该行为不优雅需要进行升级
marshaller.marshal(obj, writer);
result = writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}