前言:

在Spring Boot中实现快递鸟、顺丰和快递100的物流查询功能通常需要与它们提供的API进行交互。当然使用他们的API 我们是需要申请和注册,从而去拿到 key 来进行调用。所以为注册的必须先进行注册,以下是他们的官网地址,可以快捷到达。

快递鸟官网:快递鸟 - 快递查询接口_免费快递查询api接口 (kdniao.com)

顺丰快递官网:顺丰开放平台 (sf-express.com) 接口名为:物流轨迹查询接口

快递100官网:快递物流接口文档_电子面单接口文档_快递100api接口文档 (kuaidi100.com)

为了实现这一功能,可以创建一个工厂类,用于封装不同快递查询服务的逻辑,并为每个服务创建一个实现类。以下是一个简单的示例,演示如何在Spring Boot中创建这些类和实现快递查询功能。

1. 创建工厂类

首先,创建一个工厂类,该类根据不同的快递服务创建对应的查询实例。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; @Service
public class ExpressServiceFactory { private final Kuaidi100Service kuaidi100Service;
private final KdniaoService kdniaoService;
private final ShunfengService shunfengService; @Autowired
public ExpressServiceFactory(Kuaidi100Service kuaidi100Service, KdniaoService kdniaoService, ShunfengService shunfengService) {
this.kuaidi100Service = kuaidi100Service;
this.kdniaoService = kdniaoService;
this.shunfengService = shunfengService;
} public ExpressService getExpressService(String provider) {
switch (provider) {
case "kuaidi100":
return kuaidi100Service;
case "kdniao":
return kdniaoService;
case "shunfeng":
return shunfengService;
default:
throw new IllegalArgumentException("Invalid provider: " + provider);
}
}
}

2. 创建接口和实现类

接下来,为每个快递服务创建一个接口和实现类,分别实现快递查询的逻辑。以下是示例代码:

快递100 (Kuaidi100)

import org.springframework.stereotype.Service;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Map; @Service
public class Kuaidi100Service implements ExpressService { @Autowired
private RestTemplate restTemplate; @Override
public ExpressInfo queryExpress(String trackingNumber) {
// 调用Kuaidi100的API,查询物流信息
// 以下是伪代码,实际中需要调用Kuaidi100的API并解析返回的数据
String apiUrl = "https://api.kuaidi100.com/query";
String apiKey = "your_api_key"; // 构建请求参数
Map<String, String> params = new HashMap<>();
params.put("com", "your_com_code"); // 快递公司编码
params.put("num", trackingNumber); // 快递单号
params.put("key", apiKey); // API密钥,可以使用@Vaer注解配置在yaml // 发送HTTP请求并获取响应
ResponseEntity<String> response = restTemplate.getForEntity(apiUrl, String.class, params); if (response.getStatusCode() == HttpStatus.OK) {
// 解析返回的JSON数据,构建ExpressInfo对象
String responseBody = response.getBody();
ExpressInfo expressInfo = parseKuaidi100Response(responseBody);
return expressInfo;
} else {
throw new RuntimeException("Failed to query Kuaidi100: " + response.getStatusCode());
}
} private ExpressInfo parseKuaidi100Response(String responseBody) {
// 解析Kuaidi100返回的JSON数据并构建ExpressInfo对象的逻辑
// 以下是示例代码,实际中需要根据API返回的数据结构进行解析
ObjectMapper objectMapper = new ObjectMapper();
try {
Kuaidi100Response kuaidi100Response = objectMapper.readValue(responseBody, Kuaidi100Response.class);
ExpressInfo expressInfo = new ExpressInfo();
expressInfo.setTrackingNumber(kuaidi100Response.getTrackingNumber());
expressInfo.setLogisticsStatus(kuaidi100Response.getLogisticsStatus());
expressInfo.setLogisticsDetail(kuaidi100Response.getLogisticsDetail());
return expressInfo;
} catch (IOException e) {
throw new RuntimeException("Failed to parse Kuaidi100 response", e);
}
}
}

快递鸟 (Kdniao)

import org.springframework.stereotype.Service;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.MultiValueMap; @Service
public class KdniaoService implements ExpressService { @Autowired
private RestTemplate restTemplate; @Override
public ExpressInfo queryExpress(String trackingNumber) {
// 调用快递鸟的API,查询物流信息
// 以下是伪代码,实际中需要调用Kdniao的API并解析返回的数据
String apiUrl = "https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx";
String apiKey = "your_api_key"; // 构建请求参数
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("ShipperCode", "your_shipper_code"); // 快递公司编码
params.add("LogisticCode", trackingNumber); // 快递单号
params.add("RequestType", "1002"); // 查询方式
params.add("apiKey", apiKey); // 发送HTTP请求并获取响应
ResponseEntity<String> response = restTemplate.postForEntity(apiUrl, params, String.class); if (response.getStatusCode() == HttpStatus.OK) {
// 解析返回的XML数据,构建ExpressInfo对象
String responseBody = response.getBody();
ExpressInfo expressInfo = parseKdniaoResponse(responseBody);
return expressInfo;
} else {
throw new RuntimeException("Failed to query Kdniao: " + response.getStatusCode());
}
} private ExpressInfo parseKdniaoResponse(String responseBody) {
// 解析Kdniao返回的XML数据并构建ExpressInfo对象的逻辑
// 以下是示例代码,实际中需要根据API返回的数据结构进行解析
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
Document doc; try {
builder = factory.newDocumentBuilder();
doc = builder.parse(new InputSource(new StringReader(responseBody)));
} catch (Exception e) {
throw new RuntimeException("Failed to parse Kdniao response", e);
} // 解析XML数据并构建ExpressInfo对象
ExpressInfo expressInfo = new ExpressInfo();
// 根据XML结构解析数据并设置到ExpressInfo对象中
return expressInfo;
}
}

顺丰 (Shunfeng)

import org.springframework.stereotype.Service;

@Service
public class ShunfengService implements ExpressService { @Override
public ExpressInfo queryExpress(String trackingNumber) {
// 调用顺丰的API,查询物流信息
// 以下是伪代码,实际中需要调用顺丰的API并解析返回的数据
String apiUrl = "https://api.sf-express.com/std/service";
String apiKey = "your_api_key"; // 构建请求参数
Map<String, Object> params = new HashMap<>();
params.put("tracking_number", trackingNumber);
params.put("api_key", apiKey); // 发送HTTP请求并获取响应
ResponseEntity<String> response = restTemplate.postForEntity(apiUrl, params, String.class); if (response.getStatusCode() == HttpStatus.OK) {
// 解析返回的JSON数据,构建ExpressInfo对象
String responseBody = response.getBody();
// 解析JSON数据并构建ExpressInfo对象
ExpressInfo expressInfo = parseShunfengResponse(responseBody);
return expressInfo;
} else {
throw new RuntimeException("Failed to query Shunfeng: " + response.getStatusCode());
}
} private ExpressInfo parseShunfengResponse(String responseBody) {
// 解析顺丰API响应的JSON数据
try {
// 解析JSON数据,具体字段和格式需要根据顺丰API文档来定义
ObjectMapper objectMapper = new ObjectMapper();
JsonNode root = objectMapper.readTree(responseBody); // 检查响应状态
String status = root.get("status").asText();
if ("OK".equals(status)) {
// 从响应中提取物流信息
JsonNode dataNode = root.get("data");
String trackingNumber = dataNode.get("tracking_number").asText();
String deliveryStatus = dataNode.get("delivery_status").asText();
String lastUpdateTime = dataNode.get("last_update_time").asText(); // 构建ExpressInfo对象
ExpressInfo expressInfo = new ExpressInfo();
expressInfo.setTrackingNumber(trackingNumber);
expressInfo.setDeliveryStatus(deliveryStatus);
expressInfo.setLastUpdateTime(lastUpdateTime); return expressInfo;
} else {
// 响应中包含错误信息
String errorMsg = root.get("message").asText();
throw new RuntimeException("Shunfeng API error: " + errorMsg);
}
} catch (IOException e) {
// 处理解析错误
throw new RuntimeException("Failed to parse Shunfeng API response", e);
}
}
}

3. 创建接口

创建一个通用的快递查询服务接口,以便在工厂类中使用。

public interface ExpressService {

    /**
* 根据快递单号查询快递物流信息
* @param trackingNumber 快递单号
* @return 快递物流信息
*/
ExpressInfo queryExpress(String trackingNumber);
}

4. 使用工厂类查询物流信息

在你的控制器或服务类中,使用工厂类来获取适当的快递查询服务实例,并查询物流信息。

@RestController
public class ExpressController { private final ExpressServiceFactory expressServiceFactory; @Autowired
public ExpressController(ExpressServiceFactory expressServiceFactory) {
this.expressServiceFactory = expressServiceFactory;
} /**
* 根据快递类型和单号查询快递物流信息
* @param provider 快递类型
* @param trackingNumber 快递单号
* @return 快递物流信息
*/
@GetMapping("/query-express")
public ExpressInfo queryExpress(@RequestParam String provider, @RequestParam String trackingNumber) {
ExpressService expressService = expressServiceFactory.getExpressService(provider);
return expressService.queryExpress(trackingNumber);
}
}

到这里代码就写好!!!接下来就可以进行测试或者前端调用接口!!!

如果对你有用就点个赞或者关注一下吧!

springBoot + 工厂模式 实现 快递鸟、顺丰和快递100的物流查询的更多相关文章

  1. 快递鸟顺丰物流api接口对接多种方法整理

    目前很多自营电商平台.ERP系统.仓储系统.快递柜企业,对物流模块数据需求还是比较旺盛的.之前有介绍过简单的接口对接方法,这次给大家整理介绍两种快递数据的获取方法. 接口秘钥可以向顺丰公司申请,或者一 ...

  2. 快递鸟顺丰电子面单接口API-JAVA

    一.电子面单对接案例 1.接口描述 接口支持的消息接收方式:HTTP POST 请求方法的编码格式(utf-8):"application/x-www-form-urlencoded;cha ...

  3. Springboot中实现策略模式+工厂模式

    策略模式和工厂模式相信大家都比较熟悉,但是大家有没有在springboot中实现策略和工厂模式? 具体策略模式和工厂模式的UML我就不给出来了,使用这个这两个模式主要是防止程序中出现大量的IF ELS ...

  4. 在商城系统中使用设计模式----简单工厂模式之在springboot中使用简单工厂模式

    1.前言: 不了解简单工厂模式请先移步:在商城中使用简单工厂.在这里主要是对springboot中使用简单工厂模式进行解析. 2.问题: 什么是简单工厂:它的实现方式是由一个工厂类根据传入的参数,动态 ...

  5. SpringBoot:工厂模式实现定时任务可配置

    pringBoot:工厂模式实现定时任务可配置 需要:使用springboot,实现定时任务可配置. 定时任务可在代码中写死,在配置文件中配置,这些都不能实现定时任务在服务器不重启的情况下可配置. 为 ...

  6. springboot中使用自定义注解实现策略模式,去除工厂模式的switch或ifelse,实现新增策略代码零修改

    前言 思路与模拟业务 源码地址 https://gitee.com/houzheng1216/springboot 整体思路就是通过注解在策略类上指定约定好的type,项目启动之后将所有有注解的typ ...

  7. SpringBoot使用策略模式+工厂模式

    为了防止大量的if...else...或switch case代码的出现,可以使用策略模式+工厂模式进行优化. 在我的项目当中,报表繁多,所以尝试了这种方式进行优化报表的架构.代码很简单,如下: Fa ...

  8. 快递鸟电子面单API对接方法?

    之前说了一下快递公司.菜鸟和快递鸟的电子面单接口,很多人不知道快递鸟要怎么对接,现在为大家讲解一下.快递鸟是全球物流接口服务商,为电商 ERP.电商平台.仓储.清关公司提供物流跟踪.电子面单.智选物流 ...

  9. 电商平台如何接入快递鸟电子面单API?

    快递鸟是全球物流接口服务商,为电商 ERP.电商平台.仓储.清关公司提供物流跟踪.电子面单.智选物流.物流金融.在线下单等服务,解决电商的物流管理模块和金融模块.现就对快递鸟电子面单API做基本描述, ...

  10. JavaScript设计模式--简单工厂模式

    一,介绍 工厂模式创建对象(视为工厂里的产品)时无需指定创建对象的具体类. 工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类.该模式使一个类的实例化延迟到了子类.而子类可以重写接口 ...

随机推荐

  1. 谈谈 Kafka 的幂等性 Producer

    使用消息队列,我们肯定希望不丢消息,也就是消息队列组件,需要保证消息的可靠交付.消息交付的可靠性保障,有以下三种承诺: 最多一次(at most once):消息可能会丢失,但绝不会被重复发送. 至少 ...

  2. Spring Boot 最佳实践

    本文翻译自国外论坛 medium,原文地址:https://medium.com/@raviyasas/spring-boot-best-practices-for-developers-3f3bdf ...

  3. zookeeper运维常用指令

    zkServer.sh ./zkServer.sh start:启动zookeeper ./zkServer.sh stop:停止zookeeper ./zkServer.sh status:查看zo ...

  4. 记一次 .NET某报关系统 非托管泄露分析

    一:背景 1. 讲故事 前段时间有位朋友找到我,说他的程序内存会出现暴涨,让我看下是怎么事情?而且还告诉我是在 Linux 环境下,说实话在Linux上分析.NET程序难度会很大,难度大的原因在于Li ...

  5. 【路由器】OpenWrt 手动编译 ipk

    目录 .ipk 文件 编译准备 编译 .ipk 文件 更新 feeds 配置平台 获取交叉编译链 添加需要编译的第三方软件包 参考资料 .ipk 文件 .ipk 文件是可以通过 OpenWrt 的包管 ...

  6. 《CTFshow-Web入门》07. Web 61~70

    @ 目录 web61~65 题解 web66 题解 原理 web67 题解 原理 web68 题解 原理 web69 题解 原理 web70 题解 原理 ctf - web入门 web61~65 题解 ...

  7. 微信小程序2--WXML与WXSS

    编辑WXML文件 我们在开发者工具里打开之前修改的模板小程序home文件夹下的home.wxml,里面有如下代码 <!--pages/home/home.wxml--> <text& ...

  8. 谈谈JSF业务线程池的大小配置

    1.简介 JSF业务线程池使用JDK的线程池技术,缺省情况下采用Cached模式(核心线程数20,最大线程数200).此外,还提供了Fixed固定线程大小的模式,两种模式均可设置请求队列大小. 本文旨 ...

  9. ES13 中11个令人惊叹的 JavaScript 新特性

    前言 与许多其他编程语言一样,JavaScript 也在不断发展.每年,该语言都会通过新功能变得更加强大,使开发人员能够编写更具表现力和简洁的代码. 小编今天就为大家介绍ES13中添加的最新功能,并查 ...

  10. 利用别名简化进入docker容器数据库的操作

    之前研究docker和数据库的交互,越发对docker这个东西喜爱了.因为平常偶尔会用到各类数据库测试环境验证一些想法,需要进一步简化进入到这些环境的步骤. 比如我现在有三套docker容器数据库测试 ...