因公司自研系统要求, 有一个天猫供货商店铺需要获取发送过来的订单通知信息
官方接口:
qimen.alibaba.ascp.uop.consignorder.notify( 普通销售订单发货通知 )
地址:https://open.taobao.com/api.htm?spm=a219a.7386797.0.0.454b669aP0E5qm&source=search&docId=49308&docType=2
此接口会有官方工作人员组建工作群完成对接。
因为没有对接过奇门,下面记录一下对接后的过程, 避免二次类似对接因为经验问题导致过程不顺利。
刚开始对接本人是没有参与进去, 只是店铺的员工和官方工作人员在处理入驻等流程,然后是开发部门同事进入对接, 并发送给我一个API接口文档 ,当看见官方接口的时候, 第一时间想的是发送数据到奇门接口,但是看见API标题上有一个通知 ,那应该是一个接收接口,询问工作人员后确定这点 ,然后已接收奇门消息的接口,并返回设计 ,这次就是一波三折 。
第一次接口已json格式接收数据设计,为什么这么设计是因为官方人员在工作群中发过一个报文,非常明确的是json格式。
然后当接口完成。测试接口录入数据的时候,意外出现了。
工作人员提供的json报文里面的数据与官方API里面描述的数据不一致 ,这就尴尬了 ,因为是已他提供的测试json数据来设计的 , 于是就请教了工作人员。
官方人员给出的说法是已官方API的为主, 没有办法,只好修改本地数据结构, 这个改动不是很大,还可以接受。
于是继续往下对接,本地已经ok 接口测试也已经通过 ,可以开始联调工作了 ,当第一次联调的时候,就出现了问题。
后端报错, 报错原因是这个接口接收的数据类型不匹配 ,显示接收的是XML类型数据 。。。。然后询问工作人员, 他说是呀 ,奇门都是xml类型的。那之前发的json数据是给其他人看的吗, 是给别人测试用的呗 ,感到非常的老火,也为自己的经验不足感到无力 。 哎,没有办法, 只好继续改造接口来接收XML类型数据 。
这时候需要解决一个问题, 接口适配XML格式 ,网上通常有两种方法, 一种是按流来读, 但是整体比较麻烦, 针对数据处理复杂度也较高。另一种也是我这使用的一种,引入jackson-dataformat-xml 的jar包。
这种方法相对而言非常简洁 ,通过注解的方式,让接收到XML数据后自动映射成实体对象,例子在网上有很多, 我就简单贴一点。
/**
* 普通销售订单发货对象 platform_qimen_order_notify
*
* @date 2021-09-03
*/
@JacksonXmlRootElement(localName ="request")
public class PlatformQimenOrderNotify extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 物流订单信息主键 */
@JacksonXmlProperty(localName = "orderId")
private Long orderId;
/** 供应商id */
@JacksonXmlProperty(localName = "supplierId")
private String supplierId;
/** 供应商名称 */
@Excel(name = "供应商名称")
@JacksonXmlProperty(localName = "supplierName")
private String supplierName;
/** 平台来源[201 淘宝] */
@Excel(name = "平台来源[201 淘宝]")
@JacksonXmlProperty(localName = "orderSource")
private String orderSource;
/** 履约单号 */
@Excel(name = "履约单号")
@JacksonXmlProperty(localName = "bizOrderCode")
private String bizOrderCode;
/** 配送公司名称 */
@Excel(name = "配送公司名称")
@JacksonXmlProperty(localName = "tmsServiceName")
private String tmsServiceName;
/** 运费模式 */
@Excel(name = "运费模式")
@JacksonXmlProperty(localName = "postMode")
private String postMode;
/** 运费金额(单位分) */
@Excel(name = "运费金额(单位分)")
@JacksonXmlProperty(localName = "postFee")
private Long postFee;
/** 履约创单时间(yyyy-mm-dd HH:mm:ss) */
@Excel(name = "履约创单时间(yyyy-mm-dd HH:mm:ss)")
@JacksonXmlProperty(localName = "orderCreateTime")
private String orderCreateTime;
/** 扩展属性 */
@Excel(name = "扩展属性")
@JacksonXmlProperty(localName = "extraContent")
private String extraContent;
/** 交易金额,单位:分 */
@Excel(name = "交易金额,单位:分")
@JacksonXmlProperty(localName = "itemsValue")
private Long itemsValue;
/** 考拉交易单号 */
@Excel(name = "考拉交易单号")
@JacksonXmlProperty(localName = "klTradeId")
private String klTradeId;
/** 买家留言 */
@Excel(name = "买家留言")
@JacksonXmlProperty(localName = "buyerMessage")
private String buyerMessage;
/** 店铺Id */
@JacksonXmlProperty(localName = "sellerId")
private String sellerId;
/** 店铺名称 */
@Excel(name = "店铺名称")
@JacksonXmlProperty(localName = "sellerNick")
private String sellerNick;
/** 交易类型,当值为10000时,是预售订单 */
@Excel(name = "交易类型,当值为10000时,是预售订单")
@JacksonXmlProperty(localName = "bizType")
private String bizType;
/** 发货仓编码 */
@Excel(name = "发货仓编码")
@JacksonXmlProperty(localName = "storeCode")
private String storeCode;
/** 发货仓名称 */
@Excel(name = "发货仓名称")
@JacksonXmlProperty(localName = "storeName")
private String storeName;
/** 发件人信息管理对象 */
@JacksonXmlProperty(localName = "senderInfo")
private PlatformQimenOrderSenderinfo senderInfo;
/** 物流服务信息管理对象List */
@JacksonXmlProperty(localName = "deliverRequirement")
private PlatformQimenOrderDeliverRequirement deliverRequirement;
/** 履约单子单列对象 */
// @JacksonXmlProperty(localName = "orderItems")
// private PlatformQimenOrderItems orderItems;
@JacksonXmlElementWrapper(localName = "orderItems")
private List<PlatformQimenOrderItem> orderItems;
/** 收件方信息管理对象 */
@JacksonXmlProperty(localName = "receiverInfo")
private PlatformQimenOrderReceiverinfo receiverInfo;
// 生成的get与set方法
..........................
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("orderId", getOrderId())
.append("supplierId", getSupplierId())
.append("supplierName", getSupplierName())
.append("orderSource", getOrderSource())
.append("bizOrderCode", getBizOrderCode())
.append("tmsServiceName", getTmsServiceName())
.append("postMode", getPostMode())
.append("postFee", getPostFee())
.append("orderCreateTime", getOrderCreateTime())
.append("extraContent", getExtraContent())
.append("itemsValue", getItemsValue())
.append("klTradeId", getKlTradeId())
.append("buyerMessage", getBuyerMessage())
.append("sellerId", getSellerId())
.append("sellerNick", getSellerNick())
.append("bizType", getBizType())
.append("storeCode", getStoreCode())
.append("storeName", getStoreName())
.toString();
}
}
注解说明
@JacksonXmlRootElement用于类名,是xml最外层的根节点。注解中有localName属性,该属性如果不设置,那么生成的XML最外面就是Clazz.
@JacksonXmlCData注解是为了生成<![CDATA[text]]>
@JacksonXmlProperty注解通常可以不需要,若不用,生成xml标签名称就是实体类属性名称。但是如果你想要你的xml节点名字,首字母大写。比如例子中的Content,那么必须加这个注解,并且注解的localName填上你想要的节点名字。最重要的是!实体类原来的属性content必须首字母小写!否则会被识别成两个不同的属性。注解的isAttribute,确认是否为节点的属性,如上面“gradeId”。
@JacksonXmlElementWrapper一般用于list,list外层的标签。若不用的话,useWrapping =false
@JacksonXmlText,用实体类属性上,说明该属性是否为简单内容,如果是,那么生成xml时,不会生成对应标签名称
@JsonIgnore,忽略该实体类的属性,该注解是用于实体类转json的,但用于转xml一样有效,具体原因个人推测是XmlMapper是ObjectMapper的子类。
然后接口改造完毕, 本通过postmen工具测试了。可以正常接收XML格式的请求数据 ,于是开始再次联调,然后意外居然又又又出现了 。
官方人员回复联调还是失败, 一直在报错。
我断点观察了一下后台报错信息,发现是因为请求头Headers中传入的类型为Content-Type : text/xml , 而我本地是 application/xml。。。。。。。没有办法, 继续修改自己接口吧。
@PostMapping(value ="/NotifyMessage",consumes = { MediaType.TEXT_XML_VALUE }, produces = MediaType.TEXT_XML_VALUE)
只需要把@PostMapping中属性从application/xml 修改为text/xml就行, 然后再次联调, 总算这阶段联调成功 ,进入下阶段。