|
@@ -0,0 +1,280 @@
|
|
|
|
+package cn.org.bjca.trust.java.imserver;
|
|
|
|
+
|
|
|
|
+import cn.org.bjca.trust.java.imserver.common.json.GsonImplHelp;
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.springframework.http.*;
|
|
|
|
+import org.springframework.http.client.ClientHttpResponse;
|
|
|
|
+import org.springframework.util.LinkedMultiValueMap;
|
|
|
|
+import org.springframework.util.MultiValueMap;
|
|
|
|
+import org.springframework.web.client.ResponseErrorHandler;
|
|
|
|
+import org.springframework.web.client.RestTemplate;
|
|
|
|
+
|
|
|
|
+import java.io.*;
|
|
|
|
+import java.net.URLEncoder;
|
|
|
|
+import java.util.*;
|
|
|
|
+import java.util.zip.GZIPInputStream;
|
|
|
|
+
|
|
|
|
+import static org.springframework.http.HttpMethod.GET;
|
|
|
|
+import static org.springframework.http.HttpMethod.POST;
|
|
|
|
+
|
|
|
|
+@Slf4j
|
|
|
|
+public class CurlUtil {
|
|
|
|
+ // 请求结果
|
|
|
|
+ private String result = "";
|
|
|
|
+
|
|
|
|
+ /*** RestTemplate 请求构造内部类*/
|
|
|
|
+ public static class Builder {
|
|
|
|
+ // 请求URL
|
|
|
|
+ private String url;
|
|
|
|
+ // basic auth用户名
|
|
|
|
+ private String userName;
|
|
|
|
+ // basic auth密码
|
|
|
|
+ private String passWord;
|
|
|
|
+ // 请求方式 默认为GET
|
|
|
|
+ private HttpMethod methodType = GET;
|
|
|
|
+ // 请求参数
|
|
|
|
+ private HashMap<String, String> paramMap;
|
|
|
|
+ // 请求header头
|
|
|
|
+ private HashMap<String, String> headerMap;
|
|
|
|
+ // RestTemplate 实例
|
|
|
|
+ private RestTemplate client;
|
|
|
|
+ // header头实例
|
|
|
|
+ private HttpHeaders headers;
|
|
|
|
+ // 请求结果
|
|
|
|
+ private String result;
|
|
|
|
+
|
|
|
|
+ /*** 基础请求* @param url*/
|
|
|
|
+ public Builder(String url) {
|
|
|
|
+ this.url = url;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /*** basic auth 认证类型请求* @param url* @param userName* @param passWord*/
|
|
|
|
+ public Builder(String url, String userName, String passWord) {
|
|
|
|
+ this.url = url;
|
|
|
|
+ this.userName = userName;
|
|
|
|
+ this.passWord = passWord;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** 添加参数* @param key 参数key* @param value 参数内容* @return Builder*/
|
|
|
|
+ public Builder addParam(String key, String value) {
|
|
|
|
+ if (paramMap == null) {
|
|
|
|
+ paramMap = new LinkedHashMap<>(16);
|
|
|
|
+ }
|
|
|
|
+ paramMap.put(key, value);
|
|
|
|
+ return this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** 添加header参数* @param key 参数key* @param value 参数内容* @return Builder*/
|
|
|
|
+ public Builder addHeader(String key, String value) {
|
|
|
|
+ if (headerMap == null) {
|
|
|
|
+ headerMap = new LinkedHashMap<>(16);
|
|
|
|
+ }
|
|
|
|
+ headerMap.put(key, value);
|
|
|
|
+ return this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** GET 请求* @return Curl*/
|
|
|
|
+ public CurlUtil get() {
|
|
|
|
+ this.methodType = GET;
|
|
|
|
+ this.getResponse(MediaType.APPLICATION_FORM_URLENCODED);
|
|
|
|
+ return new CurlUtil(this);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** post 请求* @return Curl*/
|
|
|
|
+ public CurlUtil post() {
|
|
|
|
+ this.methodType = POST;
|
|
|
|
+ this.getResponse(MediaType.APPLICATION_FORM_URLENCODED);
|
|
|
|
+ return new CurlUtil(this);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** raw 方式提交json 请求* @return Curl*/
|
|
|
|
+ public CurlUtil postRaw() {
|
|
|
|
+ HashMap<String, Object> paramRawMap = new HashMap<>();
|
|
|
|
+ return this.raw(paramRawMap);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** raw 方式提交json 请求* @param paramRawMap Map数据* @return Curl*/
|
|
|
|
+ public CurlUtil postRaw(HashMap<String, Object> paramRawMap) {
|
|
|
|
+ return this.raw(paramRawMap);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** RAW 请求* @param paramRawMap 参数* @return*/
|
|
|
|
+ private CurlUtil raw(HashMap<String, Object> paramRawMap) {
|
|
|
|
+ client = new RestTemplate();
|
|
|
|
+ client.setErrorHandler(new RestErrorHandler());
|
|
|
|
+ headers = new HttpHeaders();
|
|
|
|
+ headers.setContentType(MediaType.APPLICATION_JSON);
|
|
|
|
+ this.setHeadersMapData();
|
|
|
|
+ this.responseRawExchange(GsonImplHelp.get().toJson(paramRawMap));
|
|
|
|
+ return new CurlUtil(this);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** 初始化请求体* @param type 请求类型*/
|
|
|
|
+ private void getResponse(MediaType type) {
|
|
|
|
+ client = new RestTemplate();
|
|
|
|
+ client.setErrorHandler(new RestErrorHandler());
|
|
|
|
+ headers = new HttpHeaders();
|
|
|
|
+ headers.setContentType(type);
|
|
|
|
+ this.setHeadersMapData();
|
|
|
|
+ MultiValueMap<String, String> params = this.setHttpMethodParamsMap();
|
|
|
|
+ this.responseExchange(params);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** 设置header头数据*/
|
|
|
|
+ private void setHeadersMapData() {
|
|
|
|
+ if (headerMap != null) {
|
|
|
|
+ headerMap.forEach((k, v) -> {
|
|
|
|
+ this.headers.set(k, v);
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ // 设置basic auth请求方式认证信息
|
|
|
|
+ if (this.userName != null && this.passWord != null) {
|
|
|
|
+ String secretKey = this.userName + ":" + this.passWord;
|
|
|
|
+ String authValue = "Basic " + Base64.getEncoder().encodeToString(secretKey.getBytes());
|
|
|
|
+ this.headers.set("Authorization", authValue);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** 组装请求体参数* @return MultiValueMap<String, String>*/
|
|
|
|
+ private MultiValueMap<String, String> setHttpMethodParamsMap() {
|
|
|
|
+ MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
|
|
|
|
+ if (this.methodType.equals(GET)) {
|
|
|
|
+ if (this.paramMap != null) {
|
|
|
|
+ String _UrlParams = getUrlParamsByMap(this.paramMap);
|
|
|
|
+ this.url = this.url + "?" + _UrlParams;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.paramMap != null) {
|
|
|
|
+ this.paramMap.forEach((k, v) -> {
|
|
|
|
+ params.put(k, Collections.singletonList(v));
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ } else if (this.methodType.equals(POST)) {
|
|
|
|
+ if (this.paramMap != null) {
|
|
|
|
+ this.paramMap.forEach((k, v) -> {
|
|
|
|
+ params.put(k, Collections.singletonList(v));
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return params;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** 执行Curl请求操作* @param params 请求体参数*/
|
|
|
|
+ private void responseExchange(MultiValueMap<String, String> params) {
|
|
|
|
+ HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, this.headers);
|
|
|
|
+ // 执行HTTP请求,将返回的结构使用spring ResponseEntity处理http响应
|
|
|
|
+ ResponseEntity<byte[]> responseEntity = this.client.exchange(this.url, this.methodType, requestEntity, byte[].class);
|
|
|
|
+ String contentEncoding = responseEntity.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING);
|
|
|
|
+ int httpCode = responseEntity.getStatusCodeValue();
|
|
|
|
+ String httpCodeValue = responseEntity.getStatusCode().toString();
|
|
|
|
+ log.info("状态码:{}", httpCodeValue);
|
|
|
|
+ try {
|
|
|
|
+ if ("gzip".equals(contentEncoding)) {
|
|
|
|
+ // gzip解压服务器的响应体
|
|
|
|
+ byte[] data = unGZip(new ByteArrayInputStream(responseEntity.getBody()));
|
|
|
|
+ // log.info(new String(data, StandardCharsets.UTF_8));
|
|
|
|
+ this.result = new String(data);
|
|
|
|
+ } else {
|
|
|
|
+ // 其他编码暂时不做处理(如果需要处理其他编码请自行扩展)
|
|
|
|
+ this.result = new String(responseEntity.getBody());
|
|
|
|
+ }
|
|
|
|
+ } catch (NullPointerException e) {
|
|
|
|
+ log.error("请求错误: {}", e.getMessage());
|
|
|
|
+ this.result = httpCodeValue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** 执行Curl Raw JSON请求操作* @param params 请求体参数*/
|
|
|
|
+ private void responseRawExchange(String params) {
|
|
|
|
+ HttpEntity<String> requestEntity = new HttpEntity<>(params, this.headers);
|
|
|
|
+ // 执行HTTP请求,将返回的结构使用spring ResponseEntity处理http响应
|
|
|
|
+ ResponseEntity<byte[]> responseEntity = this.client.postForEntity(this.url, requestEntity, byte[].class);
|
|
|
|
+ String contentEncoding = responseEntity.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING);
|
|
|
|
+ if ("gzip".equals(contentEncoding)) {
|
|
|
|
+ // gzip解压服务器的响应体
|
|
|
|
+ byte[] data = unGZip(new ByteArrayInputStream(responseEntity.getBody()));
|
|
|
|
+ this.result = new String(data);
|
|
|
|
+ } else {
|
|
|
|
+ // 其他编码暂时不做处理(如果需要处理其他编码请自行扩展)
|
|
|
|
+ this.result = new String(responseEntity.getBody());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** Gzip解压缩* @param inputStream 数据流* @return byte[]*/
|
|
|
|
+ private byte[] unGZip(InputStream inputStream) {
|
|
|
|
+ byte[] result = null;
|
|
|
|
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
|
|
+ try {
|
|
|
|
+ try (GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream)) {
|
|
|
|
+ byte[] buf = new byte[4096];
|
|
|
|
+ int len = -1;
|
|
|
|
+ while ((len = gzipInputStream.read(buf, 0, buf.length)) != -1) {
|
|
|
|
+ byteArrayOutputStream.write(buf, 0, len);
|
|
|
|
+ }
|
|
|
|
+ result = byteArrayOutputStream.toByteArray();
|
|
|
|
+ } finally {
|
|
|
|
+ byteArrayOutputStream.close();
|
|
|
|
+ }
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ log.error("unGZip error :", e);
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** 组装GET参数* @param params 参数* @return String*/
|
|
|
|
+ private String getUrlParamsByMap(Map<String, String> params) {
|
|
|
|
+ List<String> keys = new ArrayList<String>(params.keySet());
|
|
|
|
+ Collections.sort(keys);
|
|
|
|
+ String prestr = "";
|
|
|
|
+ try {
|
|
|
|
+ for (int i = 0; i < keys.size(); i++) {
|
|
|
|
+ String key = keys.get(i);
|
|
|
|
+ String value = params.get(key);
|
|
|
|
+ value = URLEncoder.encode(value, "UTF-8");
|
|
|
|
+ if (i == keys.size() - 1) {
|
|
|
|
+ //拼接时,不包括最后一个&字符
|
|
|
|
+ prestr = prestr + key + "=" + value;
|
|
|
|
+ } else {
|
|
|
|
+ prestr = prestr + key + "=" + value + "&";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (UnsupportedEncodingException e) {
|
|
|
|
+ log.error("GET params error: {}", e);
|
|
|
|
+ }
|
|
|
|
+ return prestr;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** RestTemplate 异常处理*/
|
|
|
|
+ public static class RestErrorHandler implements ResponseErrorHandler {
|
|
|
|
+ /*** 判断返回结果response是否是异常结果* 主要是去检查response 的HTTP Status* 仿造DefaultResponseErrorHandler实现即可*/
|
|
|
|
+ @Override
|
|
|
|
+ public boolean hasError(ClientHttpResponse response) throws IOException {
|
|
|
|
+ int rawStatusCode = response.getRawStatusCode();
|
|
|
|
+ HttpStatus statusCode = HttpStatus.resolve(rawStatusCode);
|
|
|
|
+ return (statusCode != null ? statusCode.isError() : hasError(rawStatusCode));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ protected boolean hasError(int unknownStatusCode) {
|
|
|
|
+ HttpStatus.Series series = HttpStatus.Series.resolve(unknownStatusCode);
|
|
|
|
+ return (series == HttpStatus.Series.CLIENT_ERROR || series == HttpStatus.Series.SERVER_ERROR);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void handleError(ClientHttpResponse response) throws IOException {
|
|
|
|
+ log.error("handleError:", response);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** CurlUtil 实例化* @param builder*/
|
|
|
|
+ public CurlUtil(Builder builder) {
|
|
|
|
+ this.result = builder.result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*** 结果* @return*/
|
|
|
|
+ public String build() {
|
|
|
|
+ return this.result;
|
|
|
|
+ }
|
|
|
|
+}
|