httpClient 4.5.9 连接池

需要的jar包

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.9</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.5.9</version>
            <exclusions>
                <exclusion>
                    <artifactId>httpclient</artifactId>
                    <groupId>org.apache.httpcomponents</groupId>
                </exclusion>
            </exclusions>
        </dependency>
package com.oohad.oohadshowmanager.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.oohad.oohadshowmanager.entity.LngLatMessage;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
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.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.CharsetUtils;
import org.apache.http.util.EntityUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HttpUtil {

    private HttpUtil() {
    }

    private static CloseableHttpClient httpClient = null;


    static {
        // 请求重试处理
        HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {
            @Override
            public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
                if (executionCount >= 3) {// 如果已经重试了3次,就放弃
                    return false;
                }
                if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
                    return true;
                }
                if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
                    return false;
                }
                if (exception instanceof InterruptedIOException) {// 超时
                    return false;
                }
                if (exception instanceof UnknownHostException) {// 目标服务器不可达
                    return false;
                }
                if (exception instanceof ConnectTimeoutException) {// 连接被拒绝
                    return false;
                }
                // SSL握手异常
                if (exception instanceof SSLException) {
                    return false;
                }

                HttpClientContext clientContext = HttpClientContext.adapt(context);
                HttpRequest request = clientContext.getRequest();
                // 如果请求是幂等的,就再次尝试
                if (!(request instanceof HttpEntityEnclosingRequest)) {
                    return true;
                }
                return false;
            }
        };

        httpClient = HttpClients.custom()
                // 将每个路由默认最大连接数
                .setMaxConnPerRoute(50)
                // 设置最大连接数
                .setMaxConnTotal(100)
                .evictIdleConnections(60, TimeUnit.SECONDS)
                // 请求重试处理
                .setRetryHandler(httpRequestRetryHandler)
                .build();

        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try {
                httpClient.close();
            } catch (IOException ignored) {
            }
        }));
    }

    /**
     * 过滤特殊字符串
     */
    public static final Pattern ILLEGAL_STRING_PATTERN = Pattern.compile("[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……& amp;*()——+|{}【】‘;:”“’。,、?|]");

    /**
     * 过滤换车 换行
     */
    public static final Pattern CRLF = Pattern.compile("(\r\n|\r|\n|\n\r)");

    /**
     * http post方式上传文件
     * httpPost 主要是创建百度任务的时候, 上传文件txt使用
     *
     * @param url
     * @param headers           请求头信息
     * @param FileBinaryBodyMap 请求体信息 只支持文件,可以多文件,不过后端接受文件比较麻烦 因为每个都文件都有一个name,
     *                          而spring获取文件都是通过@RequestParam("uploadFile") MultipartFile file的方式来获取
     * @return String 请求返回的json字符串
     */
    public static String httpPost(String url, Map<String, String> headers, Map<String, File> FileBinaryBodyMap, Map<String, String> textBodyMap) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // result
        String result = "";
        try {
            HttpPost httpPost = new HttpPost(url);
            // 设置请求和传输超时时间
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(60_000)
                    .setConnectionRequestTimeout(60_000)
                    .setSocketTimeout(120_000).build();
            httpPost.setConfig(requestConfig);
            headers.forEach((key, value) -> httpPost.setHeader(key, value));
            //构造请求体
            MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
            // 以浏览器兼容模式运行,防止文件名乱码。
            entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            // 设置二进制的方式上传文件addBinaryBody() 如果是表单 用addPart() 或者 addTextBody主要用哪一个看需求
            if (FileBinaryBodyMap != null) {
                FileBinaryBodyMap.forEach((key, value) -> entityBuilder.addBinaryBody(key, value));
            }
            // 这里是添加textBodyMap
            if (textBodyMap != null) {
                textBodyMap.forEach((k, v) -> entityBuilder.addTextBody(k, v));
            }
            HttpEntity reqEntity = entityBuilder.setCharset(CharsetUtils.get("UTF-8")).build();
            httpPost.setEntity(reqEntity);

            // System.out.println("发起请求的页面地址 " + httpPost.getRequestLine());
            // 发起请求 并返回请求的响应
            CloseableHttpResponse response = httpClient.execute(httpPost);
            try {
                // 获取响应对象
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, Charset.forName("UTF-8"));
                }
                /***
                 // 想看可以打开注释
                 // 打印响应状态
                 // System.out.println("response StatusLin:" + response.getStatusLine());
                 // 打印http状态码
                 // System.out.println("response code:" + response.getStatusLine().getStatusCode());
                 if (resEntity != null) {
                 // 响应长度
                 System.out.println("Response content length: "
                 + resEntity.getContentLength());
                 // 响应内容
                 System.out.println("response content: " + result);
                 }
                 */
                // 销毁
                EntityUtils.consume(resEntity);
            } finally {
                if (response != null) {
                    response.close();
                }
            }
        } finally {
            if (httpClient != null) {
                httpClient.close();
            }
        }
        return result;
    }

    /**
     * http post请求
     *
     * @param url     请求地址
     * @param headers 请求头
     * @param json    json格式请求体内容 类似postman用json格式去请求
     * @return String 请求返回的json字符串
     * @throws IOException
     */
    public static String httpPost(String url, Map<String, String> headers, String json) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // result
        String result = null;
        CloseableHttpResponse response = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            // 480秒(8分钟) 应该能返回了吧, 他们的接口真慢
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(10_000)
                    .setConnectionRequestTimeout(480_000)
                    .setSocketTimeout(480_000).build();
            httpPost.setConfig(requestConfig);
            headers.forEach((key, value) -> httpPost.setHeader(key, value));
            if (!StringUtils.isEmpty(json)) {
                StringEntity reqEntity = new StringEntity(json, "utf-8");
                reqEntity.setContentEncoding("utf-8");
                httpPost.setEntity(reqEntity);
            }
            response = httpClient.execute(httpPost);
            Integer statusCode = response.getStatusLine().getStatusCode();
            Integer SUCCESS_CODE = 200;
            Integer INTERNAL_SERVER_ERROR = 500;
            if (Objects.equals(statusCode, SUCCESS_CODE)) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, StandardCharsets.UTF_8);
                }
                EntityUtils.consume(resEntity);
            } else if (Objects.equals(statusCode, INTERNAL_SERVER_ERROR)) {
                System.out.printf("目标服务器500异常,当前http请求地址:%s, 请求头:%s, 方法体:%s %n", url, headers.toString(), json);
            }

//            Header responseHeaders = response.getFirstHeader("content-type");
//            System.out.println("===========================");
//            System.out.println(responseHeaders);
//            System.out.println(responseHeaders.getName());
//            System.out.println(responseHeaders.getValue());
//            System.out.println("===========================");
        } finally {
            if (response != null) {
                response.close();
            }
            if (httpClient != null) {
                httpClient.close();
            }
        }
        return result;
    }

    /**
     * http请求Get的方式去获取数据
     *
     * @param url     地址
     * @param headers 请求头,可以为空
     * @return
     * @throws IOException
     */
    public static String httpGet(String url, @Nullable Map<String, String> headers) throws IOException {
        // CloseableHttpClient httpClient = HttpClients.createDefault();
        // result
        String result = null;
        CloseableHttpResponse response = null;
        try {
            HttpGet httpPost = new HttpGet(url);
            // 480秒(8分钟) 应该能返回了吧,
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(10_000)
                    .setConnectionRequestTimeout(480_000)
                    .setSocketTimeout(480_000).build();
            httpPost.setConfig(requestConfig);
            if (!CollectionUtils.isEmpty(headers)) {
                headers.forEach((key, value) -> httpPost.setHeader(key, value));
            }
            response = httpClient.execute(httpPost);
            Integer statusCode = response.getStatusLine().getStatusCode();
            Integer SUCCESS_CODE = 200;
            Integer INTERNAL_SERVER_ERROR = 500;
            if (Objects.equals(statusCode, SUCCESS_CODE)) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, Charset.forName("UTF-8"));
                }
                EntityUtils.consume(resEntity);
            } else if (Objects.equals(statusCode, INTERNAL_SERVER_ERROR)) {
                System.err.printf("目标服务器500异常,当前http请求地址:%s, 请求头:%s, %n", url, headers.toString());
                result = null;
            }

//            Header responseHeaders = response.getFirstHeader("content-type");
//            System.out.println("===========================");
//            System.out.println(responseHeaders);
//            System.out.println(responseHeaders.getName());
//            System.out.println(responseHeaders.getValue());
//            System.out.println("===========================");
        } finally {
            if (response != null) {
                response.close();
            }
            // if (httpClient != null) {
            //     httpClient.close();
            // }
        }
        return result;
    }

    /**
     * http请求到百度的接口获取 百度任务接口数据
     *
     * @param url       百度服务器地址   在yml配置文件有保存的, 方法内会加上对应的获取数据接口的路径  "/zebra/carapi/task_data"
     * @param task      任务的id
     * @param data_list 需要返回数据的类型 比如1001,1002
     * @return 返回的json数据, 如果发生异常则返回 ""
     * @throws IOException
     */
    public static String carapi_task_data(String url, String task, String data_list) throws IOException {
        String uploadURL = url + "/zebra/carapi/task_data";
        Map<String, String> headers = new HashMap<>(8);
        headers.put("Content-Type", "application/json;charset=UTF-8");
        // 构造请求json字符串,
        JSONObject json = new JSONObject();
        json.put("task", task);
        json.put("username", "OrangeRun2306");
        json.put("data_list", data_list);
        String resPost = httpPost(uploadURL, headers, json.toString());
        if (resPost != null) {
            try {
                JSONObject resultJson = JSON.parseObject(resPost);
                return resultJson.toString();
            } catch (Exception e) {
                e.printStackTrace();
                return "";
            }
        }
        return "";
    }

    /**
     * 爬取经纬度
     * 1.先按照关键字截取address, 比如 xx区xx号xx档口, 则截取xx区xx号去爬
     * 如果address中未含有关键字则使用address去QQ api搜索
     * <p>
     * 2.截取关键字前4个作为key,比如福华三路268号,截取是268号, 检查返回的地址是否含有268号,如果含有则证明这是符合条件的,或者title中含有关键字,
     * <p>
     * 3.观察发现如果返回的结果只有1条,一般这个结果都是对的
     * <p>
     * TODO 问题?
     * 输入 广东省广州市天河区龙洞商业街广场B25档
     * API返回: 广东省广州市天河区天源路97号龙洞商业广场F1
     * 一个 商业街广场,一个 是商业广场, 一字之差没办法匹配到,即使是正确的地址
     *
     * @param city
     * @param address
     * @param key     qqAPI的key
     * @throws IOException
     */
    public static LngLatMessage getLngLat(String city, String address, String key) throws IOException {
        String _address = formatIllegalString(address);
        // 获取方式
        List<String> METHOD_GETING = Arrays.asList("广场", "号", "办公楼", "大楼", "大厦", "发改楼", "附属楼", "工业楼", "公寓楼", "行政楼", "基金楼", "建贸楼", "教工楼", "酒店 ", "科技楼", "科研楼", "配建楼", "商贸楼", "商夏", "商务楼", "商业楼", "生产楼", "写字楼", "宿舍楼", "研发楼", "招商楼", "中心楼", "综合楼", "花苑", "小区", "花园", "路");
        String methodGet = null;
        for (String s : METHOD_GETING) {
            if (address.contains(s)) {
                methodGet = s;
                break;
            }
        }
        // 如果都没有上列关键字, 就是默认不截取去搜索
        methodGet = methodGet == null ? "default" : methodGet;
        int keyIndex = _address.indexOf(methodGet);
        if (keyIndex > 0) {
            keyIndex += methodGet.length();
        } else {
            keyIndex = _address.length();
        }
        // 按照关键字截取address, 比如 xx区xx号xx档口, 则截取xx区xx号去爬
        String searchAddress = _address.substring(0, keyIndex);
        String url = String.format("https://apis.map.qq.com/ws/place/v1/search?boundary=region(%s,0)&keyword=%s&page_size=20&&page_index=1&orderby=_distance&key=%s",
                city, searchAddress, key);
        String searchResult = HttpUtil.httpGet(url, null);
        // 开始校验API返回结果
        JSONObject jsonObject = JSONObject.parseObject(searchResult);
        Integer count = jsonObject.getInteger("count");
        if (count == null) {
            return null;
        }
        // 4.观察发现如果返回的结果只有1条,一般这个结果都是对的
        if (count == 1) {
            JSONArray dataList = jsonObject.getJSONArray("data");
            JSONObject jsonObject1 = dataList.getJSONObject(0);
            return transform(jsonObject1, methodGet);
        }
        if (count > 0) {
            JSONArray dataList = jsonObject.getJSONArray("data");
            for (int i = 0; i < dataList.size(); i++) {
                JSONObject jsonObject1 = dataList.getJSONObject(i);
                // 截取关键字前4个作为key,比如福华三路268号,截取是268号, 检查返回的地址是否含有268号,如果含有则证明这是符合条件的,或者title中含有关键字,
                String apiResultAddress = jsonObject1.getString("address");
                String title = jsonObject1.getString("title");
                int start = 0;
                if (keyIndex - 4 > 0) {
                    start = keyIndex - 4;
                }
                String verify = _address.substring(start, keyIndex);
                if (!StringUtils.isEmpty(apiResultAddress) && apiResultAddress.contains(verify)) {
                    return transform(jsonObject1, verify);
                }

                if (!StringUtils.isEmpty(title) && title.contains(verify)) {
                    return transform(jsonObject1, title);
                }
            }
        }
        // 如果count等于0 ,有可能在geocoder元素里含有对应的经纬度,所以还要再检查一下
        /**
         {
         "status": 0,
         "message": "query ok",
         "count": 0,
         "request_id": "061140062124e095ce7adeeae2822f92984f726be14d",
         "data": [],
         "region": {
         "title": "广州市"
         },
         "geocoder": {
         "result": {
         "location": {
         "lat": 23.11605,
         "lng": 113.25278
         },
         "address_components": {
         "province": "广东省",
         "city": "广州市",
         "district": "荔湾区",
         "street": "上九路147号",
         "street_number": ""
         },
         "type": "9",
         "similarity": "0.800000"
         }
         }
         }
         */
        JSONObject geocoder = jsonObject.getJSONObject("geocoder");
        if (Objects.nonNull(geocoder)) {
            // 获取其中的地址 和目标地址是否一致
            JSONObject result = geocoder.getJSONObject("result");
            String district = result.getJSONObject("address_components").getString("street");
            if (address.contains(district)) {
                return transform(result, district);
            }
        }
        return null;
    }

    /**
     * 获取该jsonObject对象中的的经纬度和apiAddress, 同时是以什么的样式或者关键字获取的, 转换成LngLatMessage对象
     * 比如输入的是广东省广州市天河区龙洞村商业广场B09档
     * api返回的address是:广东省广州市天河区天源路97号 ,title是:龙洞商业广场 则methodGet是龙洞商业广场
     *
     * @param jsonObject1
     * @param methodGet
     * @return
     */
    private static LngLatMessage transform(JSONObject jsonObject1, String methodGet) {
        JSONObject location = jsonObject1.getJSONObject("location");
        BigDecimal lat = location.getBigDecimal("lat");
        BigDecimal lng = location.getBigDecimal("lng");
        double[] doubles = gcj02tobd09(lng, lat);
        LngLatMessage result = new LngLatMessage();
        result.setLongitudeBd09ll(BigDecimal.valueOf(doubles[0]));
        result.setLatitudeBd09ll(BigDecimal.valueOf(doubles[1]));
        String apiResultAddress = jsonObject1.getString("address");
        result.setApiAddress(apiResultAddress);
        result.setMethodGet(methodGet);
        return result;
    }

    /**
     * 使用百度API爬取经纬度
     *
     * @param city
     * @param address
     * @param key
     * @throws IOException TODO 下列情况怎么处理??
     *                     <p>
     *                     输入地址:广东省广州市花都区新华镇商业大道17-2#
     *                     返回: Results{name='商业大道17号', location=Location{lng=113.215018, lat=23.381118}, address='花都区', province='null', city='null', area='null'}
     *                     <p>
     *                     <p>
     *                     输入地址:广东省广州市天河区龙洞商业街广场B25档
     *                     返回: Results{name='龙洞商业广场', location=Location{lng=113.373722, lat=23.19938}, address='广州市天河区天源路97号', province='广东省', city='广州市', area='天河区'}
     *                     <p>
     *                     输入地址:深圳市福田区福华三路268号 星河Coco Park B1C层87-89单元
     *                     返回:Results{name='福华3路268号', location=Location{lng=114.061449, lat=22.538932}, address='福田区', province='null', city='null', area='null'}
     *                     所以 name也要校验,但是上面这种情况就尴尬了...
     */
    // public static LngLatMessage getLngLatV2(String city, String address, String key) throws IOException {
    //     // key = "0BWdbq69ArmCpXwxwtUCBhnIhNXWfHwd";
    //     String _address = formatIllegalString(address);
    //     // 1.获取方式根据下列关键词去截取地址, 然后到api爬
    //     List<String> METHOD_GETING = Arrays.asList("号", "广场", "办公楼", "大楼", "大厦", "发改楼", "附属楼", "工业楼", "公寓楼", "行政楼", "基金楼", "建贸楼", "教工楼", "酒店 ", "科技楼", "科研楼", "配建楼", "商贸楼", "商夏", "商务楼", "商业楼", "生产楼", "写字楼", "宿舍楼", "研发楼", "招商楼", "中心楼", "综合楼", "花苑", "小区", "花园", "市场", "路");
    //     String methodGet = null;
    //     for (String s : METHOD_GETING) {
    //         if (address.contains(s)) {
    //             methodGet = s;
    //             break;
    //         }
    //     }
    //     // 2.开始截取地址, 然后搜索 如果都没有上列关键字, 就是默认不截取去搜索,
    //     methodGet = methodGet == null ? "default" : methodGet;
    //     int keyIndex = _address.indexOf(methodGet);
    //     if (keyIndex > 0) {
    //         keyIndex += methodGet.length();
    //     } else {
    //         keyIndex = _address.length();
    //     }
    //     // 3.截取
    //     String searchAddress = _address.substring(0, keyIndex);
    //     String url = String.format("http://api.map.baidu.com/place/v2/search?query=%s&region=%s&output=json&ak=%s&tdsourcetag=s_pctim_aiomsg&qq-pf-to=pcqq.c2c",
    //             searchAddress, city, key);
    //     String searchResult = HttpUtil.httpGet(url, null);
    //     // 4.开始校验API返回结果
    //     ObjectMapper objectMapper = new ObjectMapper();
    //     BdResultDTO dto = objectMapper.readValue(searchResult.getBytes(), BdResultDTO.class);
    //     // 4.1 如果返回是ok
    //     if ("ok".equals(dto.getMessage())) {
    //         System.out.println(address);
    //         List<Results> outcome = dto.getResults();
    //         for (Results result : outcome) {
    //             System.out.println(result);
    //             // 4.2 关键字校验
    //             if (!"default".equals(methodGet)) {
    //                 String verify = _address.substring(keyIndex - 4, keyIndex);
    //                 // System.out.println(verify);
    //                 // 这个是要的结果
    //                 if (result.getAddress().contains(verify) || _address.contains(result.getName())) {
    //                     LngLatMessage bx = new LngLatMessage();
    //                     bx.setLongitudeBd09ll(result.getLocation().getLng());
    //                     bx.setLatitudeBd09ll(result.getLocation().getLat());
    //                     bx.setMethodGet(methodGet);
    //                     bx.setApiAddress(result.getAddress());
    //                     return bx;
    //                 }
    //             } else {
    //                 // 4.3 如果没有含有关键字
    //                 if (_address.contains(result.getName())) {
    //                     LngLatMessage bx = new LngLatMessage();
    //                     bx.setLongitudeBd09ll(result.getLocation().getLng());
    //                     bx.setLatitudeBd09ll(result.getLocation().getLat());
    //                     bx.setMethodGet(methodGet);
    //                     bx.setApiAddress(result.getAddress());
    //                     return bx;
    //                 }
    //             }
    //         }
    //
    //     }
    //     System.out.println("==============================================================================================");
    //     return null;
    //
    // }


    /**
     * 腾讯经纬度转百度经纬度,根据平哥提供的方法Python版本改写
     * Python原文:
     * <p>
     * def gcj02tobd09(lng,lat):
     * import math
     * x_pi = 3.14159265358979324 * 3000.0 / 180.0
     * z = math.sqrt(lng * lng + lat * lat) + 0.00002 * math.sin(lat * x_pi)
     * theta = math.atan2(lat, lng) + 0.000003 * math.cos(lng * x_pi)
     * bd_lng = z * math.cos(theta) + 0.0065
     * bd_lat = z * math.sin(theta) + 0.006
     * return [bd_lng, bd_lat]
     *
     * @param lng 腾讯经度
     * @param lat 腾讯纬度
     * @return double[0]:百度经度 double[1]:百度纬度
     */
    private static double[] gcj02tobd09(BigDecimal lng, BigDecimal lat) {
//        String x_pi = "52.35987755982988";
        BigDecimal x_pi = new BigDecimal(String.valueOf(3.14159265358979324 * 3000.0 / 180.0));
//                x_pi = 3.14159265358979324 * 3000.0 / 180.0;
        BigDecimal lngSquare = lng.multiply(lng);
        BigDecimal latSquare = lat.multiply(lat);
        double z = Math.sqrt(lngSquare.add(latSquare).doubleValue()) + 0.00002 * Math.sin(lat.multiply(x_pi).doubleValue());
        double theta = Math.atan2(lat.doubleValue(), lng.doubleValue()) + 0.000003 * Math.cos(lng.multiply(x_pi).doubleValue());
        double bd_lng = z * Math.cos(theta) + 0.0065;
        double bd_lat = z * Math.sin(theta) + 0.006;
        return new double[]{bd_lng, bd_lat};
    }

    public static void main(String[] args) throws IOException {
        // String aa1 = "广东省广州市增城市新塘镇百事佳金泽商业广场";
        // String aa1 = "广东省广州市新塘镇解放路139号";
        // String aa1 = "广东省广州市海珠区沥滘大道北27号之3号首层商铺";  // 失败了
        // String aa1 = "深圳市龙华区坂田街道华南物流8号仓特斯拉服务中心";
        String aa1 = "深圳市福田区福华三路268号 星河Coco Park B1C层87-89单元";
        // int i = aa1.indexOf("default");
        // System.out.println(i);
        // String substring = aa1.substring(0, aa1.length());
        // System.out.println(substring);
        // if (true) {
        //     return;
        // }
        //
        // double d = 3.14159265358979324 * 3000.0 / 180.0;
        // System.out.println(d);
        // BigDecimal lat = new BigDecimal("23.115644");
        // BigDecimal lng = new BigDecimal("113.331314");
        // System.out.println(gcj02tobd09(lng, lat)[0]);
        // System.out.println(gcj02tobd09(lng, lat)[1]);
        // // 用Python转换后的结果 [113.33786198126332, 23.12133564646517]
        //
        // System.out.println(formatIllegalString("广东省广州市白云区白云大道北东平路口往太和方向1公里(城门河货运市场内) "));
        String key = "Q2UBZ-MF53V-XIZPR-UIS5Q-EKNQK-IPB2Q";
        // LngLatMessage aa = getLngLat("广州", "广东省广州市白云区白云大道北东平路口往太和方向1公里(城门河货运市场内) ", key);

        // String key = "0BWdbq69ArmCpXwxwtUCBhnIhNXWfHwd";
        LngLatMessage 广州 = getLngLat("深圳", aa1, key);
        System.out.println(广州);

    }

    /**
     * 将Excel对象XSSFWorkbook 返回给客户端下载
     *
     * @param workbook Excel对象
     * @param fileName 文件名称
     * @param response httpServletResponse
     * @throws UnsupportedEncodingException
     */
    public static void httpOutPutExcel(Workbook workbook, String fileName, HttpServletResponse response) throws UnsupportedEncodingException {
        response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        // 下载文件能正常显示中文
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        OutputStream os = null;
        try {
            os = response.getOutputStream();
            workbook.write(os);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (workbook != null) {
                    workbook.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 输出文本内容
     *
     * @param content 文本内容
     * @param response httpServletResponse
     * @throws UnsupportedEncodingException
     */
    public static void httpOutString( String content, HttpServletResponse response) throws UnsupportedEncodingException {
        OutputStream os = null;
        response.setHeader("content-type", "text/html;charset=utf-8");
        try {
            os = response.getOutputStream();
            os.write(content.getBytes("UTF-8"));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 使用正则表达式  删除掉input字符串中的那些非法字符串
     *
     * @param s
     * @return
     */
    public static String formatIllegalString(String s) {
        if (StringUtils.isEmpty(s)) {
            return "";
        }
        Matcher matcher = ILLEGAL_STRING_PATTERN.matcher(s);
        String trim = matcher.replaceAll("").trim();
        Matcher matcher1 = CRLF.matcher(trim);
        return matcher1.replaceAll("").trim();
    }


    private static class Location implements Serializable {
        static final long serialVersionUID = 42L;
        BigDecimal lng;
        BigDecimal lat;

        public BigDecimal getLng() {
            return lng;
        }

        public void setLng(BigDecimal lng) {
            this.lng = lng;
        }

        public BigDecimal getLat() {
            return lat;
        }

        public void setLat(BigDecimal lat) {
            this.lat = lat;
        }

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder("Location{");
            sb.append("lng=").append(lng);
            sb.append(", lat=").append(lat);
            sb.append('}');
            return sb.toString();
        }
    }

    /**
     * 封装百度api返回结果
     */
    // 加入这个注解是因为json有些字段, 在该类没有定义的话,则忽略, 否则会报错的
    @JsonIgnoreProperties(ignoreUnknown = true)
    private static class Results implements Serializable {
        static final long serialVersionUID = 42L;

        String name;
        Location location;
        String address;
        String province;
        String city;
        /**
         * 区
         */
        String area;

        public static long getSerialVersionUID() {
            return serialVersionUID;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Location getLocation() {
            return location;
        }

        public void setLocation(Location location) {
            this.location = location;
        }

        public String getAddress() {
            return address;
        }

        public void setAddress(String address) {
            this.address = address;
        }

        public String getProvince() {
            return province;
        }

        public void setProvince(String province) {
            this.province = province;
        }

        public String getCity() {
            return city;
        }

        public void setCity(String city) {
            this.city = city;
        }

        public String getArea() {
            return area;
        }

        public void setArea(String area) {
            this.area = area;
        }

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder("Results{");
            sb.append("name='").append(name).append('\'');
            sb.append(", location=").append(location);
            sb.append(", address='").append(address).append('\'');
            sb.append(", province='").append(province).append('\'');
            sb.append(", city='").append(city).append('\'');
            sb.append(", area='").append(area).append('\'');
            sb.append('}');
            return sb.toString();
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    private static class BdResultDTO implements Serializable {
        static final long serialVersionUID = 42L;
        Integer status;
        String message;
        List<Results> results;

        public static long getSerialVersionUID() {
            return serialVersionUID;
        }

        public Integer getStatus() {
            return status;
        }

        public void setStatus(Integer status) {
            this.status = status;
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public List<Results> getResults() {
            return results;
        }

        public void setResults(List<Results> results) {
            this.results = results;
        }

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder("BdResultDTO{");
            sb.append("status=").append(status);
            sb.append(", message='").append(message).append('\'');
            sb.append(", results=").append(results);
            sb.append('}');
            return sb.toString();
        }
    }


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值