package com.ruoyi.app.map; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.common.core.domain.entity.SysDictData; import com.ruoyi.common.utils.DictUtils; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.utils.URIBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.springframework.stereotype.Component; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; import java.util.Set; /** Google 地址接口固定主机与路径;参数编码后发送,不跟随第三方重定向。 */ @Component public class GoogleMapLocationClient { private static final Set PATHS = Set.of("/maps/api/place/textsearch/json", "/maps/api/place/nearbysearch/json", "/maps/api/geocode/json", "/maps/api/place/details/json"); private static final RequestConfig TIMEOUTS = RequestConfig.custom().setConnectTimeout(2500) .setConnectionRequestTimeout(2500).setSocketTimeout(3500).build(); public JSONObject getObject(String path, Map query) { List keys = DictUtils.getDictCache("sys_googlemap_key"); if (keys == null || keys.isEmpty() || keys.get(0).getDictValue() == null || keys.get(0).getDictValue().isBlank()) { throw new IllegalStateException("google map key unavailable"); } HttpGet request = new HttpGet(requestUri(path, query, keys.get(0).getDictValue())); request.setConfig(TIMEOUTS); try (CloseableHttpClient client = HttpClients.custom().disableRedirectHandling() .disableAutomaticRetries().build(); CloseableHttpResponse response = client.execute(request)) { int status = response.getStatusLine().getStatusCode(); if (status < 200 || status >= 300 || response.getEntity() == null) { throw new IllegalStateException("google map response unavailable"); } JSONObject result = JSON.parseObject(EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8)); if (result == null) throw new IllegalStateException("google map response invalid"); return result; } catch (Exception exception) { // 不保留带有 Key、用户地址或完整 URL 的底层异常。 throw new IllegalStateException("google map request failed"); } } static URI requestUri(String path, Map query, String key) { if (!PATHS.contains(path) || query.containsKey("key")) { throw new IllegalArgumentException("unsupported google map request"); } try { URIBuilder uri = new URIBuilder().setScheme("https").setHost("maps.googleapis.com").setPath(path); query.forEach((name, value) -> uri.addParameter(name, String.valueOf(value))); return uri.addParameter("key", key).build(); } catch (java.net.URISyntaxException exception) { throw new IllegalArgumentException("invalid google map request"); } } }