京东物流对接

京东物流对接

之前找资源的时候 在github 上面发现一个大佬封装好的一个SDK

打开即用 可读性非常高

怎么使用:

1.引入依赖:

<dependency>
  <groupId>club.mrxiao</groupId>
  <artifactId>(不同模块参考下文)</artifactId>
  <version>1.0.2</version>
</dependency>
  • 京东物流:express-java-jdl
  • 顺丰物流:express-java-sf

2.将接口文档中的请求参数、url等封装成方法即可

就以下单为例 将请求参数、url 封装成一个请求类即可响应同理

ReceiveOrderInfoRequest:

package com.plz.kd.jdl.bean.order;

import com.plz.kd.jdl.bean.BaseRequest;
import com.plz.kd.jdl.util.json.JdlGsonBuilder;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.ArrayList;
import java.util.List;

/**
 * <pre>
 * 下单接口请求对象
 * </pre>
 */
@Data
@Builder
@EqualsAndHashCode(callSuper = true)
public class ReceiveOrderInfoRequest extends BaseRequest {

    /**
     * 服务域
     */
    private static final String LOP_DN= "express";

    /**
     * code字段
     */
    private static final String CODE_FIELD = "resultCode";

    /**
     * 成功状态码
     */
    private static final Integer SUCCESS_CODE = 100;

    /**
     * API url
     */
    private static final String METHOD = "/WaybillJosService/receiveOrderInfo";


    /**
     * 运单信息对象
     * <pre>
     * 是否必填:是
     * </pre>
     */
    private WaybillDTO waybillDTO;

    /**
     * 获取返回状态码字段
     * @return 返回状态码字段
     */
    @Override
    public String getCodeField() {
        return CODE_FIELD;
    }

    /**
     * 获取成功返回状态码
     * @return 成功返回状态码
     */
    @Override
    public Integer getSuccessCode() {
        return SUCCESS_CODE;
    }

    /**
     * 获取请求json数据
     * @return 请求json数据
     */
    @Override
    public String getJsonParams() {
        List<WaybillDTO> list = new ArrayList<>();
        list.add(this.waybillDTO);
        return JdlGsonBuilder.create().toJson(list);
    }


    /**
     * 获取服务域
     * @return 服务域
     */
    @Override
    public String getLopDn(){
        return LOP_DN;
    }

    /**
     * 获取API url
     * @return API url
     */
    @Override
    public String getMethod(){
        return METHOD;
    }
}

ReceiveOrderInfoResponse:

package com.plz.kd.jdl.bean.order;

import lombok.Data;

/**
 * <pre>
 * 下单接口响应对象
 * </pre>
 */
@Data
public class ReceiveOrderInfoResponse {

    /**
     * 返回码
     */
    private Integer resultCode;

    /**
     * 返回码说明
     */
    private String resultMessage;


    private Boolean needRetry;

    /**
     * 商家订单号(与入参相同)
     */
    private String orderId;

    /**
     * 京东运单号
     */
    private String deliveryId;

    /**
     * 实际时效产品类型(可能与入参不通,以京东实际运力计算结果为准)
     */
    private Integer promiseTimeType;

    /**
     * 错误码(暂未启用)
     */
    private Integer errorCode;

    /**
     * 错误码说明(暂未启用)
     */
    private String errorMessage;

    /**
     * 运输类型 1:陆运 2:航空 不填或者超出范围,默认是1
     */
    private Integer transType;

    private Integer expressOperationMode;

    /**
     * 预分拣结果信息
     */
    private PreSortResult preSortResult;
}

mr-xiaoyu/express-java-tools: 京东物流、顺丰物流api java封装 (github.com)

JdlController:

package com.plz.kd.controller;


import club.mrxiao.common.error.ExpressErrorException;
import com.alibaba.fastjson.JSONObject;
import com.plz.kd.jdl.bean.order.*;
import com.plz.kd.jdl.bean.trace.*;
import com.plz.kd.service.JdlOrderService;
import com.plz.kd.service.JdlService;
import com.plz.kd.service.JdlTraceService;
import com.plz.kd.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RequestMapping("/jdl")
@RestController
public class JdlController {

    @Resource
    private JdlOrderService jdlOrderService;

    @Autowired
    private JdlService jdlService;


    @RequestMapping("/test")
    public R test() {
        return R.ok().put("test", "Test");
    }

    @RequestMapping("/receiveOrder")
    public ReceiveOrderInfoResponse receiveOrder(@RequestBody String json)  {
        WaybillDTO waybillDTO = JSONObject.parseObject(json, WaybillDTO.class);
        ReceiveOrderInfoRequest request = ReceiveOrderInfoRequest.builder().build();
        request.setWaybillDTO(waybillDTO);
        ReceiveOrderInfoResponse response = null;
        try {
            response = jdlOrderService.receiveOrder(request);
            return response;
        } catch (ExpressErrorException e) {
            throw new RuntimeException(e);
        }
    }

    @RequestMapping("/cancelOrder")
    //todo 修改取消订单入参逻辑
    public CancelOrderResponse cancelOrder (@RequestBody String json) {
        CancelWaybillInterceptReq cancel = JSONObject.parseObject(json, CancelWaybillInterceptReq.class);
        cancel.setCancelOperator("happyLiu");
        cancel.setCancelTime(System.currentTimeMillis());
        cancel.setCancelReasonCode(1);
        cancel.setInterceptReason("用户发起取消");
        CancelOrderRequest request = CancelOrderRequest.builder().cancelRequest(cancel).build();
        CancelOrderResponse response = null;
        try {
            response = jdlOrderService.cancelOrder(request);
            return response;
        } catch (ExpressErrorException e) {
            throw new RuntimeException(e);
        }
    }

    @RequestMapping("/queryOrder")
    public QueryTraceResponse queryOrder(@RequestBody String json) {
        //获取京东物流轨迹api接口
        JdlTraceService jdlTraceService = jdlService.getJdlTraceService();
        TraceQueryDTO traceQueryDTO = JSONObject.parseObject(json, TraceQueryDTO.class);
        QueryTraceRequest request = QueryTraceRequest.builder().queryDTO(traceQueryDTO).build();
        QueryTraceResponse response = null;
        try {
            response = jdlTraceService.queryTrace(request);
            return response;
        } catch (ExpressErrorException e) {
            throw new RuntimeException(e);
        }
    }

    // 全程跟踪查询
    @RequestMapping("/queryDynamicTrace")
    public QueryTraceResponse queryDynamicTrace(@RequestBody String json) {
        //获取京东物流轨迹api接口
        JdlTraceService jdlTraceService = jdlService.getJdlTraceService();
        TraceQueryDTO traceQueryDTO = JSONObject.parseObject(json, TraceQueryDTO.class);
        QueryDynamicTraceInfoRequest request = QueryDynamicTraceInfoRequest.builder().queryDTO(traceQueryDTO).build();
        QueryTraceResponse response = null;
        try {
            response = jdlTraceService.queryDynamicTrace(request);
            return response;
        } catch (ExpressErrorException e) {
            throw new RuntimeException(e);
        }
    }
    @RequestMapping("/queryWaybill")
    public QueryWaybillResponse queryWaybill(@RequestBody String json) {
        //查询预估运费
        JdlOrderService jdlOrderService = jdlService.getJdlOrderService();
        QueryWaybill queryWaybill = JSONObject.parseObject(json, QueryWaybill.class);
        QueryWaybillRequest request = QueryWaybillRequest.builder().queryWaybill(queryWaybill).build();
        QueryWaybillResponse response = null;
        try {
            response = jdlOrderService.queryWaybillFreights(request);
            return response;
        } catch (ExpressErrorException e) {
            throw new RuntimeException(e);
        }
    }
    // 查询物流轨迹(给消费者)
    @RequestMapping("/waybill2CTraceByWaybillCode")
    public GetWaybill2cTraceByWaybillCodeResponse Waybill2CTraceByWaybillCode (@RequestBody String json) {
        JdlTraceService jdlTraceService = jdlService.getJdlTraceService();
        Waybill2cTraceDTO waybill2cTraceDTO = JSONObject.parseObject(json, Waybill2cTraceDTO.class);
        GetWaybill2cTraceByWaybillCodeRequest request = GetWaybill2cTraceByWaybillCodeRequest.builder().waybill2cTraceDto(waybill2cTraceDTO).build();
        try {
            GetWaybill2cTraceByWaybillCodeResponse response = jdlTraceService.getWaybill2cTraceByWaybillCode(request);
            return response;
        } catch (ExpressErrorException e) {
            throw new RuntimeException(e);
        }
    }
}

JdlService:

package com.plz.kd.service;


import club.mrxiao.common.error.ExpressErrorException;
import com.plz.kd.jdl.bean.BaseRequest;
import com.plz.kd.jdl.config.JdlConfig;

/**
 * <pre>
 * 京东物流api接口
 * </pre>
 */
public interface JdlService {

    /**
     * 设置配置
     * @param config {@link JdlConfig} 配置
     * @throws ExpressErrorException {@link ExpressErrorException} 异常信息
     */
    void setConfig(JdlConfig config) throws ExpressErrorException;

    /**
     * 获取配置
     * @return {@link JdlConfig} 配置
     */
    JdlConfig getConfig();

    /**
     * 执行请求
     * @param request {@link BaseRequest} 统一请求对象
     * @param <T> 返回对象
     * @param clazz 返回对象
     * @return 请求结果
     * @throws ExpressErrorException {@link ExpressErrorException} 异常信息
     */
    <T> T execute(BaseRequest request, Class<T> clazz) throws ExpressErrorException;

    /**
     * 获取京东物流订单api接口
     * @return 京东订单api接口
     */
    JdlOrderService getJdlOrderService();

    /**
     * 获取京东物流订单轨迹api接口
     * @return 京东订单轨迹api接口
     */
    JdlTraceService getJdlTraceService();

    /**
     * 获取京东物流云打印api接口
     * @return 京东物流云打印api接口
     */
    JdlPrintService getJdlPrintService();
}
JdlServiceImpl:
package com.plz.kd.service.impl;



import club.mrxiao.common.error.ExpressError;
import club.mrxiao.common.error.ExpressErrorException;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpRequest;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.google.gson.JsonObject;
import com.plz.kd.jdl.bean.BaseRequest;
import com.plz.kd.jdl.bean.token.TokenResult;
import com.plz.kd.jdl.config.JdlConfig;
import com.plz.kd.jdl.util.json.JdlGsonBuilder;
import com.plz.kd.service.JdlOrderService;
import com.plz.kd.service.JdlPrintService;
import com.plz.kd.service.JdlService;
import com.plz.kd.service.JdlTraceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import static com.plz.kd.jdl.util.sign.SignUtil.encode;
import static com.plz.kd.utils.MD5.md5;


/**
 * <pre>
 * 京东快递api接口实现
 * </pre>
 */
@Service
public class JdlServiceImpl implements JdlService {

    /**
     * 错误返回
     */
    private static final String ERROR_RESPONSE = "error_response";

    private final Log log = LogFactory.get(this.getClass().getName());


    @Autowired
    private JdlConfig config;
    private JdlOrderService jdlOrderService = new JdlOrderServiceImpl(this);
    private JdlTraceService jdlTraceService = new JdlTraceServiceImpl(this);
    private JdlPrintService jdlPrintService = new JdlPrintServiceImpl(this);


    @Override
    public void setConfig(JdlConfig config) throws ExpressErrorException {
        this.refreshToken(config);
    }

    @Override
    public JdlConfig getConfig() {
        return this.config;
    }

    @Override
    public JdlOrderService getJdlOrderService() {
        return this.jdlOrderService;
    }

    @Override
    public JdlTraceService getJdlTraceService() {
        return this.jdlTraceService;
    }

    @Override
    public JdlPrintService getJdlPrintService() {
        return this.jdlPrintService;
    }

    @Override
    public <T> T execute(BaseRequest request, Class<T> clazz) throws ExpressErrorException {
        try {
            String result = request.build(this.config).execute().body();
            if(StrUtil.isBlank(result)){
                throw new ExpressErrorException(ExpressError.builder().errorCode("9999").errorMsg("无响应内容").build());
            }
            if (result.contains(ERROR_RESPONSE)) {
                throw new ExpressErrorException(ExpressError.builder().json(result).build());
            }
//            this.resultSuccess(request,result);
            log.debug("【result】: {} \n",result);
            return JdlGsonBuilder.create().fromJson(result, clazz);
        }catch (HttpException e){
            throw new ExpressErrorException(ExpressError.builder().errorCode("9999").errorMsg("接口请求发生错误").build(),e);
        }

    }

    private void refreshToken(JdlConfig config) throws ExpressErrorException {

        SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH);
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
        String timestamp = dateFormat.format(new Date());

        String sign = md5(config.getAppSecret() + "app_key" + config.getAppKey() + "refresh_token" + config.getRefreshToken() + "timestamp" + timestamp + config.getAppSecret());

        String url = config.getUrl() +
                "/oauth/refresh_token_ext?LOP-DN=oauth.jdwl.com&app_key=" +
                config.getAppKey() +
                "&refresh_token=" + config.getRefreshToken() +
                "&timestamp=" + encode(timestamp) +
                "&sign=" + sign;
        try {
            String result = HttpRequest.post(url).execute().body();
            if(StrUtil.isBlank(result)){
                throw new ExpressErrorException(ExpressError.builder().errorCode("9999").errorMsg("无响应内容").build());
            }
            if (result.contains(ERROR_RESPONSE)) {
                throw new ExpressErrorException(ExpressError.builder().json(result).build());
            }
            TokenResult r = TokenResult.fromJson(result);
            if(!r.isSuccess()){
                throw new ExpressErrorException(ExpressError.builder()
                        .errorCode(r.getErrCode())
                        .errorMsg(r.getErrMsg())
                        .json(result)
                        .build());
            }
            config.setToken(r.getModel().getAccessToken());
            config.setPin(r.getModel().getSellerId());
            this.config = config;
        }catch (HttpException e){
            throw new ExpressErrorException(ExpressError.builder().errorCode("9999").errorMsg("接口请求发生错误").build(),e);
        }
    }

    private void resultSuccess(BaseRequest request,String result) throws ExpressErrorException {
        JsonObject obj = JdlGsonBuilder.create().fromJson(result, JsonObject.class);
        if(!obj.has(request.getCodeField())){
            throw new ExpressErrorException(ExpressError.builder()
                    .errorCode("9999")
                    .errorMsg("状态码不存在")
                    .json(result)
                    .build());
        }
        Integer code = obj.get(request.getCodeField()).getAsInt();
        if(!request.getSuccessCode().equals(code)){
            throw new ExpressErrorException(ExpressError.builder()
                    .errorCode(String.valueOf(code))
                    .json(result)
                    .build());
        }
    }
}

JdlOrderService:

package com.plz.kd.service;


import club.mrxiao.common.error.ExpressErrorException;
import com.plz.kd.jdl.bean.order.*;

/**
 * <pre>
 * 京东物流订单api接口
 * </pre>
 */
public interface JdlOrderService {

    /**
     * 下单
     * @param request {@link ReceiveOrderInfoRequest} 下单接口请求对象
     * @return {@link ReceiveOrderInfoResponse} 下单接口响应对象
     * @throws ExpressErrorException {@link ExpressErrorException} 异常信息
     */
    ReceiveOrderInfoResponse receiveOrder(ReceiveOrderInfoRequest request) throws ExpressErrorException;

    /**
     * 取消下单
     * @param request {@link CancelOrderRequest} 取消下单请求对象
     * @return {@link CancelOrderResponse} 取消下单响应对象
     * @throws ExpressErrorException {@link ExpressErrorException} 异常信息
     */
    CancelOrderResponse cancelOrder(CancelOrderRequest request) throws ExpressErrorException;

    QueryWaybillResponse queryWaybillFreights(QueryWaybillRequest request) throws ExpressErrorException;

}
JdlOrderServiceImpl:
package com.plz.kd.service.impl;



import club.mrxiao.common.error.ExpressErrorException;
import com.plz.kd.jdl.bean.order.*;
import com.plz.kd.jdl.config.JdlConfig;
import com.plz.kd.service.JdlOrderService;
import com.plz.kd.service.JdlService;
import config.Config;
import jdk.nashorn.internal.ir.annotations.Reference;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/**
 * <pre>
 * 京东订单api接口实现
 * </pre>
 */
@Service
@AllArgsConstructor
public class JdlOrderServiceImpl implements JdlOrderService {

    /**
     * 服务接口
     */
    @Autowired
    private JdlService jdlService;

    @Override
    public ReceiveOrderInfoResponse receiveOrder(ReceiveOrderInfoRequest request) throws ExpressErrorException {
        JdlConfig config = this.jdlService.getConfig();
        request.getWaybillDTO().setJosPin(config.getPin());
        request.getWaybillDTO().setAppKey(config.getAppKey());
        request.getWaybillDTO().setCustomerCode(config.getCustomerCode());
        return this.jdlService.execute(request,ReceiveOrderInfoResponse.class);
    }

    @Override
    public CancelOrderResponse cancelOrder(CancelOrderRequest request) throws ExpressErrorException {
        JdlConfig config = this.jdlService.getConfig();
        request.getCancelRequest().setPin(config.getPin());
        request.getCancelRequest().setVendorCode(config.getCustomerCode());
        return this.jdlService.execute(request, CancelOrderResponse.class);
    }

    @Override
    public QueryWaybillResponse queryWaybillFreights(QueryWaybillRequest request) throws ExpressErrorException {
        JdlConfig config = this.jdlService.getConfig();
        request.getQueryWaybill().setVendorCode(config.getCustomerCode());
        return this.jdlService.execute(request, QueryWaybillResponse.class);
    }
}

JdlConfig:

package com.plz.kd.jdl.config;

import lombok.Data;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

/**
 * <pre>
 * 配置
 * </pre>
 */
@Data
public class JdlConfig {
    /**
     * 生产环境地址
     */
    private static final String PRO_URL = "https://api.jdl.com";

    /**
     * UAT环境地址
     */
    private static final String BOX_URL = "https://uat-api.jdl.com";


    /**
     * 是否生产环境
     */
    private Boolean pro = true;

    /**
     * 京东账号
     */
    private String pin = "";

    /**
     * token 不用配置
     */
    private String token = "";
    

    /**
     * refresh_token
     */
    private String refreshToken = "";

    /**
     * app_key
     */
    private String appKey = "";

    /**
     * app_secret
     */
    private String appSecret = "";

    /**
     * 商家编码
     */
    private String customerCode = "";

    /**
     * 标准模版链接
     */
    private String printTempUrl;

    /**
     * 页面上下偏移量
     */
    private Integer printOffsetTop = 0;

    /**
     * 页面左右偏移量
     */
    private Integer printOffsetLeft = 0;

    /**
     * 版本s
     */
    private String v = "2.0";


    /**
     * 获取api地址
     *
     * @return api地址
     */
    public String getUrl() {
        if (this.pro) {
            return PRO_URL;
        }
        return BOX_URL;
    }
}

以上就是对接京东物流的核心代码了 可以用作其他平台的接口的对接

毫不夸张的讲 写一个新接口只需要 十分钟二十分钟 就可以写好

非常好用! 赞一个

GitHub地址

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值