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

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

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 {@Autowiredprivate 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) {//回调urlString 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层:@Transactionalpublic 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());//根据物流单号获取原来的物流信息,首次记录是返回nullOrderLogistics oldOrderLogistics = orderLogisticsRepository.findAllByOrderId(Long.valueOf(orderId));//根据物流单号删除物流信息,首次记录是返回0int 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---返回物流信息

快递100 查询物流信息 Java相关推荐

  1. java 快递100_使用快递100 查询链接实现快速查询的示例

    Express-Query 本工程使用快递100 查询链接实现,仅供学习,禁止商业使用. 工程主要使用的是快递100官方提供的查询api //先查询该单号所属快递商 http://www.kuaidi ...

  2. 快递100快递java_使用快递100 查询链接实现快速查询的示例

    Express-Query 本工程使用快递100 查询链接实现,仅供学习,禁止商业使用. 工程主要使用的是快递100官方提供的查询api //先查询该单号所属快递商 http://www.kuaidi ...

  3. 续集关于上次简单微信小程序制作 (快递100查询)

    上次给大家简单介绍了小程序的实现原理以及传统APP与小程序的对比,这次给大家点干货: 一,移动互联网的八大平台 IOS.Android.H5.BAT.头条.手机厂商 动态App平台阵营(H5.BAT. ...

  4. python爬取物流信息_手把手教你用Python爬取快递100查询你的物流信息

    前言 我们经常会去查快递的物流单号,可是这些物流单号是从哪里来的呢? 快递鸟集合了多家快递公司查询接口,输入相应快递公司编码和快递单号就可以获取到对应的物流信息很方便快捷. 项目目标 教会大家如何用P ...

  5. java对接快递100追踪物流信息

    1.官网地址 快递100API开放平台_快递100快递单号查询API接口_快递100API_快递电子面单接口_寄快递接口 2.从官网下载java示例代码 3.调用 @CrossOrigin@Respo ...

  6. java 查询快递_调用快递100查询快递信息

    [java]代码库/** * 根据快递单号查询数据信息 * @param kuaidiNo * @return */ public static String getExpressInfo(Strin ...

  7. TPShop使用快递100查询订单物流信息

    TPShop的物流信息显示有点问题,每刷新一次则出现不同的物流信息,怀疑是被快递100进行IP限制或者其他原因,于是便注册了快递100个人版,但是还是不行,每次测试都提示不支持该物流,最后找到快递10 ...

  8. 快递100查询接口工具类

    1.快递物流信息是具有实效性,丰网有效期1个月 其它3个月,超过时效性无法查看,需要根据业务情况是否需要保存到数据库中. 2.查询快递物流信息需要填写手机号的快递公司有:顺丰速运("shun ...

  9. 使用免费快递接口查询物流信息

    电商,ERP厂商可能需要物流信息接口,对运单号的物流轨迹进行跟踪,通常有些免费的不好用,及时性要求达不到,收费的也太贵了.最近发现一个免费的API接口,及时性非常高,基本上就是实时返回.需要可以联系Q ...

最新文章

  1. 阿卡迪亚大学的计算机科学,阿卡迪亚大学计算机科学
  2. Sentinel流控规则_QPS直接失败_分布式系统集群限流_线程数隔离_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0033
  3. CS224n自然语言处理(三)——问答系统、字符级模型和自然语言生成
  4. epoll编程实例客户端_深入底层探析网络编程之多路复用器(select,poll,epoll)
  5. js中获取当前项目名等
  6. 同样是断言,为何 Hamcrest 如此优秀?
  7. 海康威视球形摄像头激活,web二次开发
  8. java分页用到的控件,laypage分页控件使用方法
  9. 反冲物料_父母有更多的时间休息,然后反冲开始了
  10. 捏脸是如何实现的?程序化生成3D头像
  11. C++(数据结构与算法):30---散列(哈希)表的介绍(散列函数、散列冲突、散列溢出)
  12. 小猪猪的matlab学习笔记
  13. 消息Hander dispatchfalled; nested excepton is java.ang.NOSuchMethodError: org.springramewrk.utl.tring
  14. K8S部署skywalking
  15. django多对多展示
  16. dropbear:一个小巧的ssh server
  17. Scrum敏捷开发笔记
  18. html frameset边框,frameset框架集(示例代码)
  19. 【随笔】博弈中的模仿策略
  20. 文献阅读之Design and Evaluation of Scalable Intrusion Detection System Using Machine Learning and Apache

热门文章

  1. ARIMA 时间序列模型
  2. E. Physical Education Lessons
  3. 消失的信用卡——反向工程人
  4. html5对各浏览器的支持情况
  5. 拒绝“内卷”跃迁软件测试最大门槛,我是如何从月薪8K到15K的?
  6. 1688API接口,获得商品详情(部分接口展示)
  7. 如何使用GAMS的许可证
  8. 漫画本地化母语翻译、审校、嵌字排版 安睿杰翻译
  9. 医学信息工程考公务员可以报计算机类的吗,医学信息工程专业可以报考公务员吗...
  10. 破2000万,物联网用户规模排名第一的城市