苍穹外卖项目中,订单提交需要校验收货地址是否在店铺5公里配送范围内,这一功能依赖百度地图API实现。
网上教程对此部分讲解较简略:AK申请流程不够详细、代码缺少日志导致理解困难,且AK明文配置存在安全隐患。
所以这篇文章的目的是:
详细申请百度地图AK;
完成配送范围校验配置;
添加日志提升代码可读性与调试效率;
使用环境变量安全存储AK,避免泄露。

📚 目录(点击跳转对应章节)


一、百度地图 AK 的详细获取流程

  1. 访问百度地图开放平台官网:https://lbsyun.baidu.com/,在页面右上角登录或注册账号。

    登录/注册入口

  2. 登录成功后,点击“立即接入”按钮进入控制台。

    立即接入按钮

  3. (推荐)完成开发者认证以提升免费额度
    进入控制台后,若未认证会弹出提示。建议选择“个人开发者”进行实名认证(填写姓名、身份证信息,通常即时通过)。

    开发者认证提示

  4. 创建应用获取 AK
    在左侧菜单点击 应用管理我的应用创建应用

    创建应用按钮

  5. 填写应用信息(关键配置如下)

    • 应用名称:随意
    • 应用类型:选择 服务器端(适用于苍穹外卖项目)
    • IP 白名单:开发阶段建议填写 0.0.0.0/0(便于本地调试,上线后请限制为服务器真实 IP)

    应用信息填写
    IP 白名单设置

  6. 创建完成后,复制生成的 AK 并妥善保存。

二、在苍穹外卖项目中配置百度地图

  1. 在配置文件中添加店铺地址和百度地图 AK:

    配置文件添加示例

  2. OrderServiceImpl 中注入配置:

    @Value("${sky.shop.address}")
    private String shopAddress;
    
    @Value("${sky.baidu.ak}")
    private String ak;
    
  3. 实现配送范围校验方法 checkOutOfRange(完整代码如下):

    /**
     * 检查客户的收货地址是否超出配送范围
     * @param address 用户收货地址
     */
    private void checkOutOfRange(String address) {
        Map<String, String> map = new HashMap<>();
        map.put("address", shopAddress);
        map.put("output", "json");
        map.put("ak", ak);
    
        // 获取店铺经纬度坐标
        String shopCoordinate = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", map);
        JSONObject jsonObject = JSON.parseObject(shopCoordinate);
        if (!"0".equals(jsonObject.getString("status"))) {
            throw new OrderBusinessException("店铺地址解析失败");
        }
    
        JSONObject location = jsonObject.getJSONObject("result").getJSONObject("location");
        String shopLngLat = location.getString("lat") + "," + location.getString("lng");
    
        // 获取用户收货地址经纬度坐标
        map.put("address", address);
        String userCoordinate = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", map);
        jsonObject = JSON.parseObject(userCoordinate);
        if (!"0".equals(jsonObject.getString("status"))) {
            throw new OrderBusinessException("收货地址解析失败");
        }
    
        location = jsonObject.getJSONObject("result").getJSONObject("location");
        String userLngLat = location.getString("lat") + "," + location.getString("lng");
    
        // 路线规划参数
        map.put("origin", shopLngLat);
        map.put("destination", userLngLat);
        map.put("steps_info", "0");
    
        String json = HttpClientUtil.doGet("https://api.map.baidu.com/directionlite/v1/driving", map);
        jsonObject = JSON.parseObject(json);
        if (!"0".equals(jsonObject.getString("status"))) {
            throw new OrderBusinessException("配送路线规划失败");
        }
    
        JSONObject result = jsonObject.getJSONObject("result");
        JSONArray routes = result.getJSONArray("routes");
        Integer distance = ((JSONObject) routes.get(0)).getInteger("distance");
    
        if (distance > 5000) {
            throw new OrderBusinessException("超出配送范围");
        }
    }
    
  4. submitOrder 方法中调用该校验方法:

    调用校验方法

三、优化黑马项目中的百度地图配置及提升代码可读性

1. 通过添加日志提升代码可读性和调试效率

原代码逻辑较为紧凑,不便于理解和排查问题。推荐在 checkOutOfRange 方法中加入详细日志,便于观察每一步的执行情况:

/**
 * 判断当前地址是否超出配送范围
 * @param address 用户地址
 */
private void checkOutOfRange(String address) {
    log.info("开始检查配送范围,店铺地址: {}, 用户地址: {}", shopAddress, address);

    Map<String, String> map = new HashMap<>();
    map.put("address", shopAddress);
    map.put("output", "json");
    map.put("ak", ak);
    log.info("请求店铺坐标参数: address={}, ak={}", shopAddress, ak);

    String shopCoordinate = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", map);
    log.info("店铺坐标解析结果: {}", shopCoordinate);

    JSONObject jsonObject = JSON.parseObject(shopCoordinate);
    if (!"0".equals(jsonObject.getString("status"))) {
        log.error("店铺地址解析失败,状态码: {}, 错误信息: {}", jsonObject.getString("status"), jsonObject.getString("message"));
        throw new OrderBusinessException("店铺地址解析失败");
    }

    JSONObject location = jsonObject.getJSONObject("result").getJSONObject("location");
    String shopLngLat = location.getString("lat") + "," + location.getString("lng");
    log.info("店铺坐标 (纬度,经度): {}", shopLngLat);

    map.put("address", address);
    String userCoordinate = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", map);
    log.info("用户坐标解析结果: {}", userCoordinate);

    jsonObject = JSON.parseObject(userCoordinate);
    if (!"0".equals(jsonObject.getString("status"))) {
        log.error("用户地址解析失败,状态码: {}, 错误信息: {}", jsonObject.getString("status"), jsonObject.getString("message"));
        throw new OrderBusinessException("收货地址解析失败");
    }

    location = jsonObject.getJSONObject("result").getJSONObject("location");
    String userLngLat = location.getString("lat") + "," + location.getString("lng");
    log.info("用户坐标 (纬度,经度): {}", userLngLat);

    map.put("origin", shopLngLat);
    map.put("destination", userLngLat);
    map.put("steps_info", "0");

    String driving = HttpClientUtil.doGet("https://api.map.baidu.com/directionlite/v1/driving", map);
    log.info("路线规划结果: {}", driving);

    jsonObject = JSON.parseObject(driving);
    if (!"0".equals(jsonObject.getString("status"))) {
        log.error("路线规划失败,状态码: {}, 错误信息: {}", jsonObject.getString("status"), jsonObject.getString("message"));
        throw new OrderBusinessException("配送路线规划失败");
    }

    JSONObject result = jsonObject.getJSONObject("result");
    JSONArray routes = result.getJSONArray("routes");
    Integer distance = ((JSONObject) routes.get(0)).getInteger("distance");
    log.info("配送距离: {} 米", distance);

    if (distance > 5000) {
        throw new OrderBusinessException("超出配送范围");
    }
}

好处:每一步的关键参数和返回结果都会打印到日志中,大大方便调试和学习理解。

2. 使用环境变量存储 AK,避免明文泄露

2.1 设置系统环境变量(需以管理员身份运行命令提示符)
# 设置永久环境变量
setx BAIDU_MAP_AK "你的百度地图AK" /M

# 验证是否成功
echo %BAIDU_MAP_AK%
2.2 修改配置文件

application.ymlapplication-dev.yml 中的 AK 配置改为:

sky:
  baidu:
    ak: ${BAIDU_MAP_AK}

application.yml 修改
application-dev.yml 修改

好处:AK 不再硬编码在配置文件中,避免误提交到代码仓库导致泄露;生产环境也可统一通过服务器环境变量管理。

四、总结

经过如上修改我们完成了:

  • 百度地图 AK 的申请与安全获取;
  • 在苍穹外卖项目中实现基于百度地图的配送范围校验;
  • 通过详细日志提升代码可读性和调试效率;
  • 使用环境变量安全存储 AK,杜绝明文泄露风险。
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐