前言:
在Spring Boot中实现快递鸟、顺丰和快递100的物流查询功能通常需要与它们提供的API进行交互。当然使用他们的API 我们是需要申请和注册,从而去拿到 key 来进行调用。所以为注册的必须先进行注册,以下是他们的官网地址,可以快捷到达。
快递鸟官网:快递鸟 - 快递查询接口_免费快递查询api接口 (kdniao.com)
顺丰快递官网:顺丰开放平台 (sf-express.com) 接口名为:物流轨迹查询接口
快递100官网:快递物流接口文档_电子面单接口文档_快递100api接口文档 (kuaidi100.com)
为了实现这一功能,可以创建一个工厂类,用于封装不同快递查询服务的逻辑,并为每个服务创建一个实现类。以下是一个简单的示例,演示如何在Spring Boot中创建这些类和实现快递查询功能。
首先,创建一个工厂类,该类根据不同的快递服务创建对应的查询实例。
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); } } }
接下来,为每个快递服务创建一个接口和实现类,分别实现快递查询的逻辑。以下是示例代码:
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); } } }
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; } }
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); } } }
创建一个通用的快递查询服务接口,以便在工厂类中使用。
public interface ExpressService { /** * 根据快递单号查询快递物流信息 * @param trackingNumber 快递单号 * @return 快递物流信息 */ ExpressInfo queryExpress(String trackingNumber); }
在你的控制器或服务类中,使用工厂类来获取适当的快递查询服务实例,并查询物流信息。
@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); } }
到这里代码就写好!!!接下来就可以进行测试或者前端调用接口!!!
如果对你有用就点个赞或者关注一下吧!