JAVA项目实战

本节分享高德地图API实现web服务端导航和定位等功能

1package com.example.combat.gaodemapUtils; 2 3import cn.hutool.core.io.FileUtil; 4import com.alibaba.fastjson.JSON; 5import com.alibaba.fastjson.JSONObject; 6import com.example.combat.gaodemapUtils.param.GaodeMapConstant; 7import com.example.combat.gaodemapUtils.param.Geocodes; 8import com.example.combat.gaodemapUtils.param.req.*; 9import com.google.common.collect.Maps; 10import com.sun.org.apache.regexp.internal.RE; 11import io.swagger.annotations.ApiImplicitParam; 12import io.swagger.annotations.ApiImplicitParams; 13import io.swagger.annotations.ApiOperation; 14import lombok.extern.slf4j.Slf4j; 15import org.apache.commons.codec.binary.Base64; 16import org.apache.http.NameValuePair; 17import org.apache.http.client.utils.URIBuilder; 18import org.springframework.beans.factory.annotation.Value; 19import org.springframework.cglib.beans.BeanMap; 20import org.springframework.stereotype.Component; 21import org.springframework.util.StringUtils; 22import sun.misc.BASE64Decoder; 23 24import javax.imageio.ImageIO; 25import javax.servlet.ServletOutputStream; 26import javax.servlet.http.HttpServletResponse; 27import java.awt.image.BufferedImage; 28import java.awt.image.RenderedImage; 29import java.io.*; 30import java.net.URL; 31import java.net.URLDecoder; 32import java.util.List; 33import java.util.Map; 34import java.util.Objects; 35import java.util.Random; 36import java.util.zip.GZIPOutputStream; 37 38import static com.example.combat.gaodemapUtils.HttpUtil.covertParams2NVPS; 39 40/** 41 * @description: 高德地图工具类 42 * @author: zhucj 43 * @date: 2019-11-25 17:22 44 */ 45@Component 46@Slf4j 47public class GaodeMapUtil { 48 49 50 @Value("${gaodemap.key}") 51 private String key; 52 53 @Value("${gaodemap.pathImg}") 54 private String pathImg; 55 56 /** 57 * 结构化地址信息查询 58 * @param geocodeRequestVo 59 * @return 60 */ 61 @ApiOperation(value ="结构化地址信息查询") 62 @ApiImplicitParams({ 63 @ApiImplicitParam(name = "address",value = "结构化地址信息",required = true,dataType = "String"), 64 @ApiImplicitParam(name = "city",value = "指定查询城市 城市的中文或中文全拼 ",required = false,dataType = "String") 65 }) 66 public R getGeocodes(GeocodeRequestVo geocodeRequestVo) { 67 log.info("==>查询结构化地址:"+geocodeRequestVo.getAddress()); 68 //是否支持批量查询 true:支持 false:不支持 69 geocodeRequestVo.setBatch(false); 70 //支持的格式XML,JSON 71 geocodeRequestVo.setOutput(GaodeMapConstant.JSON); 72 Map<String, Object> stringObjectMap = beanToMap(geocodeRequestVo); 73 stringObjectMap.put(GaodeMapConstant.KEY,key); 74 String resultJson = null; 75 try { 76 resultJson = HttpUtil.httpGet(GaodeMapConstant.GEOCODE_GEO, stringObjectMap); 77 } catch (Exception e) { 78 log.error("请求服务异常:{}",e.getMessage()); 79 return R.error("请求服务异常").setCode(SystemConstant.SERVER_ERROR_CODE); 80 } 81 JSONObject jsonObject = JSON.parseObject(resultJson); 82 if (Objects.equals(GaodeMapConstant.SUCCESS,jsonObject.get("status"))){ 83 String geocodes = JSON.toJSONString(jsonObject.get("geocodes")); 84 List<Geocodes> geocodes1 = JSON.parseArray(geocodes, Geocodes.class); 85 return R.ok(geocodes1.get(0)).setCode(SystemConstant.SUCCESS_CODE); 86 }else { 87 log.info("获取地址信息失败,原因:{}",jsonObject.get("info")); 88 return R.error(jsonObject.get("info").toString()).setCode(SystemConstant.SERVER_ERROR_CODE); 89 } 90 } 91 92 /** 93 * 通过经纬度,获取地理位置信息 94 * @param geocodeRequestVo 95 * @return 96 */ 97 @ApiOperation(value = "获取逆地理编码信息列表",notes = "朱传捷") 98 @ApiImplicitParams({ 99 @ApiImplicitParam(name = "location",value = "经纬度(格式:116.481488,39.990464)",required = true,dataType = "String"), 100 @ApiImplicitParam(name = "poitype",value = "返回附近POI类型(extensions 参数为 all 时才生效)",required = false,dataType = "String"), 101 @ApiImplicitParam(name = "radius",value = "搜索半径",required = false,dataType = "String"), 102 @ApiImplicitParam(name = "extensions",value = "返回结果控制(base和all)",required = false,dataType = "String"), 103 @ApiImplicitParam(name = "roadlevel",value = "道路等级",required = false,dataType = "String") 104 }) 105 public R getReGeocodes(GeocodeRequestVo geocodeRequestVo) { 106 //是否支持批量查询 true:支持 false:不支持 107 geocodeRequestVo.setBatch(false); 108 //支持的格式XML,JSON 109 geocodeRequestVo.setOutput(GaodeMapConstant.JSON); 110 Map<String, Object> stringObjectMap = beanToMap(geocodeRequestVo); 111 stringObjectMap.put(GaodeMapConstant.KEY,key); 112 try { 113 String resultJson = HttpUtil.httpGet(GaodeMapConstant.GEOCODE_REGEO, stringObjectMap); 114 JSONObject jsonObject = JSON.parseObject(resultJson); 115 if (Objects.equals(GaodeMapConstant.SUCCESS,jsonObject.get("status"))){ 116 return R.ok(jsonObject.get("regeocode")).setCode(SystemConstant.SUCCESS_CODE); 117 }else { 118 return R.error(jsonObject.get("info").toString()).setCode(SystemConstant.SERVER_ERROR_CODE); 119 } 120 } catch (Exception e) { 121 log.error("通过经纬度获取地址失败:{}",e.getMessage()); 122 return R.error("获取地址失败").setCode(SystemConstant.SERVER_ERROR_CODE); 123 } 124 } 125 126 /** 127 * 路线规划 128 * @param directionRequestVo 129 * @return 130 */ 131 @ApiOperation(value = "地图路线规划,支持步行、公交、驾车方式") 132 @ApiImplicitParams({ 133 @ApiImplicitParam(name = "directionType",value = "交通工具类型1:步行 2:公交 3:驾车",required = true,dataType = "Integer"), 134 @ApiImplicitParam(name = "origin",value = "出发点经纬度",required = true,dataType = "String"), 135 @ApiImplicitParam(name = "destination",value = "终点经纬度",required = true,dataType = "String"), 136 @ApiImplicitParam(name = "city",value = "城市/跨城规划时的起点城市,directionType = 2时必传",required = false,dataType = "String"), 137 @ApiImplicitParam(name = "strategy",value = "换乘策略",required = false,dataType = "Integer") 138 }) 139 public R getDirection(DirectionRequestVo directionRequestVo) { 140 if (StringUtils.isEmpty(directionRequestVo.getOrigin())){ 141 return R.error(GaodeMapConstant.ERR_ORIGIN_PARAM_NULL).setCode(SystemConstant.PARAM_INCORRECT_CODE); 142 } 143 if (StringUtils.isEmpty(directionRequestVo.getDestination())){ 144 return R.error(GaodeMapConstant.ERR_DESTINATION_PARAM_NULL).setCode(SystemConstant.PARAM_INCORRECT_CODE); 145 } 146 //判断路线规划类型,目前只支持3种,strategy=2时,city城市名称 147 String reqUrl = null; 148 switch (directionRequestVo.getStrategy()){ 149 case 1: 150 reqUrl = GaodeMapConstant.DIRECTION_WALKING; 151 break; 152 case 2: 153 if (StringUtils.isEmpty(directionRequestVo.getCity())){ 154 return R.error(GaodeMapConstant.ERR_CITY_PARAM_NULL).setCode(SystemConstant.PARAM_INCORRECT_CODE); 155 } 156 reqUrl = GaodeMapConstant.DIRECTION_INTEGRATED; 157 break; 158 159 case 3: 160 reqUrl = GaodeMapConstant.DIRECTION_DRIVING; 161 break; 162 default: 163 return R.error(GaodeMapConstant.ERR_DIRECTIONTYPE_PARAM_NULL).setCode(SystemConstant.PARAM_INCORRECT_CODE); 164 } 165 Map<String, Object> stringObjectMap = beanToMap(directionRequestVo); 166 stringObjectMap.put(GaodeMapConstant.KEY,key); 167 try { 168 String rusultStr = HttpUtil.httpGet(reqUrl, stringObjectMap); 169 JSONObject jsonObject = JSON.parseObject(rusultStr); 170 if (Objects.equals(GaodeMapConstant.SUCCESS,jsonObject.get("status"))){ 171 return R.ok(jsonObject.get("route")); 172 }else { 173 log.error("查询路线规划失败:{}",jsonObject.get("info").toString()); 174 return R.error(jsonObject.get("info").toString()).setCode(SystemConstant.SERVER_ERROR_CODE); 175 } 176 } catch (Exception e) { 177 log.error("查询路线规划异常:{}",e.getMessage()); 178 return R.error("查询路线规划异常").setCode(SystemConstant.SERVER_ERROR_CODE); 179 } 180 } 181 182 /** 183 * 静态地图 184 * @param staticMapRequest 185 */ 186 @ApiOperation(value = "生成静态地图") 187 @ApiImplicitParams({ 188 @ApiImplicitParam(name = "locations",value = "经纬度集合",required = true,dataType = "List"), 189 @ApiImplicitParam(name = "zoom",value = "地图缩放级别:[1,17]",required = true,dataType = "String"), 190 @ApiImplicitParam(name = "size",value = "图片宽度*图片高度。最大值为1024*1024",required = true,dataType = "String"), 191 @ApiImplicitParam(name = "scale",value = "清晰度",required = true,dataType = "Integer") 192 }) 193 public void staticMap(StaticMapRequest staticMapRequest, HttpServletResponse response){ 194 195 //设置地图缩放级别 196 staticMapRequest.setZoom(staticMapRequest.getZoom()); 197 //地图大小 198 staticMapRequest.setSize(staticMapRequest.getSize()); 199 //设置高清 200 staticMapRequest.setScale(staticMapRequest.getScale()); 201 List<String> localhosts = staticMapRequest.getLocalhosts(); 202 //设置默认第一个和最后一个点,标注,起,终 203 Markers marker1 = Markers 204 .builder() 205 .color("0xFF0000") 206 .size("mid") 207 .label("起:"+localhosts.get(0)) 208 .build(); 209 Markers markers2 = Markers 210 .builder() 211 .size("mid") 212 .color("0xFF0000") 213 .label("终:"+localhosts.get(localhosts.size()-1)) 214 .build(); 215 //拼接markers属性 216 String setMarkers1 = marker1.getSize()+","+marker1.getColor()+","+marker1.getLabel(); 217 String setMarkers2 = markers2.getSize()+","+markers2.getColor()+","+markers2.getLabel(); 218 staticMapRequest.setMarkers(setMarkers1+"|"+setMarkers2); 219 //绘制折线 220 Paths paths = Paths 221 .builder() 222 .weight(5) 223 .color("0xFF0000") 224 .transparency("1") 225 .build(); 226 StringBuilder stringBuilder = new StringBuilder(); 227 for (String localhost:localhosts){ 228 stringBuilder.append(localhost+";"); 229 } 230 String s = stringBuilder.deleteCharAt(stringBuilder.length() - 1).toString(); 231 String path = paths.getWeight()+","+paths.getColor()+","+paths.getTransparency()+","+","+":"+s; 232 staticMapRequest.setPaths(path); 233 Map<String, Object> stringObjectMap = beanToMap(staticMapRequest); 234 stringObjectMap.put(GaodeMapConstant.KEY,key); 235 try { 236 // 转换请求参数 237 List<NameValuePair> pairs = covertParams2NVPS(stringObjectMap); 238 // 装载请求地址和参数 239 URIBuilder ub = new URIBuilder(); 240 ub.setPath(GaodeMapConstant.STATUC_MAP); 241 ub.setParameters(pairs); 242 String s1 = ub.toString(); 243 String compress = compress(s1,pathImg ); 244 exportImg(response,pathImg+compress); 245 } catch (Exception e) { 246 log.error("下载图片异常"+e.getMessage()); 247 } 248 } 249 /** 250 * bean -> map 实体类转map 251 * @param bean 252 * @param <T> 253 * @return 254 */ 255 public static <T> Map<String, Object> beanToMap(T bean) { 256 Map<String, Object> map = Maps.newHashMap(); 257 if (bean != null) { 258 BeanMap beanMap = BeanMap.create(bean); 259 for (Object key : beanMap.keySet()) { 260 if (Objects.nonNull(beanMap.get(key)) && !(Objects.equals("",beanMap.get(key)))){ 261 map.put(key + "",beanMap.get(key)); 262 } 263 } 264 } 265 return map; 266 } 267 268 /** 269 * 下载地图 270 * @param url 271 * @param path 272 * @return 273 */ 274 public static String compress(String url,String path) { 275 try { 276 String imageName = "map.png"; 277 File file = new File(path + imageName); 278 //判断文件是否已经存在 279 if (file.exists()) { 280 file.delete(); 281 } 282 file.createNewFile(); 283 URL uri = new URL(url); 284 InputStream in = uri.openStream(); 285 FileOutputStream fo = new FileOutputStream(file); 286 byte[] buf = new byte[1024]; 287 int length = 0; 288 while ((length = in.read(buf, 0, buf.length)) != -1) { 289 fo.write(buf, 0, length); 290 } 291 in.close(); 292 fo.close(); 293 return imageName; 294 } catch (Exception e) { 295 log.error("下载失败",e.getMessage()); 296 return null; 297 } 298 299 } 300 301 /** 302 * 输出图片 303 * @param response 304 * @param filePath 305 */ 306 public static void exportImg(HttpServletResponse response, String filePath) { 307 File file = new File(filePath); 308 response.setCharacterEncoding("utf-8"); 309 //设置响应的内容类型 310 response.setContentType("text/plain"); 311 //设置文件的名称和格式 312 response.setHeader("content-type", "application/octet-stream"); 313 response.setContentType("application/octet-stream"); 314 response.addHeader("Content-Disposition", "attachment;filename=" + file.getName()); 315 BufferedOutputStream buff = null; 316 ServletOutputStream outStr = null; 317 try { 318 outStr = response.getOutputStream(); 319 buff = new BufferedOutputStream(outStr); 320 buff.write(FileUtil.readBytes(filePath)); 321 buff.flush(); 322 buff.close(); 323 } catch (Exception e) { 324 e.printStackTrace(); 325 log.error("文件导出异常:", e); 326 } finally { 327 try { 328 buff.close(); 329 } catch (Exception e) { 330 log.error("流关闭异常:", e); 331 } 332 try { 333 outStr.close(); 334 } catch (Exception e) { 335 log.error("流关闭异常:", e); 336 } 337 } 338 } 339 340} 341 342package com.example.combat.gaodemapUtils; 343 344import com.alibaba.fastjson.JSON; 345import lombok.extern.slf4j.Slf4j; 346import org.apache.commons.codec.binary.Base64; 347import org.apache.http.HttpEntity; 348import org.apache.http.NameValuePair; 349import org.apache.http.client.entity.UrlEncodedFormEntity; 350import org.apache.http.client.methods.CloseableHttpResponse; 351import org.apache.http.client.methods.HttpGet; 352import org.apache.http.client.methods.HttpPost; 353import org.apache.http.client.methods.HttpRequestBase; 354import org.apache.http.client.utils.URIBuilder; 355import org.apache.http.config.Registry; 356import org.apache.http.config.RegistryBuilder; 357import org.apache.http.conn.socket.ConnectionSocketFactory; 358import org.apache.http.conn.socket.PlainConnectionSocketFactory; 359import org.apache.http.conn.ssl.NoopHostnameVerifier; 360import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 361import org.apache.http.entity.ContentType; 362import org.apache.http.entity.StringEntity; 363import org.apache.http.impl.client.CloseableHttpClient; 364import org.apache.http.impl.client.HttpClients; 365import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; 366import org.apache.http.message.BasicNameValuePair; 367import org.apache.http.ssl.SSLContextBuilder; 368import org.apache.http.ssl.SSLContexts; 369import org.apache.http.ssl.TrustStrategy; 370import org.apache.http.util.EntityUtils; 371 372import javax.net.ssl.SSLContext; 373import java.io.*; 374import java.nio.charset.StandardCharsets; 375import java.security.KeyStore; 376import java.security.cert.CertificateException; 377import java.security.cert.X509Certificate; 378import java.util.ArrayList; 379import java.util.List; 380import java.util.Map; 381import java.util.zip.GZIPInputStream; 382import java.util.zip.GZIPOutputStream; 383 384@Slf4j 385public class HttpUtil { 386 387 public static final ContentType TEXT_PLAIN = ContentType.create("text/plain", StandardCharsets.UTF_8); 388 389 /** 390 * HttpClient 连接池 391 */ 392 private static PoolingHttpClientConnectionManager cm = null; 393 394 static { 395 // 初始化连接池,可用于请求HTTP/HTTPS(信任所有证书) 396 cm = new PoolingHttpClientConnectionManager(getRegistry()); 397 // 整个连接池最大连接数 398 cm.setMaxTotal(200); 399 // 每路由最大连接数,默认值是2 400 cm.setDefaultMaxPerRoute(5); 401 } 402 403 /** 404 * 发送 HTTP GET请求 405 * <p>不带请求参数和请求头</p> 406 * @param url 地址 407 * @return 408 * @throws Exception 409 */ 410 public static String httpGet(String url) throws Exception { 411 log.info("请求参数:{}",url); 412 HttpGet httpGet = new HttpGet(url); 413 414 return doHttp(httpGet); 415 } 416 417 /** 418 * 发送 HTTP GET请求 419 * <p>带请求参数,不带请求头</p> 420 * @param url 地址 421 * @param params 参数 422 * @return 423 * @throws Exception 424 * @throws Exception 425 */ 426 public static String httpGet(String url, Map<String, Object> params) throws Exception { 427 // 转换请求参数 428 List<NameValuePair> pairs = covertParams2NVPS(params); 429 430 // 装载请求地址和参数 431 URIBuilder ub = new URIBuilder(); 432 ub.setPath(url); 433 ub.setParameters(pairs); 434 HttpGet httpGet = new HttpGet(ub.build()); 435 436 return doHttp(httpGet); 437 } 438 439 /** 440 * 发送 HTTP GET请求 441 * <p>带请求参数和请求头</p> 442 * @param url 地址 443 * @param headers 请求头 444 * @param params 参数 445 * @return 446 * @throws Exception 447 * @throws Exception 448 */ 449 public static String httpGet(String url, Map<String, Object> headers, Map<String, Object> params) throws Exception { 450 // 转换请求参数 451 List<NameValuePair> pairs = covertParams2NVPS(params); 452 453 // 装载请求地址和参数 454 URIBuilder ub = new URIBuilder(); 455 ub.setPath(url); 456 ub.setParameters(pairs); 457 458 HttpGet httpGet = new HttpGet(ub.build()); 459 // 设置请求头 460 for (Map.Entry<String, Object> param : headers.entrySet()){ 461 httpGet.addHeader(param.getKey(), String.valueOf(param.getValue()));} 462 463 return doHttp(httpGet); 464 } 465 466 /** 467 * 发送 HTTP POST请求 468 * <p>不带请求参数和请求头</p> 469 * 470 * @param url 地址 471 * @return 472 * @throws Exception 473 */ 474 public static String httpPost(String url) throws Exception { 475 HttpPost httpPost = new HttpPost(url); 476 477 return doHttp(httpPost); 478 } 479 480 /** 481 * 发送 HTTP POST请求 482 * <p>带请求参数,不带请求头</p> 483 * 484 * @param url 地址 485 * @param params 参数 486 * @return 487 * @throws Exception 488 */ 489 public static String httpPost(String url, Map<String, Object> params) throws Exception { 490 // 转换请求参数 491 List<NameValuePair> pairs = covertParams2NVPS(params); 492 493 HttpPost httpPost = new HttpPost(url); 494 // 设置请求参数 495 httpPost.setEntity(new UrlEncodedFormEntity(pairs, StandardCharsets.UTF_8.name())); 496 497 return doHttp(httpPost); 498 } 499 500 /** 501 * 发送 HTTP POST请求 502 * <p>带请求参数和请求头</p> 503 * 504 * @param url 地址 505 * @param headers 请求头 506 * @param params 参数 507 * @return 508 * @throws Exception 509 */ 510 public static String httpPost(String url, Map<String, Object> headers, Map<String, Object> params) throws Exception { 511 log.info("POST请求参数:{}",params); 512 HttpPost httpPost = new HttpPost(url); 513 // 设置请求参数 514 StringEntity entity = new StringEntity(JSON.toJSONString(params),ContentType.APPLICATION_JSON); 515 httpPost.setEntity(entity); 516 // 设置请求头 517 for (Map.Entry<String, Object> param : headers.entrySet()){ 518 httpPost.addHeader(param.getKey(), String.valueOf(param.getValue()));} 519 520 return doHttp(httpPost); 521 } 522 523 524 525 526 /** 527 * 转换请求参数 528 * 529 * @param params 530 * @return 531 */ 532 public static List<NameValuePair> covertParams2NVPS(Map<String, Object> params) { 533 List<NameValuePair> pairs = new ArrayList<NameValuePair>(); 534 535 for (Map.Entry<String, Object> param : params.entrySet()){ 536 pairs.add(new BasicNameValuePair(param.getKey(), String.valueOf(param.getValue())));} 537 538 return pairs; 539 } 540 541 /** 542 * 发送 HTTP 请求 543 * 544 * @param request 545 * @return 546 * @throws Exception 547 */ 548 private static String doHttp(HttpRequestBase request) throws Exception { 549 // 通过连接池获取连接对象 550 CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build(); 551 552 return doRequest(httpClient, request); 553 } 554 555 /** 556 * 发送 HTTPS 请求 557 * <p>使用指定的证书文件及密码</p> 558 * 559 * @param request 560 * @param path 561 * @param password 562 * @return 563 * @throws Exception 564 * @throws Exception 565 */ 566 private static String doHttps(HttpRequestBase request, String path, String password) throws Exception { 567 // 获取HTTPS SSL证书 568 SSLConnectionSocketFactory csf = getSSLFactory(path, password); 569 // 通过连接池获取连接对象 570 CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build(); 571 572 return doRequest(httpClient, request); 573 } 574 575 /** 576 * 获取HTTPS SSL连接工厂 577 * <p>使用指定的证书文件及密码</p> 578 * 579 * @param path 证书全路径 580 * @param password 证书密码 581 * @return 582 * @throws Exception 583 * @throws Exception 584 */ 585 private static SSLConnectionSocketFactory getSSLFactory(String path, String password) throws Exception { 586 587 // 初始化证书,指定证书类型为“PKCS12” 588 KeyStore keyStore = KeyStore.getInstance("PKCS12"); 589 // 读取指定路径的证书 590 FileInputStream input = new FileInputStream(new File(path)); 591 592 try { 593 // 装载读取到的证书,并指定证书密码 594 keyStore.load(input, password.toCharArray()); 595 } finally { 596 input.close(); 597 } 598 599 // 获取HTTPS SSL证书连接上下文 600 SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(keyStore, password.toCharArray()).build(); 601 602 // 获取HTTPS连接工厂,指定TSL版本 603 SSLConnectionSocketFactory sslCsf = new SSLConnectionSocketFactory(sslContext, new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier()); 604 605 return sslCsf; 606 } 607 608 /** 609 * 获取HTTPS SSL连接工厂 610 * <p>跳过证书校验,即信任所有证书</p> 611 * 612 * @return 613 * @throws Exception 614 */ 615 private static SSLConnectionSocketFactory getSSLFactory() throws Exception { 616 // 设置HTTPS SSL证书信息,跳过证书校验,即信任所有证书请求HTTPS 617 SSLContextBuilder sslBuilder = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { 618 public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { 619 return true; 620 } 621 }); 622 623 // 获取HTTPS SSL证书连接上下文 624 SSLContext sslContext = sslBuilder.build(); 625 626 // 获取HTTPS连接工厂 627 SSLConnectionSocketFactory sslCsf = new SSLConnectionSocketFactory(sslContext, new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE); 628 629 return sslCsf; 630 } 631 632 /** 633 * 获取 HTTPClient注册器 634 * 635 * @return 636 * @throws Exception 637 */ 638 private static Registry<ConnectionSocketFactory> getRegistry() { 639 Registry<ConnectionSocketFactory> registry = null; 640 641 try { 642 registry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", new PlainConnectionSocketFactory()).register("https", getSSLFactory()).build(); 643 } catch (Exception e) { 644 log.error("获取 HTTPClient注册器失败", e); 645 } 646 647 return registry; 648 } 649 650 651 /** 652 * 处理Http/Https请求,并返回请求结果 653 * <p>注:默认请求编码方式 UTF-8</p> 654 * 655 * @param httpClient 656 * @param request 657 * @return 658 * @throws Exception 659 */ 660 private static String doRequest(CloseableHttpClient httpClient, HttpRequestBase request) throws Exception { 661 String result = null; 662 CloseableHttpResponse response = null; 663 664 try { 665 // 获取请求结果 666 response = httpClient.execute(request); 667 // 解析请求结果 668 HttpEntity entity = response.getEntity(); 669 if ((entity.getContentEncoding() != null) 670 && entity.getContentEncoding().getValue().contains("gzip")) { 671 GZIPInputStream gzip = new GZIPInputStream( 672 new ByteArrayInputStream(EntityUtils.toByteArray(entity))); 673 InputStreamReader isr = new InputStreamReader(gzip); 674 BufferedReader br = new BufferedReader(isr); 675 StringBuilder sb = new StringBuilder(); 676 String temp; 677 while((temp = br.readLine()) != null){ 678 sb.append(temp); 679 sb.append("\r\n"); 680 } 681 isr.close(); 682 gzip.close(); 683 return sb.toString(); 684 } 685 // 转换结果 686 result = EntityUtils.toString(entity, StandardCharsets.UTF_8.name()); 687 // 关闭IO流 688 EntityUtils.consume(entity); 689 } finally { 690 if (null != response){ 691 response.close();} 692 } 693 694 return result; 695 } 696 697 698} 699 700package com.example.combat.gaodemapUtils; 701 702import io.swagger.annotations.ApiModel; 703import io.swagger.annotations.ApiModelProperty; 704import lombok.ToString; 705 706import java.io.Serializable; 707 708/** 709 * 返回类型 710 * @author choleece 711 * @date 2018/9/27 712 */ 713@ApiModel 714@ToString 715public class R<T> implements Serializable { 716 717 private static final long serialVersionUID = -6287952131441663819L; 718 719 /** 720 * 编码 721 */ 722 @ApiModelProperty(value = "响应码", example = "200") 723 private int code = 200; 724 725 /** 726 * 成功标志 727 */ 728 @ApiModelProperty(value = "成功标志", example = "true") 729 private Boolean success; 730 731 /** 732 * 返回消息 733 */ 734 @ApiModelProperty(value = "返回消息说明", example = "操作成功") 735 private String msg="操作成功"; 736 737 /** 738 * 返回数据 739 */ 740 @ApiModelProperty(value = "返回数据") 741 private T data; 742 743 /** 744 * 创建实例 745 * @return 746 */ 747 public static R instance() { 748 return new R(); 749 } 750 751 public int getCode() { 752 return code; 753 } 754 755 public R setCode(int code) { 756 this.code = code; 757 return this; 758 } 759 760 public Boolean getSuccess() { 761 return success; 762 } 763 764 public R setSuccess(Boolean success) { 765 this.success = success; 766 return this; 767 } 768 769 public String getMsg() { 770 return msg; 771 } 772 773 public R setMsg(String msg) { 774 this.msg = msg; 775 return this; 776 } 777 778 public T getData() { 779 return data; 780 } 781 public R setData(T data) { 782 this.data = data; 783 return this; 784 } 785 786 public static R ok() { 787 return R.instance().setSuccess(true); 788 } 789 790 public static R ok(Object data) { 791 return ok().setData(data); 792 } 793 794 public static R ok(Object data, String msg) { 795 return ok(data).setMsg(msg); 796 } 797 798 public static R error() { 799 return R.instance().setSuccess(false); 800 } 801 802 public static R error(String msg) { 803 return error().setMsg(msg); 804 } 805 806 /** 807 * 无参 808 */ 809 public R() { 810 } 811 812 public R(int code, String msg) { 813 this.code = code; 814 this.msg = msg; 815 } 816 817 public R(int code, T data){ 818 this.code = code; 819 this.data = data; 820 } 821 822 /** 823 * 有全参 824 * @param code 825 * @param msg 826 * @param data 827 * @param success 828 */ 829 public R(int code, String msg, T data, Boolean success) { 830 this.code = code; 831 this.msg = msg; 832 this.data = data; 833 this.success = success; 834 } 835 836 /** 837 * 有参 838 * @param code 839 * @param msg 840 * @param data 841 */ 842 public R(int code, String msg, T data) { 843 this.code = code; 844 this.msg = msg; 845 this.data = data; 846 } 847} 848 849package com.example.combat.gaodemapUtils; 850 851/** 前端返回信息 852 * @Author: zhucj 853 * @Date: 2019/5/21 16:19 854 */ 855public class SystemConstant { 856 857 858 /** 传参不规范,code:400*/ 859 public static final Integer PARAM_INCORRECT_CODE = 400; 860 861 /** 成功,code:200*/ 862 public static final Integer SUCCESS_CODE = 200; 863 864 /** 服务内部调用失败,code:500*/ 865 public static final Integer SERVER_ERROR_CODE = 500; 866 867 /** 登录失效,code:401*/ 868 public static final Integer AUTH_FAIL_CODE = 401; 869 870 /** 无对应接口权限,code:402*/ 871 public static final Integer HAVE_NOT_PERMISSION_CODE = 402; 872 873 /** 操作无记录,code:403*/ 874 public static final Integer NO_RECORD_OPERATION = 403; 875 876 877 878 879 880} 881 882package com.example.combat.gaodemapUtils.param.req; 883 884import io.swagger.annotations.ApiModel; 885import lombok.*; 886 887/** 888 * @description: 889 * @author: zhucj 890 * @date: 2019-08-05 11:19 891 */ 892@Data 893@ApiModel(description = "路径规划请求视图") 894@Builder 895@NoArgsConstructor 896@AllArgsConstructor 897@ToString 898public class DirectionRequestVo { 899 900 /** 901 * 交通工具类型 1:步行 2:公交 3:驾车 902 */ 903 private Integer directionType; 904 /** 905 * 出发点 lon,lat(经度,纬度), “,”分割,如117.500244, 40.417801 906 */ 907 private String origin; 908 909 /** 910 * 目的地 lon,lat(经度,纬度), “,”分割,如117.500244, 40.417801 911 */ 912 private String destination; 913 914 /** 915 * 城市/跨城规划时的起点城市,directionType = 2时必传 916 */ 917 private String city; 918 919 /** 920 * 公交换乘策略 directionType = 2和3时选传 默认0 可选值: 921 * 0:最快捷模式,1:最经济模式,2:最少换乘模式,3:最少步行模式,5:不乘地铁模式 922 * 下方10~20的策略,会返回多条路径规划结果。(高德地图APP策略也包含在内,强烈建议从此策略之中选择) 923 * 下方策略 0~9的策略,仅会返回一条路径规划结果 924 */ 925 /** 926 * 下方策略仅返回一条路径规划结果 927 * 0,速度优先,不考虑当时路况,此路线不一定距离最短 928 * 1,费用优先,不走收费路段,且耗时最少的路线 929 * 2,距离优先,不考虑路况,仅走距离最短的路线,但是可能存在穿越小路/小区的情况 930 * 3,速度优先,不走快速路,例如京通快速路(因为策略迭代,建议使用13) 931 * 4,躲避拥堵,但是可能会存在绕路的情况,耗时可能较长 932 * 5,多策略(同时使用速度优先、费用优先、距离优先三个策略计算路径)。 933 * 其中必须说明,就算使用三个策略算路,会根据路况不固定的返回一~三条路径规划信息。 934 * 6,速度优先,不走高速,但是不排除走其余收费路段 935 * 7,费用优先,不走高速且避免所有收费路段 936 * 8,躲避拥堵和收费,可能存在走高速的情况,并且考虑路况不走拥堵路线,但有可能存在绕路和时间较长 937 * 9,躲避拥堵和收费,不走高速 938 * 下方策略返回多条路径规划结果 939 * 10,返回结果会躲避拥堵,路程较短,尽量缩短时间,与高德地图的默认策略也就是不进行任何勾选一致 940 * 11,返回三个结果包含:时间最短;距离最短;躲避拥堵 (由于有更优秀的算法,建议用10代替) 941 * 12,返回的结果考虑路况,尽量躲避拥堵而规划路径,与高德地图的“躲避拥堵”策略一致 942 * 13,返回的结果不走高速,与高德地图“不走高速”策略一致 943 * 14,返回的结果尽可能规划收费较低甚至免费的路径,与高德地图“避免收费”策略一致 944 * 15,返回的结果考虑路况,尽量躲避拥堵而规划路径,并且不走高速,与高德地图的“躲避拥堵&不走高速”策略一致 945 * 16,返回的结果尽量不走高速,并且尽量规划收费较低甚至免费的路径结果,与高德地图的“避免收费&不走高速”策略一致 946 * 17,返回路径规划结果会尽量的躲避拥堵,并且规划收费较低甚至免费的路径结果,与高德地图的“躲避拥堵&避免收费”策略一致 947 * 18,返回的结果尽量躲避拥堵,规划收费较低甚至免费的路径结果,并且尽量不走高速路,与高德地图的“避免拥堵&避免收费&不走高速”策略一致 948 * 19,返回的结果会优先选择高速路,与高德地图的“高速优先”策略一致 949 * 20,返回的结果会优先考虑高速路,并且会考虑路况躲避拥堵,与高德地图的“躲避拥堵&高速优先”策略一致 950 */ 951 private Integer strategy; 952 953} 954 955package com.example.combat.gaodemapUtils.param.req; 956 957import io.swagger.annotations.ApiModel; 958import lombok.*; 959 960/** 961 * @description: 962 * @author:zhucj 963 * @date: 2019-08-02 11:50 964 */ 965@Data 966@ApiModel(description = "地理名称请求视图") 967@Builder 968@NoArgsConstructor 969@AllArgsConstructor 970@ToString 971public class GeocodeRequestVo { 972 973 //TODO: 地理编码参数 974 /** 975 * 结构化地址信息 976 * 如:北京市朝阳区阜通东大街6号。如果需要解析多个地址的话, 977 * 请用"|"进行间隔,并且将 batch 参数设置为 true, 978 * 最多支持 10 个地址进进行"|"分割形式的请求。 979 */ 980 private String address; 981 982 /** 983 * 城市名称 984 * 指定城市的中文(如北京)、指定城市的中文全拼(beijing)、 985 * citycode(010)、adcode(110000),不支持县级市。 986 */ 987 private String city; 988 989 /** 990 * 批量查询控制 991 * batch 参数设置为 true 时进行批量查询操作,最多支持 10 个地址进行批量查询。 992 * batch 参数设置为 false 时进行单点查询,此时即使传入多个地址也只返回第一个地址的解析查询结果。 993 */ 994 private Boolean batch; 995 996 /** 997 * 返回数据格式类型 998 * 可选输入内容包括:JSON,XML 999 */ 1000 private String output; 1001 1002 /** 1003 * 数字签名 1004 */ 1005 private String sig; 1006 1007 /** 1008 * 回调函数 1009 */ 1010 private String callback; 1011 1012 //TODO:逆地理编码参数 1013 1014 /** 1015 * 经纬度坐标 1016 * 经度在前,纬度在后,经纬度间以“,”分割,经纬度小数点后不要超过 6 位 1017 */ 1018 private String location; 1019 1020 /** 1021 * 搜索半径 1022 * radius取值范围在0~3000,默认是1000。单位:米 1023 */ 1024 private String radius ; 1025 1026 /** 1027 * 返回结果控制 1028 * extensions 参数默认取值是 base,也就是返回基本地址信息; 1029 * extensions 参数取值为 all 时会返回基本地址信息、附近 POI 内容、道路信息以及道路交叉口信息。 1030 */ 1031 private String extensions; 1032 1033 /** 1034 *道路等级 1035 * 以下内容需要 extensions 参数为 all 时才生效。 1036 * 可选值:0,1 1037 * 当roadlevel=0时,显示所有道路 1038 * 当roadlevel=1时,过滤非主干道路,仅输出主干道路数据 1039 */ 1040 private String roadlevel; 1041 1042 /** 1043 * 是否优化POI返回顺序 1044 * 以下内容需要 extensions 参数为 all 时才生效。 1045 * homeorcorp 参数的设置可以影响召回 POI 内容的排序策略,目前提供三个可选参数: 1046 * 0:不对召回的排序策略进行干扰。 1047 * 1:综合大数据分析将居家相关的 POI 内容优先返回,即优化返回结果中 pois 字段的poi顺序。 1048 * 2:综合大数据分析将公司相关的 POI 内容优先返回,即优化返回结果中 pois 字段的poi顺序。 1049 */ 1050 private String homeorcorp; 1051} 1052 1053package com.example.combat.gaodemapUtils.param.req; 1054 1055import io.swagger.annotations.ApiModel; 1056import lombok.*; 1057 1058/** 1059 * @description: 1060 * @author: zhucj 1061 * @date: 2019-11-26 11:15 1062 */ 1063@Data 1064@ApiModel(description = "标注视图") 1065@Builder 1066@NoArgsConstructor 1067@AllArgsConstructor 1068@ToString 1069public class Markers { 1070 1071 /** 1072 * 可选值: small,mid,large 1073 */ 1074 private String size; 1075 1076 /** 1077 * 0x000000 black, 1078 * 0x008000 green, 1079 * 0x800080 purple, 1080 * 0xFFFF00 yellow, 1081 * 0x0000FF blue, 1082 * 0x808080 gray, 1083 * 0xffa500 orange, 1084 * 0xFF0000 red, 1085 * 0xFFFFFF white 1086 */ 1087 private String color; 1088 1089 /** 1090 * 0-9]、[A-Z]、[单个中文字] 当size为small时,图片不展现标注名。 1091 * 格式 A:116.31604,39.96491 1092 */ 1093 private String label; 1094} 1095 1096package com.example.combat.gaodemapUtils.param.req; 1097 1098import io.swagger.annotations.ApiModel; 1099import lombok.*; 1100 1101/** 1102 * @description: 1103 * @author: zhucj 1104 * @date: 2019-11-26 11:20 1105 */ 1106@Data 1107@ApiModel(description = "折线视图") 1108@Builder 1109@NoArgsConstructor 1110@AllArgsConstructor 1111@ToString 1112public class Paths { 1113 1114 /** 1115 * 线条粗细。 1116 * 可选值: [2,15] 1117 */ 1118 private Integer weight; 1119 1120 /** 1121 * 折线颜色。 选值范围:[0x000000, 0xffffff] 1122 * 例如: 1123 * 0x000000 black, 1124 * 0x008000 green, 1125 * 0x800080 purple, 1126 * 0xFFFF00 yellow, 1127 * 0x0000FF blue, 1128 * 0x808080 gray, 1129 * 0xffa500 orange, 1130 * 0xFF0000 red, 1131 * 0xFFFFFF white 1132 */ 1133 private String color; 1134 1135 /** 1136 * 透明度。 1137 * 可选值[0,1],小数后最多2位,0表示完全透明,1表示完全不透明。 1138 */ 1139 private String transparency; 1140 1141 /** 1142 * 多边形的填充颜色,此值不为空时折线封闭成多边形。取值规则同color 1143 */ 1144 private String fillcolor; 1145 1146 /** 1147 * 填充面透明度。 1148 * 可选值[0,1],小数后最多2位,0表示完全透明,1表示完全不透明 1149 */ 1150 private String fillTransparency; 1151} 1152 1153package com.example.combat.gaodemapUtils.param.req; 1154 1155import io.swagger.annotations.ApiModel; 1156import lombok.*; 1157 1158import java.util.List; 1159 1160/** 1161 * @description: 绘制静态地图请求实体 1162 * @author:zhucj 1163 * @date: 2019-11-26 10:48 1164 */ 1165@Data 1166@ApiModel(description = "绘制静态地图请求视图") 1167@Builder 1168@NoArgsConstructor 1169@AllArgsConstructor 1170@ToString 1171public class StaticMapRequest { 1172 1173 /** 1174 * 路线主键Id 1175 */ 1176 private Long id; 1177 1178 /** 1179 * 地图中心点 中心点坐标。 1180 * 规则:经度和纬度用","分隔 经纬度小数点后不得超过6位。 1181 */ 1182 private String location; 1183 1184 /** 1185 * 地图缩放级别:[1,17] 1186 */ 1187 private Integer zoom; 1188 1189 /** 1190 * 图片宽度*图片高度。最大值为1024*1024 1191 */ 1192 private String size; 1193 1194 /** 1195 *1:返回普通图; 1196 * 2:调用高清图,图片高度和宽度都增加一倍,zoom也增加一倍(当zoom为最大值时,zoom不再改变)。 1197 */ 1198 private Integer scale; 1199 1200 /** 1201 * 标注 1202 */ 1203 private String markers; 1204 1205 /** 1206 * 折线 1207 */ 1208 private String paths; 1209 1210 1211 /** 1212 * 经纬度集合 1213 */ 1214 private List<String> localhosts; 1215 1216} 1217 1218package com.example.combat.gaodemapUtils.param; 1219 1220/** 1221 * @description: 高德地图服务枚举 1222 * @author:zhucj 1223 * @date: 2019-08-02 11:25 1224 */ 1225public class GaodeMapConstant { 1226 1227 /** 1228 * 前端返回字段不匹配异常信息 1229 **/ 1230 public static final String ERR_ORIGIN_PARAM_NULL = "出发点经纬度,不为空!"; 1231 1232 public static final String ERR_CITY_PARAM_NULL = "公交路线规划,传入的城市名称不为空!"; 1233 1234 1235 public static final String ERR_DESTINATION_PARAM_NULL = "目的地经纬度,不为空!"; 1236 1237 public static final String ERR_DIRECTIONTYPE_PARAM_NULL = "传入的规划类型,暂不支持目前只有1,2,3"; 1238 1239 /** 1240 * 地理请求地址 1241 */ 1242 public static final String GEOCODE_GEO = "https://restapi.amap.com/v3/geocode/geo"; 1243 1244 1245 /** 1246 * 逆地理请求地址 1247 */ 1248 public static final String GEOCODE_REGEO = "https://restapi.amap.com/v3/geocode/regeo"; 1249 1250 /** 1251 * 步行规划路线请求地址 1252 */ 1253 public static final String DIRECTION_WALKING = "https://restapi.amap.com/v3/direction/walking"; 1254 1255 /** 1256 * 公交规划路线请求地址 1257 */ 1258 public static final String DIRECTION_INTEGRATED = "https://restapi.amap.com/v3/direction/transit/integrated"; 1259 1260 /** 1261 * 驾车路线规划 1262 */ 1263 public static final String DIRECTION_DRIVING = "https://restapi.amap.com/v3/direction/driving"; 1264 1265 /** 1266 * 货车路线规划 1267 */ 1268 public static final String DIRECTION_TRUCK = "https://restapi.amap.com/v4/direction/truck"; 1269 1270 /** 1271 * 距离测量 1272 */ 1273 public static final String DISTANCE = "https://restapi.amap.com/v3/distance"; 1274 1275 /** 1276 * 静态地图 1277 */ 1278 public static final String STATUC_MAP = "https://restapi.amap.com/v3/staticmap"; 1279 1280 1281 1282 /** 1283 * 返回状态码 成功 1284 */ 1285 public static final String SUCCESS = "1"; 1286 1287 /** 1288 * 返回状态码 失败 1289 */ 1290 public static final String FAIL= "0"; 1291 1292 /** 1293 * 返回数据格式 1294 */ 1295 public static final String JSON = "JSON"; 1296 1297 /** 1298 * 高德地图key秘钥 1299 */ 1300 public static final String KEY = "key"; 1301} 1302 1303package com.example.combat.gaodemapUtils.param; 1304 1305import lombok.AllArgsConstructor; 1306import lombok.Builder; 1307import lombok.Data; 1308import lombok.NoArgsConstructor; 1309 1310/** 1311 * @description: 地址编码返回参数 1312 * @author: zhucj 1313 * @date: 2019-11-25 18:17 1314 */ 1315@Data 1316@Builder 1317@NoArgsConstructor 1318@AllArgsConstructor 1319public class Geocodes { 1320 1321 private String formatted_address; 1322 1323 private String country; 1324 1325 private String province; 1326 1327 private String city; 1328 1329 private String citycode; 1330 1331 private String district; 1332 1333 private String street; 1334 1335 private String number; 1336 1337 private String adcode; 1338 1339 private String location; 1340 1341 private String level; 1342} 1343 1344#高德地图配置 1345gaodemap: 1346 key: ******** 1347 pathImg: E://upload/
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Android So动态加载 优雅实现与原理分析

背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我