苍穹外卖-DAY09
苍穹外卖-DAY09
百度地图
1
https://lbsyun.baidu.com/apiconsole/key
用来检测地址是否超过配送距离
检验方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/**
* 检查客户的收货地址是否超出配送范围
*/
private void checkOutOfRange(String address) throws UnsupportedEncodingException {
// --- 第一步:获取店铺经纬度 ---
Map<String, String> shopMap = new LinkedHashMap<>();
shopMap.put("address", shopAddress);
shopMap.put("output", "json");
shopMap.put("ak", ak);
// 【新增】必须添加 timestamp 参数,值为当前时间戳(毫秒)
shopMap.put("timestamp", String.valueOf(System.currentTimeMillis()));
// 计算SN并加入参数
String shopSn = generateSn("/geocoding/v3", shopMap);
shopMap.put("sn", shopSn);
String shopCoordinate = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", shopMap);
JSONObject shopJson = JSON.parseObject(shopCoordinate);
if (!"0".equals(shopJson.getString("status"))) {
throw new OrderBusinessException("店铺地址解析失败: " + shopJson.getString("message"));
}
JSONObject shopLocation = shopJson.getJSONObject("result").getJSONObject("location");
String shopLngLat = shopLocation.getString("lat") + "," + shopLocation.getString("lng");
// --- 第二步:获取用户收货地址经纬度 ---
Map<String, String> userMap = new LinkedHashMap<>();
userMap.put("address", address);
userMap.put("output", "json");
userMap.put("ak", ak);
// 【新增】必须添加 timestamp 参数
userMap.put("timestamp", String.valueOf(System.currentTimeMillis()));
// 计算SN并加入参数
String userSn = generateSn("/geocoding/v3", userMap);
userMap.put("sn", userSn);
String userCoordinate = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", userMap);
JSONObject userJson = JSON.parseObject(userCoordinate);
if (!"0".equals(userJson.getString("status"))) {
throw new OrderBusinessException("收货地址解析失败: " + userJson.getString("message"));
}
JSONObject userLocation = userJson.getJSONObject("result").getJSONObject("location");
String userLngLat = userLocation.getString("lat") + "," + userLocation.getString("lng");
// --- 第三步:路线规划 (驾车) ---
Map<String, String> driveMap = new LinkedHashMap<>();
driveMap.put("origin", shopLngLat);
driveMap.put("destination", userLngLat);
driveMap.put("steps_info", "0");
driveMap.put("ak", ak);
// 【新增】必须添加 timestamp 参数
driveMap.put("timestamp", String.valueOf(System.currentTimeMillis()));
// 计算SN并加入参数 (注意URI变成了 directionlite/v1/driving)
String driveSn = generateSn("/directionlite/v1/driving", driveMap);
driveMap.put("sn", driveSn);
String driveJsonStr = HttpClientUtil.doGet("https://api.map.baidu.com/directionlite/v1/driving", driveMap);
JSONObject driveJson = JSON.parseObject(driveJsonStr);
if (!"0".equals(driveJson.getString("status"))) {
throw new OrderBusinessException("配送路线规划失败: " + driveJson.getString("message"));
}
JSONObject result = driveJson.getJSONObject("result");
JSONArray jsonArray = result.getJSONArray("routes");
Integer distance = jsonArray.getJSONObject(0).getInteger("distance");
if (distance > 5000) {
throw new OrderBusinessException("超出配送范围");
}
}
/**
* 核心算法:生成SN签名
* 基于百度地图官方Java Demo改编
*
* @param uri 接口的URI,例如 /geocoding/v3
* @param data 已经put好参数的LinkedHashMap
* @return 计算后的sn字符串
*/
private String generateSn(String uri, Map<String, String> data) throws UnsupportedEncodingException {
try {
// 1. 将Map参数转换为UrlEncoded的查询字符串
StringBuilder queryString = new StringBuilder();
for (Map.Entry<String, String> pair : data.entrySet()) {
queryString.append(pair.getKey()).append("=");
//以此处为例,Value必须进行UTF-8编码
queryString.append(URLEncoder.encode(pair.getValue(), "UTF-8")).append("&");
}
if (queryString.length() > 0) {
queryString.deleteCharAt(queryString.length() - 1);
}
// 2. 拼接:URI + ? + QueryString + SK
String wholeStr = uri + "?" + queryString.toString() + sk;
// 3. 对整个拼接后的字符串再次进行URLEncode (这一步非常关键,官方文档强调的)
String tempStr = URLEncoder.encode(wholeStr, "UTF-8");
// 4. MD5加密
return MD5(tempStr);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
/**
* MD5计算辅助方法
*/
private String MD5(String md5) {
try {
java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
byte[] array = md.digest(md5.getBytes());
StringBuilder sb = new StringBuilder();
for (int i = 0; i < array.length; ++i) {
sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
}总体代码如上

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 十七.!