快递100和聚合数据最可行:前者文档清晰、参数校验严格;后者支持小众快递但需apikey;均需清洗单号、设正确header及json解析容错。

用哪个物流查询接口最省事
国内能直接调用、无需企业资质、有免费额度的,快递100 和 聚合数据 是目前最可行的选择。前者文档清晰、返回结构统一;后者需申请 APIKey,但支持更多小众快递公司。
别碰那些“免密调用”的第三方中转接口——它们常把 403 或 502 错误包装成“查不到”,实际是上游限流或失效了,排查起来反而更费时间。
-
快递100的subscribe接口必须传真实手机号(即使只查单号),否则返回{"result":false,"returnCode":"500","message":"参数错误"} - 聚合数据的
express_query接口要求com字段必须是它文档里列出的快递编码(比如sf不能写成shunfeng),填错就直接返回空数组 - 所有接口都要求单号为纯字母数字组合,带空格或中文括号(如 “SF123456789 CN”)会查不到,得先用
replaceAll("[^a-zA-Z0-9]", "")清洗
Java里怎么发请求不被拦截
用 HttpURLConnection 或 OkHttpClient 都可以,但必须设好基础头,否则部分接口直接拒绝响应。重点不是“能不能发出去”,而是“对方认不认你是正常客户端”。
- 至少带上
User-Agent,值设为"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",有些接口会校验这个字段长度和格式 - 快递100 要求
Content-Type: application/x-www-form-urlencoded,如果用application/json就返回{"result":false,"returnCode":"400"} - 别用
RestTemplate默认配置直连——它默认不处理 302 重定向,而某些测试环境会跳转,导致你拿到的是 HTML 登录页而不是 JSON
解析返回 JSON 容易漏掉的关键字段
物流接口返回的 JSON 看似结构固定,但实际存在大量“可选字段”:比如 data 数组可能为空、status 字段在不同接口含义不同、甚至同一接口在不同快递公司下字段名不一致(time vs ftime)。
立即学习“Java免费学习笔记(深入)”;
- 快递100 的
data是数组,但没物流信息时是空数组[],不是null,用ObjectMapper反序列化要配DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT否则报错 - 聚合数据返回的
result是对象,但里面list字段可能是null,也可能是空数组,判空得写成list != null && !list.isEmpty() - 别直接取
data.get(0).getTime()—— 第一条记录不一定是最新状态,要看time字段排序,或者依赖接口返回的state字段(0=已签收,1=派件中,2=运输中,3=已揽收)
本地调试时怎么绕过跨域和频率限制
开发阶段反复调用真接口,很快触发 IP 限流(快递100 免费版 100 次/天,聚合数据 20 次/小时),建议用本地 mock 响应代替。
- 写个简易
MockServer类,监听本地8081端口,对匹配/api/query的请求直接返回预存的 JSON 文件(比如sf_success.json),避免每次改代码都要等接口响应 - 用
WireMock更稳:启动后加一行stubFor(post("/v1/query").willReturn(aResponse().withBodyFile("mock_response.json"))),比手写 HTTP server 少踩 3 个编码和 header 的坑 - 别在
application.properties里硬编码接口地址——抽成spring.profiles.active=dev+logistics.api.url=http://localhost:8081,上线前切 profile 即可,不用改代码
真正麻烦的从来不是“怎么调通”,而是“怎么让失败情况有明确反馈”:比如单号格式错、快递公司识别失败、网络超时、接口返回异常码——这些分支每少处理一个,上线后日志里就多一类无法归因的“查不到”投诉。










