快递100 查询物流信息 Java

最近项目需要些查询物流信息这个功能,刚开始是一脸懵逼,写什么,怎么写,需要哪些内容。。。?满脑子空白。上网一看各式各样、五花八门的写法,那么多,该选择哪一个呢?

开始之前先知道以下几个问题:

1.需要知道选择哪一家的api  ? 快递100、快递鸟、阿里物流。。。

2.选择使用哪一个快递接口api ?  订阅推送api、实时查询api。。。

3.接口需要哪些入参,入参类型;接口返回值?

选择:选择快递100家的api,订阅推送api。

思路想法:项目的物流信息通过访问快递100api获取物流信息保存到数据库中,当需要查询物流信息的时候,是从数据库里取数据,而不是从快递100那边再获取。

现在已经选择好了,记得在数据库建一张物流信息表:

图1-----订单物流表

现在开始撸代码了:

1.开始订阅物流信息,输入快递单号和快递公司的Code,开始订阅物流信息,当发现有新的物流信息的时候,快递100会通过回调Url返回物流信息,则在回调接口吧物流信息保存到数据库中。下面是conroller

import com.hczt.mall.modules.service.logistics.LogisticsService;
import com.hczt.mall.modules.vo.logistics.NoticeResponse;
import com.hczt.mall.modules.vo.logistics.TaskRequest;
import com.hczt.mall.result.RtnResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

@RestController
@Slf4j
public class LogisticsController {
    @Autowired
    private LogisticsService logisticsService;

    /**
     * 订单订阅物流信息
     *
     * @param req
     * @return
     */
    @PostMapping("/api/logistics/subscrible/{orderId}")
    public RtnResult<Object> subscribleLogistics(@RequestBody TaskRequest req, @PathVariable long orderId) {
        return logisticsService.subscribleLogistics(req, orderId);
    }
}

订阅service层: 请求参数快递单号和快递公司code不能为空。

 public RtnResult<Object> subscribleLogistics(TaskRequest req, long orderId) {
        //回调url
        String url = urlHeader.concat(Constants.LogisticsConstants.CALLBACK_URL_MIDDLE).concat(String.valueOf(orderId));
        req.getParameters().put("callbackurl", url);
        req.setKey(kuaidi100Key);
        Map<String, String> p = new HashMap<String, String>();
        p.put("schema", "json");
        p.put("param", JacksonHelper.toJSON(req));
        log.info("物流信息订阅开始,订单号:【{}】,入参为:【{}】", orderId, p);
        try {
            String ret = HttpRequest.postData("http://www.kuaidi100.com/poll", p, "UTF-8");
            TaskResponse resp = JacksonHelper.fromJSON(ret, TaskResponse.class);
            if (resp.getResult() != true) {
                if (resp.getReturnCode().equals("600") || resp.getReturnCode().equals("601") || resp.getReturnCode().equals("500")) {
                    CodeMsg codeMsg = CodeMsg.SUBSCRIBLE_FAIL;
                    codeMsg = codeMsg.addData(resp.getMessage());
                    log.error("订阅物流信息失败,订单号为:【{}】,失败原因为:【{}】", orderId, resp.getMessage());
                    return RtnResult.error(codeMsg);
                } else {
                    log.error("订阅物流信息失败,订单号为:【{}】,失败原因为:【{}】", orderId, resp.getMessage());
                    return RtnResult.success(resp.getMessage());
                }
            } else {
                //同步订单的快递单号,快递公司code,修改订单状态为已发货
                Optional<Order> orderOptional = orderRepository.findById(orderId);
                if (orderOptional.isPresent()) {
                    Order order = orderOptional.get();
                    order.setOrderLogisticsNo(req.getNumber());
                    order.setExpressCompanyCode(req.getCompany());
                    order.setOrderStatus(Constants.OrderConstants.TradeState.SENDED);
                    orderRepository.save(order);
                }
                log.info("订阅物流信息成功,订单号为:【{}】,物流单号为:【{}】", orderId, req.getNumber());
                return RtnResult.success("success");
            }
        } catch (Exception e) {
            throw new BusinessException("", e);
        }
    }

2.订阅后的回调接口:把物流信息解析直接一整个保存到数据库,当查询的时候在吧数据做解析。

注意:回调结果要有返回值,无论成功或者失败,都要返回result、returnCode、message。

 返回实例:成功一定要有返回值,不然回重发推送。

成功:
//要返回成功(格式与订阅时指定的格式一致),不返回成功就代表失败,没有这个30分钟以后会重推
'{"result":"true",	"returnCode":"200","message":"成功"}';

失败://保存失败,返回失败信息,30分钟以后会重推
 '{"result":"false",	"returnCode":"500","message":"失败"}';
 
controller层:

    /**
     * 快递结果回调接口
     *
     * @param request
     * @return
     */
    @PostMapping("/logistics/callback/{orderId}")
    public NoticeResponse expressCallback(HttpServletRequest request, @PathVariable String orderId) {
        String param = request.getParameter("param");
        log.info("订单物流回调开始,入参为:" + param);
        return logisticsService.updateExpressInfo(param, orderId);
    }

service层:

@Transactional
    public NoticeResponse updateExpressInfo(String param, String orderId) {
        NoticeResponse resp = new NoticeResponse();
        try {
            NoticeRequest nReq = JacksonHelper.fromJSON(param, NoticeRequest.class);
            if (!"abort".equals(nReq.getStatus())) {
                Result result = nReq.getLastResult();
                // 运单号
                String logisticsNo = result.getNu();

                // 快递公司编码
                String expressCompanyCode = result.getCom();

                // 快递单当前签收状态
                String status = result.getState();

                //	是否签收标记
                String isCheck = result.getIscheck();

                String data = JacksonHelper.toJSON(result.getData());

                //根据物流单号获取原来的物流信息,首次记录是返回null
                OrderLogistics oldOrderLogistics = orderLogisticsRepository.findAllByOrderId(Long.valueOf(orderId));

                //根据物流单号删除物流信息,首次记录是返回0
                int changeRows = orderLogisticsRepository.deleteByLogisticsNo(logisticsNo);

                //根据物流单号和订单号查询订单
                Order order = orderRepository.findByOrderIdAndOrderLogisticsNo(Long.valueOf(orderId), logisticsNo);


                ExpressCompanyDict expressCompanyDict = expressCompanyDictRepository.findByExpressCompanyCode(expressCompanyCode);
                // 快递公司名称
                String expressCompanyName = expressCompanyDict.getExpressCompanyName();
                OrderLogistics orderLogistics = new OrderLogistics();
                orderLogistics.setOrderId(Long.valueOf(orderId));
                orderLogistics.setLogisticsNo(logisticsNo);
                orderLogistics.setStatus(status);
                orderLogistics.setExpressCompanyCode(expressCompanyCode);
                orderLogistics.setExpressCompanyName(expressCompanyName);
                orderLogistics.setData(data);
                orderLogistics.setIsCheck(isCheck);
                orderLogisticsRepository.save(orderLogistics);
                log.info("订单物流回调成功,订单物流信息为:【{}】", orderLogistics);
                if (changeRows != 0) {
                    log.info("订单物流回调,旧的物流信息为:【{}】,新的物流信息为:【{}】", oldOrderLogistics, orderLogistics);
                }

                resp.setResult(true);
                resp.setReturnCode("200");
                resp.setMessage("成功");
            }

        } catch (Exception e) {
            resp.setResult(false);
            resp.setReturnCode("500");
            resp.setMessage("保存失败" + e);
            log.error("订单物流回调失败,失败信息为:【{}】", resp);
        }
        return resp;
    }

3.查询物流信息:根据订单号查询物流信息

conroller层:
    @GetMapping("/api/logistics/detail/{orderId}")
    public RtnResult<Object> getLogistics(@PathVariable long orderId) {
        return logisticsService.getLogistics(orderId);
    }

service层:
    public RtnResult<Object> getLogistics(long orderId) {
        OrderLogistics orderLogistics = orderLogisticsRepository.findAllByOrderId(orderId);
        Optional<Order> optionalOrder = orderRepository.findById(orderId);
        if (!optionalOrder.isPresent()) {
            return RtnResult.error(CodeMsg.ORDER_NOT_EXIST);
        }
        Order order = optionalOrder.get();
        if (orderLogistics == null) {
            return RtnResult.error(CodeMsg.LOGISTICS_NOT_EXIST);
        }
    //解析物流信息
        JSONArray obj = JSONArray.parseArray(orderLogistics.getData());
       // int index = 1;
       // for (Object o : obj) {
       //    Map<String, Object> m = (Map) o;
       //    m.put("index", index++);
       // }
        Map<String, Object> map = new HashMap<>();
        map.put("expressCompanyCode", orderLogistics.getExpressCompanyCode());
        map.put("expressCompanyName", orderLogistics.getExpressCompanyName());
        map.put("logisticsNo", orderLogistics.getLogisticsNo());
        map.put("address", order.getAddress());
        map.put("logisticsData", obj);
        map.put("statusCode", orderLogistics.getStatus());
        map.put("statusName", LogisticsStatusEnum.getValueByCode(orderLogistics.getStatus()));
        map.put("isCheck", orderLogistics.getIsCheck());
        map.put("receiveName", order.getReceiverName());
        map.put("receiveTel", order.getReceiverTel());
        return RtnResult.success(map);
    }

postman测试:

图2---返回物流信息
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值