PolyvHttpUtil.java 15.2 KB
Newer Older
F
fengyw 已提交
1
package com.roncoo.education.common.video.impl.polyv;
F
fengyw 已提交
2

3 4
import com.roncoo.education.common.core.tools.JSUtil;
import lombok.extern.slf4j.Slf4j;
F
fengyw 已提交
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
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
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.methods.HttpUriRequest;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.*;

/**
 * @author: sadboy
 **/
30
@Slf4j
F
fengyw 已提交
31
public class PolyvHttpUtil {
32 33 34 35 36

    public static final String KEY = "rc-education";
    public static final String SUCCESS_STATUS = "success";
    public static final Integer SUCCESS_CODE = 200;

F
fengyw 已提交
37 38 39 40 41 42
    private static final String UTF8 = "UTF-8";
    private static final String APPLICATION_FORM_URLENCODED = "application/x-www-form-urlencoded; charset=UTF-8";
    private static final String APPLICATION_JSON = "application/json; charset=UTF-8";
    private static final String TEXT_PLAIN = "text/plain; charset=UTF-8";
    private static final String TEXT_HTML = "text/html; charset=UTF-8";
    private static final String APPLICATION_XML = "application/xml; charset=UTF-8";
43

F
fengyw 已提交
44 45
    private PolyvHttpUtil() {
    }
46 47


F
fengyw 已提交
48 49
    /**
     * 向url发送get请求
50 51
     *
     * @param url      请求url
F
fengyw 已提交
52 53 54 55
     * @param paramMap 需要拼接的参数
     * @return 请求返回的数据
     * @throws IOException 读写异常
     */
56 57 58 59 60 61 62 63
    public static String get(String url, Map<String, Object> paramMap) {
        try {
            url = appendUrl(url, paramMap);
            return get(url, UTF8, EntityUtils::toString);
        } catch (Exception e) {
            log.error("请求错误,url={}", url, e);
            return "";
        }
F
fengyw 已提交
64
    }
65

F
fengyw 已提交
66 67
    /**
     * HTTP GET 内部公共请求处理逻辑
68 69 70
     *
     * @param url       请求地址
     * @param encoding  编码字符集, 默认为 utf-8
F
fengyw 已提交
71 72 73 74 75
     * @param dataParse 返回数据反序列化逻辑实现类
     * @return HTTP 返回的内容
     * @throws IOException 客户端和服务器读写通讯异常
     */
    private static <T> T get(String url, String encoding, DataParse<T> dataParse) throws IOException {
76
        log.debug("http get url: {}", url);
F
fengyw 已提交
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
        T result = null;
        // 创建httpclient对象
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 创建get方式请求对象
        HttpGet httpGet = new HttpGet(url);
        httpGet.addHeader("Content-type", APPLICATION_JSON);
        // 通过请求对象获取响应对象
        CloseableHttpResponse response = sendRequestAndGetResult(url, httpClient, httpGet);
        // 获取结果实体
        if (null != response) {
            result = dataParse.parseData(response.getEntity(), encoding);
            if (!(result instanceof byte[])) {
                log.debug("http 请求结果: {}", result);
            } else {
                Header[] headers = response.getHeaders("Content-Type");
                for (Header responseHead : headers) {
                    String headStr = responseHead.getValue();
                    if (headStr.startsWith("application/json")) {
                        String json = new String((byte[]) result);
                        response.close();
                        throw new RuntimeException(json);
                    }
                }
            }
        }
        try {
            if (null != response) {
                response.close();
            }
        } catch (IOException ex) {
            log.error(ex.getMessage(), ex);
        }
        return result;
    }
111

F
fengyw 已提交
112 113
    /**
     * 向url发送post请求表单提交数据
114 115
     *
     * @param url      请求url
F
fengyw 已提交
116 117 118 119
     * @param paramMap 表单数据
     * @return 请求返回的数据
     * @throws IOException 读写异常
     */
120
    public static String post(String url, Map<String, Object> paramMap) {
F
fengyw 已提交
121 122 123 124
        log.debug("http 请求 url: {} , 请求参数: {}", url, appendUrl("", paramMap).replace("?", ""));
        // 创建post方式请求对象
        HttpPost httpPost = new HttpPost(url);
        // 装填参数
125
        List<NameValuePair> nameValuePairs = new ArrayList<>();
F
fengyw 已提交
126
        if (paramMap != null) {
127 128
            for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
                String value = entry.getValue().toString();
F
fengyw 已提交
129 130 131 132 133 134 135
                //去掉如下判断会造成String类型的value为null时
                if (value != null) {
                    nameValuePairs.add(new BasicNameValuePair(entry.getKey(), value));
                }
            }
        }
        // 设置参数到请求对象中
136 137 138 139 140
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, UTF8));
        } catch (UnsupportedEncodingException e) {
            log.error("请求异常,url={}, paramMap={}", url, JSUtil.toJsonString(paramMap), e);
        }
F
fengyw 已提交
141 142 143
        // 设置header信息
        // 指定报文头【Content-type】、【User-Agent】
        httpPost.setHeader("Content-type", APPLICATION_FORM_URLENCODED);
144
        return post(url, httpPost, UTF8, EntityUtils::toString);
F
fengyw 已提交
145
    }
146

F
fengyw 已提交
147 148
    /**
     * 向url发送post请求发送json
149
     *
F
fengyw 已提交
150
     * @param url 请求url
151 152 153 154 155 156 157 158 159 160 161
     * @return 请求返回的数据
     * @throws IOException 读写异常
     */
    public static String postForJson(String url, Map<String, Object> paramMap) {
        return postForJson(url, paramMap, "");
    }

    /**
     * 向url发送post请求发送json
     *
     * @param url  请求url
F
fengyw 已提交
162 163 164 165
     * @param json json字符串
     * @return 请求返回的数据
     * @throws IOException 读写异常
     */
166
    public static String postForJson(String url, Map<String, Object> paramMap, String json) {
F
fengyw 已提交
167
        // 创建post方式请求对象
168
        url = appendUrl(url, paramMap);
F
fengyw 已提交
169 170 171 172
        HttpPost httpPost = new HttpPost(url);
        // 设置参数到请求对象中
        StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);
        //  Constant.UTF8
173
        stringEntity.setContentEncoding(UTF8);
F
fengyw 已提交
174
        httpPost.setEntity(stringEntity);
175
        return post(url, httpPost, UTF8, EntityUtils::toString);
F
fengyw 已提交
176
    }
177

F
fengyw 已提交
178 179
    /**
     * 向url发送post请求
180 181
     *
     * @param url      请求url
F
fengyw 已提交
182 183 184 185
     * @param httpPost httpClient
     * @return 请求返回的数据
     * @throws IOException 读写异常
     */
186 187 188
    private static <T> T post(String url, HttpPost httpPost, String encoding, DataParse<T> dataParse) {
        log.debug("http post url: {} , 请求参数: {}", url, JSUtil.toJsonString(httpPost));

F
fengyw 已提交
189
        T result = null;
190
        CloseableHttpResponse response;
F
fengyw 已提交
191 192 193
        // 创建httpclient对象
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        try {
194 195 196 197 198 199 200 201 202
            // 执行请求操作,并拿到结果(同步阻塞)
            response = sendRequestAndGetResult(url, httpClient, httpPost);
            // 获取结果实体
            // 判断网络连接状态码是否正常(0--200都数正常)
            if (null != response) {
                result = dataParse.parseData(response.getEntity(), encoding);
                log.debug("http 请求结果: {}", result);
            }

F
fengyw 已提交
203 204 205 206 207 208 209 210
            if (null != response) {
                response.close();
            }
        } catch (IOException ex) {
            log.error(ex.getMessage(), ex);
        }
        return result;
    }
211

F
fengyw 已提交
212 213
    /**
     * 设置http头,发送http请求,打印请求耗时
214 215 216
     *
     * @param url            请求url
     * @param httpClient     httpClient
F
fengyw 已提交
217 218 219 220
     * @param httpUriRequest httpUriRequest
     * @return 请求返回的数据
     * @throws IOException 读写异常
     */
221
    private static CloseableHttpResponse sendRequestAndGetResult(String url, CloseableHttpClient httpClient, HttpUriRequest httpUriRequest) throws IOException {
F
fengyw 已提交
222 223 224 225 226 227
        long startTime = System.currentTimeMillis();
        CloseableHttpResponse response = httpClient.execute(httpUriRequest);
        long endTime = System.currentTimeMillis();
        collectAPISpendTime(url, startTime, endTime);
        return response;
    }
228 229


F
fengyw 已提交
230 231
    /**
     * 向url发送post请求上传单文件
232 233
     *
     * @param url      请求url
F
fengyw 已提交
234
     * @param paramMap 需要表单提交的参数
235
     * @param fileMap  需要上传的文件
F
fengyw 已提交
236 237 238 239
     * @param encoding 编码
     * @return 请求返回的数据
     * @throws IOException 读写异常
     */
240
    public static String postFile(String url, Map<String, Object> paramMap, Map<String, File> fileMap, String encoding)
F
fengyw 已提交
241 242
            throws IOException {
        if (fileMap != null) {
243
            Map<String, List<File>> fileListMap = new HashMap<>();
F
fengyw 已提交
244 245
            for (Map.Entry<String, File> entry : fileMap.entrySet()) {
                File file = entry.getValue();
246
                List<File> fileList = new ArrayList<>();
F
fengyw 已提交
247 248 249 250 251 252 253
                fileList.add(file);
                fileListMap.put(entry.getKey(), fileList);
            }
            return postMultipleFile(url, paramMap, fileListMap, encoding);
        }
        return postMultipleFile(url, paramMap, null, encoding);
    }
254

F
fengyw 已提交
255 256 257
    /**
     * 向url发送post请求上传多文件
     * 向url发送post请求上传单文件
258 259 260
     *
     * @param url         请求url
     * @param paramMap    需要表单提交的参数
F
fengyw 已提交
261
     * @param fileListMap 需要上传的文件
262
     * @param encoding    编码
F
fengyw 已提交
263 264 265
     * @return 请求返回的数据
     * @throws IOException 读写异常
     */
266 267 268
    public static String postMultipleFile(String url, Map<String, Object> paramMap, Map<String, List<File>> fileListMap,
                                          String encoding) throws IOException {
        return postFileBody(url, paramMap, fileListMap, encoding, EntityUtils::toString);
F
fengyw 已提交
269
    }
270

F
fengyw 已提交
271 272 273
    /**
     * 向url发送post请求上传多文件
     * 向url发送post请求上传单文件
274 275 276
     *
     * @param url         请求url
     * @param paramMap    需要表单提交的参数
F
fengyw 已提交
277
     * @param fileListMap 需要上传的文件
278
     * @param encoding    编码
F
fengyw 已提交
279 280 281
     * @return 请求返回的数据
     * @throws IOException 读写异常
     */
282 283
    private static <T> T postFileBody(String url, Map<String, Object> paramMap, Map<String, List<File>> fileListMap,
                                      String encoding, DataParse<T> dataParse) throws IOException {
F
fengyw 已提交
284 285 286 287 288 289
        log.debug("http 请求 url: {} , 请求参数: {}", url, appendUrl("", paramMap).replace("?", ""));
        encoding = encoding == null ? UTF8 : encoding;
        T result = null;
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost httpPost = new HttpPost(url);
        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
290

F
fengyw 已提交
291 292
        ContentType contentType = ContentType.create("text/plain", Charset.forName(encoding));
        if (null != paramMap) {
293 294
            for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
                entityBuilder.addTextBody(entry.getKey(), entry.getValue().toString(), contentType);
F
fengyw 已提交
295 296
            }
        }
297

F
fengyw 已提交
298 299 300 301 302 303 304 305 306 307
        if (null != fileListMap) {
            for (Map.Entry<String, List<File>> entry : fileListMap.entrySet()) {
                String key = entry.getKey();
                List<File> fileList = entry.getValue();
                for (File file : fileList) {
                    FileBody fileBody = new FileBody(file);
                    entityBuilder.addPart(key, fileBody);
                }
            }
        }
308

F
fengyw 已提交
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
        HttpEntity entity = entityBuilder.build();
        httpPost.setEntity(entity);
        CloseableHttpResponse response = sendRequestAndGetResult(url, httpClient, httpPost);
        if (null != response) {
            result = dataParse.parseData(response.getEntity(), encoding);
            log.debug("http 请求结果: {}", result);
        }
        try {
            if (null != response) {
                response.close();
            }
        } catch (IOException ex) {
            log.error(ex.getMessage(), ex);
        }
        return result;
    }
325

F
fengyw 已提交
326 327
    /**
     * 将url与map拼接成HTTP查询字符串
328 329
     *
     * @param url      请求url
F
fengyw 已提交
330 331 332
     * @param paramMap 需要拼装的map
     * @return 拼装好的url
     */
333
    public static String appendUrl(String url, Map<String, Object> paramMap) {
F
fengyw 已提交
334 335 336 337
        if (paramMap == null) {
            return url;
        }
        StringBuffer paramStringBuffer = new StringBuffer();
338
        Iterator<Map.Entry<String, Object>> mapIterator = paramMap.entrySet().iterator();
F
fengyw 已提交
339
        while (mapIterator.hasNext()) {
340 341 342 343 344 345
            Map.Entry<String, Object> next = mapIterator.next();
            try {
                paramStringBuffer.append(next.getKey()).append("=").append(URLEncoder.encode(next.getValue().toString(), UTF8)).append("&");
            } catch (UnsupportedEncodingException e) {
                log.error("错误", e);
            }
F
fengyw 已提交
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
        }
        String paramStr = paramStringBuffer.toString();
        if (paramStr != null && !"".equals(paramStr)) {
            if (url.indexOf("?") > 0) {
                if (url.endsWith("&")) {
                    url += paramStr.substring(0, paramStr.length() - 1);
                } else {
                    url += "&" + paramStr.substring(0, paramStr.length() - 1);
                }
            } else {
                url += "?" + paramStr.substring(0, paramStr.length() - 1);
            }
        }
        return url;
    }
361

F
fengyw 已提交
362 363
    /**
     * 把二进制写入文件
364
     *
F
fengyw 已提交
365 366 367 368
     * @param bytes
     * @param path
     * @throws IOException
     */
369
    private static void writeFile(byte[] bytes, String path) throws IOException {
F
fengyw 已提交
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
        OutputStream os = null;
        try {
            // 根据绝对路径初始化文件
            File localFile = new File(path);
            if (!localFile.exists()) {
                boolean newFile = localFile.createNewFile();
                if (!newFile) {
                    throw new RuntimeException("创建文件异常,路径:" + path);
                }
            }
            // 输出流
            os = new FileOutputStream(localFile);
            os.write(bytes);
        } finally {
            if (os != null) {
                os.close();
            }
        }
    }
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419

    /**
     * 公共数据解析接口
     *
     * @param <T>
     */
    private interface DataParse<T> {
        /**
         * 解析返回数据
         *
         * @param httpEntity 返回实体
         * @param encoding   编码
         * @return 实际解析返回内容
         * @throws IOException io异常
         */
        T parseData(HttpEntity httpEntity, String encoding) throws IOException;

    }

    /**
     * 打印请求信息
     *
     * @param url       请求url
     * @param startTime 请求开始时间
     * @param endTime   请求结束时间
     */
    private static void collectAPISpendTime(String url, long startTime, long endTime) {
        log.debug("HTTP请求耗时分析,请求URL: {} , 耗时: {} ms", url, endTime - startTime);
    }


F
fengyw 已提交
420 421
}