Java调用淘宝API实现手机号归属地查询

沈知远
沈知远
发布时间:2026-10-14 | 2人浏览过
原创

本文展示如何在Java环境中通过HTTP请求调用淘宝手机归属地API,并利用第三方JSON库解析返回的数据以获取手机号所属省份及城市信息。该方法适用于需要在后端服务中进行手机号格式校验或基础信息补全的场景。

实现原理与准备工作

要实现手机号归属地查询,核心思路是构造特定的HTTP GET请求指向淘宝提供的公开接口,接收返回的JSON字符串,并将其转换为Java对象以便提取关键字段。在此示例中,主要依赖 net.sf.json(即 json-lib 库)来处理JSON数据。

确保项目中引入了以下必要的依赖库:

  • json-lib:用于JSON对象的序列化和反序列化。
  • commons-lang, commons-beanutils, commons-collections, commons-logging:json-lib 运行所需的依赖包。
  • ezmorph:支持基本类型的转换。

单号归属地查询实现

第一步是构建连接并读取数据。我们需要创建一个URL对象,打开输入流,并使用正确的字符集(如GB2312,因为该老版API常使用此编码)读取内容。

第1步:发起网络请求并读取响应

目的:获取原始的JSON字符串数据。

操作入口:定义一个方法 calcMobileCity(String mobileNumber)。

具体动作:

  1. 拼接API地址:http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel= + 手机号码。
  2. 使用 BufferedReader 和 InputStreamReader 读取流,指定编码为 gb2312 以防止乱码。
  3. 将读取的行追加到 StringBuffer 中。

第2步:清洗JSON字符串

目的:适配标准JSON格式以便解析。

说明:淘宝该接口返回的数据并非纯JSON,通常以类似 __GetZoneResult_ = {...}; 的形式包裹。需要去除前缀标识符,只保留内部的JSON部分。

关键代码逻辑:使用正则表达式替换掉开头的变量名部分,并在末尾补上右大括号,使其成为合法的JSON数组结构。

第3步:解析JSON并返回结果

目的:提取具体的归属地信息。

操作:

  1. 使用 JSONArray.fromObject(jsonString2) 将清洗后的字符串转为JSON数组。
  2. 通过 array.getJSONObject(0) 获取第一个元素。
  3. 调用 getString("province") 获取省份名称。同样可获取 city、isp(运营商)等字段。
package com.think.java;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class TestMobileCity {

    /**
     * 测试手机号码是来自哪个城市的,利用淘宝的API
     * @param mobileNumber 手机号码
     * @return 省份名称
     */
    public static String calcMobileCity(String mobileNumber) throws MalformedURLException{
        String jsonString = null;
        JSONArray array = null;
        JSONObject jsonObject = null;
        // 注意:实际生产环境建议配置超时时间或使用HttpClient替代原生URLConnection
        String urlString = "http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=" + mobileNumber;
        StringBuffer sb = new StringBuffer();
        BufferedReader buffer;
        URL url = new URL(urlString);
        try{
            InputStream in = url.openStream();
            
            // 解决乱码问题,部分老接口使用gb2312编码
            buffer = new BufferedReader(new InputStreamReader(in,"gb2312"));
            String line = null;
            while((line = buffer.readLine()) != null){
                sb.append(line);
            }
            in.close();
            buffer.close();
            
            jsonString = sb.toString();
            // 替换掉“__GetZoneResult_ = ”,让它能转换为JSONArray对象
            // 正则表达式去头
            jsonString = jsonString.replaceAll("^[__]\\w{14}+[_ = ]+", "[");
            // 补尾
            String jsonString2 = jsonString + "]";
            
            // 把STRING转化为json对象
            array = JSONArray.fromObject(jsonString2);
            
            // 获取JSONArray的JSONObject对象,便于读取array里的键值对
            jsonObject = array.getJSONObject(0);       
        }catch(Exception e){
            e.printStackTrace();
        }
        return jsonObject.getString("province");
    }

    /**
     * 计算多个号码的归属地
     * @param mobileNumbers 号码列表
     * @return JSON对象,Key为手机号,Value为省份
     */
    public static JSONObject calcMobilesCities(List mobileNumbers) throws MalformedURLException{
        JSONObject jsonNumberCity = new JSONObject();
        for(String mobileNumber : mobileNumbers){
            jsonNumberCity.put(mobileNumber, calcMobileCity(mobileNumber));
        }
        return jsonNumberCity;
    }

    public static void main(String[] args) throws Exception{
        // 单号测试
        String testMobileNumber = "1881758452";
        System.out.println("单号归属地: " + calcMobileCity(testMobileNumber));
        
        // 批量测试示例
        List mobileList = new ArrayList();
        // 生成少量测试号码
        for(int i = 1350345; i < 1350388; i++){
            mobileList.add(String.valueOf(i));
        }
        System.out.println("批量结果: " + calcMobilesCities(mobileList).toString());
    }
}

注意事项与优化建议

上述代码展示了基础实现逻辑,但在实际工程应用中需注意以下几点:

  1. 资源管理:示例中使用的是传统的 try-catch 块关闭流。在现代Java版本中,建议使用 try-with-resources 语法自动关闭 InputStream 和 BufferedReader,防止连接泄漏。
  2. 异常处理:当前代码在捕获异常后仅打印堆栈,未做空值保护。如果API不可用或返回非预期格式,jsonObject 可能为null,直接调用 getString 会抛出空指针异常。应增加判空逻辑。
  3. 并发性能:对于大批量查询(如示例中的循环),同步阻塞式的HTTP请求效率较低。建议引入线程池或使用异步HTTP客户端(如OkHttp、Apache HttpClient Async)来提升吞吐量。
  4. 缓存机制
  5. :同一号段的归属地信息通常是固定的。建议引入本地缓存(如Guava Cache或Redis)来存储查询结果,避免重复请求公共API,提高系统稳定性并降低延迟。

总结

通过以上步骤,我们实现了基于Java和淘宝API的手机归属地查询功能。虽然使用的是较早期的JSON库和原生网络请求方式,但其核心流程——构造URL、读取流、清洗数据、解析JSON——适用于大多数类似的轻量级API集成场景。在实际项目中,请根据安全性、稳定性和性能要求对代码进行现代化重构。

以上就是Java使用淘宝API读写json实现手机归属地查询功能的详细内容,更多关于Java API调用的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表