ToB企服应用市场:ToB评测及商务社交产业平台

标题: springBoot + 工厂模式 实现 快递鸟、顺丰和快递100的物流查询 [打印本页]

作者: 络腮胡菲菲    时间: 2024-1-11 14:31
标题: springBoot + 工厂模式 实现 快递鸟、顺丰和快递100的物流查询
前言:
在Spring Boot中实现快递鸟、顺丰和快递100的物流查询功能通常需要与它们提供的API进行交互。当然使用他们的API 我们是需要申请和注册,从而去拿到 key 来进行调用。所以为注册的必须先进行注册,以下是他们的官网地址,可以快捷到达。
快递鸟官网:快递鸟 - 快递查询接口_免费快递查询api接口 (kdniao.com)
顺丰快递官网:顺丰开放平台 (sf-express.com)     接口名为:物流轨迹查询接口
快递100官网:快递物流接口文档_电子面单接口文档_快递100api接口文档 (kuaidi100.com)
为了实现这一功能,可以创建一个工厂类,用于封装不同快递查询服务的逻辑,并为每个服务创建一个实现类。以下是一个简单的示例,演示如何在Spring Boot中创建这些类和实现快递查询功能。
1. 创建工厂类

首先,创建一个工厂类,该类根据不同的快递服务创建对应的查询实例。
  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.stereotype.Service;
  3. @Service
  4. public class ExpressServiceFactory {
  5.     private final Kuaidi100Service kuaidi100Service;
  6.     private final KdniaoService kdniaoService;
  7.     private final ShunfengService shunfengService;
  8.     @Autowired
  9.     public ExpressServiceFactory(Kuaidi100Service kuaidi100Service, KdniaoService kdniaoService, ShunfengService shunfengService) {
  10.         this.kuaidi100Service = kuaidi100Service;
  11.         this.kdniaoService = kdniaoService;
  12.         this.shunfengService = shunfengService;
  13.     }
  14.     public ExpressService getExpressService(String provider) {
  15.         switch (provider) {
  16.             case "kuaidi100":
  17.                 return kuaidi100Service;
  18.             case "kdniao":
  19.                 return kdniaoService;
  20.             case "shunfeng":
  21.                 return shunfengService;
  22.             default:
  23.                 throw new IllegalArgumentException("Invalid provider: " + provider);
  24.         }
  25.     }
  26. }
复制代码
2. 创建接口和实现类

接下来,为每个快递服务创建一个接口和实现类,分别实现快递查询的逻辑。以下是示例代码:
快递100 (Kuaidi100)
  1. import org.springframework.stereotype.Service;
  2. import org.springframework.http.ResponseEntity;
  3. import org.springframework.web.client.RestTemplate;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import java.util.Map;
  6. @Service
  7. public class Kuaidi100Service implements ExpressService {
  8.    
  9.     @Autowired
  10.     private RestTemplate restTemplate;
  11.     @Override
  12.     public ExpressInfo queryExpress(String trackingNumber) {
  13.         // 调用Kuaidi100的API,查询物流信息
  14.         // 以下是伪代码,实际中需要调用Kuaidi100的API并解析返回的数据
  15.         String apiUrl = "https://api.kuaidi100.com/query";
  16.         String apiKey = "your_api_key";
  17.         
  18.         // 构建请求参数
  19.         Map<String, String> params = new HashMap<>();
  20.         params.put("com", "your_com_code");  // 快递公司编码
  21.         params.put("num", trackingNumber);   // 快递单号
  22.         params.put("key", apiKey);           // API密钥,可以使用@Vaer注解配置在yaml
  23.         
  24.         // 发送HTTP请求并获取响应
  25.         ResponseEntity<String> response = restTemplate.getForEntity(apiUrl, String.class, params);
  26.         
  27.         if (response.getStatusCode() == HttpStatus.OK) {
  28.             // 解析返回的JSON数据,构建ExpressInfo对象
  29.             String responseBody = response.getBody();
  30.             ExpressInfo expressInfo = parseKuaidi100Response(responseBody);
  31.             return expressInfo;
  32.         } else {
  33.             throw new RuntimeException("Failed to query Kuaidi100: " + response.getStatusCode());
  34.         }
  35.     }
  36.     private ExpressInfo parseKuaidi100Response(String responseBody) {
  37.         // 解析Kuaidi100返回的JSON数据并构建ExpressInfo对象的逻辑
  38.         // 以下是示例代码,实际中需要根据API返回的数据结构进行解析
  39.         ObjectMapper objectMapper = new ObjectMapper();
  40.         try {
  41.             Kuaidi100Response kuaidi100Response = objectMapper.readValue(responseBody, Kuaidi100Response.class);
  42.             ExpressInfo expressInfo = new ExpressInfo();
  43.             expressInfo.setTrackingNumber(kuaidi100Response.getTrackingNumber());
  44.             expressInfo.setLogisticsStatus(kuaidi100Response.getLogisticsStatus());
  45.             expressInfo.setLogisticsDetail(kuaidi100Response.getLogisticsDetail());
  46.             return expressInfo;
  47.         } catch (IOException e) {
  48.             throw new RuntimeException("Failed to parse Kuaidi100 response", e);
  49.         }
  50.     }
  51. }
复制代码
快递鸟 (Kdniao)
  1. import org.springframework.stereotype.Service;
  2. import org.springframework.http.ResponseEntity;
  3. import org.springframework.web.client.RestTemplate;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.util.MultiValueMap;
  6. @Service
  7. public class KdniaoService implements ExpressService {
  8.     @Autowired
  9.     private RestTemplate restTemplate;
  10.     @Override
  11.     public ExpressInfo queryExpress(String trackingNumber) {
  12.         // 调用快递鸟的API,查询物流信息
  13.         // 以下是伪代码,实际中需要调用Kdniao的API并解析返回的数据
  14.         String apiUrl = "https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx";
  15.         String apiKey = "your_api_key";
  16.         // 构建请求参数
  17.         MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
  18.         params.add("ShipperCode", "your_shipper_code");  // 快递公司编码
  19.         params.add("LogisticCode", trackingNumber);       // 快递单号
  20.         params.add("RequestType", "1002");               // 查询方式
  21.         params.add("apiKey", apiKey);
  22.         // 发送HTTP请求并获取响应
  23.         ResponseEntity<String> response = restTemplate.postForEntity(apiUrl, params, String.class);
  24.         if (response.getStatusCode() == HttpStatus.OK) {
  25.             // 解析返回的XML数据,构建ExpressInfo对象
  26.             String responseBody = response.getBody();
  27.             ExpressInfo expressInfo = parseKdniaoResponse(responseBody);
  28.             return expressInfo;
  29.         } else {
  30.             throw new RuntimeException("Failed to query Kdniao: " + response.getStatusCode());
  31.         }
  32.     }
  33.     private ExpressInfo parseKdniaoResponse(String responseBody) {
  34.         // 解析Kdniao返回的XML数据并构建ExpressInfo对象的逻辑
  35.         // 以下是示例代码,实际中需要根据API返回的数据结构进行解析
  36.         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  37.         DocumentBuilder builder;
  38.         Document doc;
  39.         try {
  40.             builder = factory.newDocumentBuilder();
  41.             doc = builder.parse(new InputSource(new StringReader(responseBody)));
  42.         } catch (Exception e) {
  43.             throw new RuntimeException("Failed to parse Kdniao response", e);
  44.         }
  45.         // 解析XML数据并构建ExpressInfo对象
  46.         ExpressInfo expressInfo = new ExpressInfo();
  47.         // 根据XML结构解析数据并设置到ExpressInfo对象中
  48.         return expressInfo;
  49.     }
  50. }
复制代码
顺丰 (Shunfeng)
  1. import org.springframework.stereotype.Service;
  2. @Service
  3. public class ShunfengService implements ExpressService {
  4.     @Override
  5.     public ExpressInfo queryExpress(String trackingNumber) {
  6.         // 调用顺丰的API,查询物流信息
  7.         // 以下是伪代码,实际中需要调用顺丰的API并解析返回的数据
  8.         String apiUrl = "https://api.sf-express.com/std/service";
  9.         String apiKey = "your_api_key";
  10.         
  11.         // 构建请求参数
  12.         Map<String, Object> params = new HashMap<>();
  13.         params.put("tracking_number", trackingNumber);
  14.         params.put("api_key", apiKey);
  15.         
  16.         // 发送HTTP请求并获取响应
  17.         ResponseEntity<String> response = restTemplate.postForEntity(apiUrl, params, String.class);
  18.         
  19.         if (response.getStatusCode() == HttpStatus.OK) {
  20.             // 解析返回的JSON数据,构建ExpressInfo对象
  21.             String responseBody = response.getBody();
  22.             // 解析JSON数据并构建ExpressInfo对象
  23.             ExpressInfo expressInfo = parseShunfengResponse(responseBody);
  24.             return expressInfo;
  25.         } else {
  26.             throw new RuntimeException("Failed to query Shunfeng: " + response.getStatusCode());
  27.         }
  28.     }
  29.     private ExpressInfo parseShunfengResponse(String responseBody) {
  30.         // 解析顺丰API响应的JSON数据
  31.         try {
  32.             // 解析JSON数据,具体字段和格式需要根据顺丰API文档来定义
  33.             ObjectMapper objectMapper = new ObjectMapper();
  34.             JsonNode root = objectMapper.readTree(responseBody);
  35.             // 检查响应状态
  36.             String status = root.get("status").asText();
  37.             if ("OK".equals(status)) {
  38.                 // 从响应中提取物流信息
  39.                 JsonNode dataNode = root.get("data");
  40.                 String trackingNumber = dataNode.get("tracking_number").asText();
  41.                 String deliveryStatus = dataNode.get("delivery_status").asText();
  42.                 String lastUpdateTime = dataNode.get("last_update_time").asText();
  43.                 // 构建ExpressInfo对象
  44.                 ExpressInfo expressInfo = new ExpressInfo();
  45.                 expressInfo.setTrackingNumber(trackingNumber);
  46.                 expressInfo.setDeliveryStatus(deliveryStatus);
  47.                 expressInfo.setLastUpdateTime(lastUpdateTime);
  48.                 return expressInfo;
  49.             } else {
  50.                 // 响应中包含错误信息
  51.                 String errorMsg = root.get("message").asText();
  52.                 throw new RuntimeException("Shunfeng API error: " + errorMsg);
  53.             }
  54.         } catch (IOException e) {
  55.             // 处理解析错误
  56.             throw new RuntimeException("Failed to parse Shunfeng API response", e);
  57.         }
  58.     }
  59. }
复制代码
3. 创建接口

创建一个通用的快递查询服务接口,以便在工厂类中使用。
  1. public interface ExpressService {
  2.     /**
  3.      * 根据快递单号查询快递物流信息
  4.      * @param trackingNumber  快递单号
  5.      * @return 快递物流信息
  6.      */
  7.     ExpressInfo queryExpress(String trackingNumber);
  8. }
复制代码
4. 使用工厂类查询物流信息

在你的控制器或服务类中,使用工厂类来获取适当的快递查询服务实例,并查询物流信息。
  1. @RestController
  2. public class ExpressController {
  3.     private final ExpressServiceFactory expressServiceFactory;
  4.     @Autowired
  5.     public ExpressController(ExpressServiceFactory expressServiceFactory) {
  6.         this.expressServiceFactory = expressServiceFactory;
  7.     }
  8.      /**
  9.      * 根据快递类型和单号查询快递物流信息
  10.      * @param provider 快递类型
  11.      * @param trackingNumber  快递单号
  12.      * @return 快递物流信息
  13.      */
  14.     @GetMapping("/query-express")
  15.     public ExpressInfo queryExpress(@RequestParam String provider, @RequestParam String trackingNumber) {
  16.         ExpressService expressService = expressServiceFactory.getExpressService(provider);
  17.         return expressService.queryExpress(trackingNumber);
  18.     }
  19. }
复制代码
到这里代码就写好!!!接下来就可以进行测试或者前端调用接口!!!
如果对你有用就点个赞或者关注一下吧!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4