| | |
| | | |
| | | /** |
| | | * 高德猎鹰服务 |
| | | * key次数用完时自动切换可用key(切换后自动重建serverId) |
| | | */ |
| | | @Component |
| | | public class GDFalconUtil implements ApplicationRunner { |
| | | |
| | | private String key = "ca723c3c8a78962a7751129ae035dc9d"; |
| | | |
| | | @Autowired |
| | | private RestTemplate restTemplate; |
| | | |
| | | @Autowired |
| | | private GDKeyManager gdKeyManager; |
| | | |
| | | private static String serverId = null; |
| | | |
| | | /** |
| | | * 当前serverId对应的key(key切换后需重建serverId) |
| | | */ |
| | | private static volatile String currentKey = null; |
| | | |
| | | |
| | | public String getServerId() { |
| | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 初始化创建服务 |
| | | */ |
| | | public void init(){ |
| | | if(serverId == null){ |
| | | JSONArray jsonArray = this.selectServer(); |
| | | if(null == jsonArray){ |
| | | serverId = this.createServer("server"); |
| | | }else{ |
| | | serverId = jsonArray.getJSONObject(0).getString("sid"); |
| | | if (gdKeyManager == null || restTemplate == null) { |
| | | // 非容器实例(如 GunsApplication.main 中 new 出来的对象),由容器内bean完成初始化 |
| | | return; |
| | | } |
| | | ensureServerId(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 参数构造器:key与sid切换后需按最新值重新构造 |
| | | */ |
| | | private interface ParamsBuilder { |
| | | MultiValueMap<String, Object> build(String key, String sid); |
| | | } |
| | | |
| | | /** |
| | | * 确保serverId与当前使用的key对应: |
| | | * key切换后自动查询/重建serverId;key用完自动切换可用key重试 |
| | | */ |
| | | private synchronized String ensureServerId(){ |
| | | int maxAttempts = 5; |
| | | String lastKey = gdKeyManager.getKey(); |
| | | for (int i = 0; i < maxAttempts; i++) { |
| | | String gdKey = gdKeyManager.getKey(); |
| | | lastKey = gdKey; |
| | | if (serverId != null && gdKey.equals(currentKey)) { |
| | | return gdKey; |
| | | } |
| | | // 1. 查询该key下的服务列表 |
| | | JSONArray jsonArray = null; |
| | | try { |
| | | String url = "https://tsapi.amap.com/v1/track/service/list?key=" + gdKey; |
| | | String forObject = restTemplate.getForObject(url, String.class); |
| | | JSONObject jsonObject = JSON.parseObject(forObject); |
| | | if (GDKeyManager.isFalconExhausted(jsonObject)) { |
| | | gdKeyManager.reportExhausted(gdKey); |
| | | serverId = null; |
| | | continue; |
| | | } |
| | | if (jsonObject.getIntValue("errcode") == 10000) { |
| | | JSONObject data = jsonObject.getJSONObject("data"); |
| | | if (null != data) { |
| | | jsonArray = data.getJSONArray("results"); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | loggerWarn("查询猎鹰服务列表异常", e); |
| | | } |
| | | if (jsonArray != null && jsonArray.size() > 0) { |
| | | serverId = jsonArray.getJSONObject(0).getString("sid"); |
| | | currentKey = gdKey; |
| | | return gdKey; |
| | | } |
| | | // 2. 无服务:创建新服务 |
| | | String sid = createServerInternal("server", gdKey); |
| | | if (sid != null) { |
| | | serverId = sid; |
| | | currentKey = gdKey; |
| | | return gdKey; |
| | | } |
| | | // 3. 创建失败(可能key用完):切换key重试 |
| | | gdKeyManager.reportExhausted(gdKey); |
| | | serverId = null; |
| | | } |
| | | return lastKey; |
| | | } |
| | | |
| | | private void loggerWarn(String msg, Exception e) { |
| | | System.err.println("[GDFalconUtil] " + msg + ":" + e.getMessage()); |
| | | } |
| | | |
| | | /** |
| | | * 执行猎鹰POST表单请求:key次数用完时自动切换key并重建serverId重试 |
| | | */ |
| | | private String doFalconPost(String url, ParamsBuilder builder) { |
| | | String lastResp = null; |
| | | int maxAttempts = 5; |
| | | for (int i = 0; i < maxAttempts; i++) { |
| | | String gdKey = ensureServerId(); |
| | | String sid = serverId; |
| | | MultiValueMap<String, Object> params = builder.build(gdKey, sid); |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); |
| | | HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers); |
| | | String resp = restTemplate.postForObject(url, requestEntity, String.class); |
| | | lastResp = resp; |
| | | JSONObject jsonObject; |
| | | try { |
| | | jsonObject = JSON.parseObject(resp); |
| | | } catch (Exception e) { |
| | | return resp; |
| | | } |
| | | if (GDKeyManager.isFalconExhausted(jsonObject)) { |
| | | gdKeyManager.reportExhausted(gdKey); |
| | | serverId = null; |
| | | continue; |
| | | } |
| | | return resp; |
| | | } |
| | | return lastResp; |
| | | } |
| | | |
| | | /** |
| | | * 执行猎鹰GET请求:key次数用完时自动切换可用key重试 |
| | | */ |
| | | private String doFalconGet(String baseUrl) { |
| | | String lastResp = null; |
| | | int maxAttempts = 5; |
| | | for (int i = 0; i < maxAttempts; i++) { |
| | | String gdKey = gdKeyManager.getKey(); |
| | | String url = baseUrl + (baseUrl.contains("?") ? "&" : "?") + "key=" + gdKey; |
| | | String resp = restTemplate.getForObject(url, String.class); |
| | | lastResp = resp; |
| | | JSONObject jsonObject; |
| | | try { |
| | | jsonObject = JSON.parseObject(resp); |
| | | } catch (Exception e) { |
| | | return resp; |
| | | } |
| | | if (GDKeyManager.isFalconExhausted(jsonObject)) { |
| | | gdKeyManager.reportExhausted(gdKey); |
| | | continue; |
| | | } |
| | | return resp; |
| | | } |
| | | return lastResp; |
| | | } |
| | | |
| | | |
| | |
| | | * @return |
| | | */ |
| | | public String createServer(String name){ |
| | | return createServerInternal(name, gdKeyManager.getKey()); |
| | | } |
| | | |
| | | /** |
| | | * 创建新的服务(内部直连,供ensureServerId使用) |
| | | */ |
| | | private String createServerInternal(String name, String key){ |
| | | String url = "https://tsapi.amap.com/v1/track/service/add"; |
| | | //调用推送 |
| | | HttpHeaders headers = new HttpHeaders(); |
| | |
| | | |
| | | |
| | | /** |
| | | * 查询服务 |
| | | * @return |
| | | */ |
| | | private JSONArray selectServer(){ |
| | | String url = "https://tsapi.amap.com/v1/track/service/list?key=" + key; |
| | | String forObject = restTemplate.getForObject(url, String.class); |
| | | JSONObject jsonObject = JSON.parseObject(forObject); |
| | | if(jsonObject.getIntValue("errcode") == 10000){ |
| | | JSONObject data = jsonObject.getJSONObject("data"); |
| | | if(null != data){ |
| | | return data.getJSONArray("results"); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 创建终端数据 |
| | | * @param name |
| | | * @return |
| | |
| | | if(tid != null){ |
| | | return tid; |
| | | } |
| | | String url = "https://tsapi.amap.com/v1/track/terminal/add"; |
| | | //调用推送 |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | // 以表单的方式提交 |
| | | headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); |
| | | //将请求头部和参数合成一个请求 |
| | | MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(); |
| | | params.add("key", key); |
| | | params.add("sid", serverId); |
| | | params.add("name", name); |
| | | HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers); |
| | | String s = restTemplate.postForObject(url, requestEntity , String.class); |
| | | String s = doFalconPost("https://tsapi.amap.com/v1/track/terminal/add", (key, sid) -> { |
| | | MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(); |
| | | params.add("key", key); |
| | | params.add("sid", sid); |
| | | params.add("name", name); |
| | | return params; |
| | | }); |
| | | JSONObject jsonObject = JSON.parseObject(s); |
| | | if(jsonObject.getIntValue("errcode") == 10000){ |
| | | JSONObject data = jsonObject.getJSONObject("data"); |
| | |
| | | * @return |
| | | */ |
| | | public String selectTerminal(String name){ |
| | | String url = "https://tsapi.amap.com/v1/track/terminal/list?key=" + key + "&name=" + name; |
| | | String forObject = restTemplate.getForObject(url, String.class); |
| | | String forObject = doFalconGet("https://tsapi.amap.com/v1/track/terminal/list?name=" + name); |
| | | JSONObject jsonObject = JSON.parseObject(forObject); |
| | | if(jsonObject.getIntValue("errcode") == 10000){ |
| | | JSONObject data = jsonObject.getJSONObject("data"); |
| | |
| | | * @return |
| | | */ |
| | | public String createTrack(String tid){ |
| | | String url = "https://tsapi.amap.com/v1/track/trace/add"; |
| | | //调用推送 |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | // 以表单的方式提交 |
| | | headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); |
| | | //将请求头部和参数合成一个请求 |
| | | MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(); |
| | | params.add("key", key); |
| | | params.add("sid", serverId); |
| | | params.add("tid", tid); |
| | | HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers); |
| | | String s = restTemplate.postForObject(url, requestEntity , String.class); |
| | | String s = doFalconPost("https://tsapi.amap.com/v1/track/trace/add", (key, sid) -> { |
| | | MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(); |
| | | params.add("key", key); |
| | | params.add("sid", sid); |
| | | params.add("tid", tid); |
| | | return params; |
| | | }); |
| | | JSONObject jsonObject = JSON.parseObject(s); |
| | | if(jsonObject.getIntValue("errcode") == 10000){ |
| | | return jsonObject.getString("data"); |
| | |
| | | * @param trid 轨迹id |
| | | */ |
| | | public void deleteTrack(String tid, String trid){ |
| | | String url = "https://tsapi.amap.com/v1/track/trace/delete"; |
| | | //调用推送 |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | // 以表单的方式提交 |
| | | headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); |
| | | //将请求头部和参数合成一个请求 |
| | | MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(); |
| | | params.add("key", key); |
| | | params.add("sid", serverId); |
| | | params.add("tid", tid); |
| | | params.add("trid", trid); |
| | | HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers); |
| | | String s = restTemplate.postForObject(url, requestEntity , String.class); |
| | | String s = doFalconPost("https://tsapi.amap.com/v1/track/trace/delete", (key, sid) -> { |
| | | MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(); |
| | | params.add("key", key); |
| | | params.add("sid", sid); |
| | | params.add("tid", tid); |
| | | params.add("trid", trid); |
| | | return params; |
| | | }); |
| | | JSONObject jsonObject = JSON.parseObject(s); |
| | | if(jsonObject.getIntValue("errcode") != 10000){ |
| | | System.err.println(jsonObject.getString("errmsg")); |
| | | } |
| | | } |
| | | |
| | | |
| | | // |
| | | // public Map<String, Object> queryTrsearch(){ |
| | | // |
| | | // } |
| | | } |