diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpRequestTemplate.java b/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpRequestTemplate.java index b7b1ed3..218a26e 100644 --- a/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpRequestTemplate.java +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpRequestTemplate.java @@ -1,11 +1,17 @@ package com.egzosn.pay.common.http; -import com.egzosn.pay.common.bean.MethodType; -import com.egzosn.pay.common.bean.result.PayException; -import com.egzosn.pay.common.exception.PayErrorException; -import com.egzosn.pay.common.util.str.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.util.Map; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; + +import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; @@ -23,24 +29,22 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.ssl.SSLContexts; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.NoSuchAlgorithmException; -import java.util.Map; +import com.egzosn.pay.common.bean.MethodType; +import com.egzosn.pay.common.bean.result.PayException; +import com.egzosn.pay.common.exception.PayErrorException; +import com.egzosn.pay.common.util.str.StringUtils; /** * http请求工具 + * * @author egan - * + * * email egzosn@gmail.com
* date 2017/3/3 21:33 - *
+ *
*/ public class HttpRequestTemplate { @@ -55,8 +59,10 @@ public class HttpRequestTemplate { protected HttpConfigStorage configStorage; private SSLConnectionSocketFactory sslsf; + /** - * 获取代理带代理地址的 HttpHost + * 获取代理带代理地址的 HttpHost + * * @return 获取代理带代理地址的 HttpHost */ public HttpHost getHttpProxy() { @@ -98,7 +104,8 @@ public class HttpRequestTemplate { } /** - * 初始化 + * 初始化 + * * @param configStorage 请求配置 */ public HttpRequestTemplate(HttpConfigStorage configStorage) { @@ -111,24 +118,26 @@ public class HttpRequestTemplate { /** - * 创建ssl配置 + * 创建ssl配置 + * * @param configStorage 请求配置 * @return SSLConnectionSocketFactory Layered socket factory for TLS/SSL connections. */ - public SSLConnectionSocketFactory createSSL( HttpConfigStorage configStorage){ - if (null != sslsf){ + public SSLConnectionSocketFactory createSSL(HttpConfigStorage configStorage) { + if (null != sslsf) { return sslsf; } - if (null == configStorage.getKeystore()){ + if (null == configStorage.getKeystore()) { try { return sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault()); - } catch (NoSuchAlgorithmException e) { + } + catch (NoSuchAlgorithmException e) { LOG.error("", e); } } //读取本机存放的PKCS12证书文件 - try(InputStream instream = configStorage.getKeystoreInputStream()){ + try (InputStream instream = configStorage.getKeystoreInputStream()) { //指定读取证书格式为PKCS12 KeyStore keyStore = KeyStore.getInstance("PKCS12"); @@ -148,9 +157,11 @@ public class HttpRequestTemplate { new DefaultHostnameVerifier()); return sslsf; - } catch (IOException e) { + } + catch (IOException e) { LOG.error("", e); - } catch (GeneralSecurityException e) { + } + catch (GeneralSecurityException e) { LOG.error("", e); } return null; @@ -159,10 +170,11 @@ public class HttpRequestTemplate { /** * 创建凭据提供程序 + * * @param configStorage 请求配置 * @return 凭据提供程序 */ - public CredentialsProvider createCredentialsProvider(HttpConfigStorage configStorage){ + public CredentialsProvider createCredentialsProvider(HttpConfigStorage configStorage) { if (StringUtils.isBlank(configStorage.getAuthUsername())) { @@ -181,20 +193,21 @@ public class HttpRequestTemplate { /** * 初始化连接池 + * * @param configStorage 配置 * @return 连接池对象 */ - public PoolingHttpClientConnectionManager connectionManager(HttpConfigStorage configStorage){ - if (null != connectionManager){ + public PoolingHttpClientConnectionManager connectionManager(HttpConfigStorage configStorage) { + if (null != connectionManager) { return connectionManager; } - if (0 == configStorage.getMaxTotal() || 0 == configStorage.getDefaultMaxPerRoute()){ + if (0 == configStorage.getMaxTotal() || 0 == configStorage.getDefaultMaxPerRoute()) { return null; } if (LOG.isInfoEnabled()) { LOG.info(String.format("Initialize the PoolingHttpClientConnectionManager -- maxTotal:%s, defaultMaxPerRoute:%s", configStorage.getMaxTotal(), configStorage.getDefaultMaxPerRoute())); } - Registry socketFactoryRegistry = RegistryBuilder. create() + Registry socketFactoryRegistry = RegistryBuilder.create() .register("https", createSSL(configStorage)) .register("http", new PlainConnectionSocketFactory()) .build(); @@ -216,26 +229,25 @@ public class HttpRequestTemplate { if (null != configStorage && StringUtils.isNotBlank(configStorage.getHttpProxyHost())) { //http代理地址设置 - httpProxy = new HttpHost(configStorage.getHttpProxyHost(),configStorage.getHttpProxyPort());; + httpProxy = new HttpHost(configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort()); + ; } return this; } - - /** - * * post - * @param uri 请求地址 - * @param request 请求参数 + * + * @param uri 请求地址 + * @param request 请求参数 * @param responseType 为响应类(需要自己依据响应格式来确定) * @param uriVariables 地址通配符对应的值 - * @param 响应类型 + * @param 响应类型 * @return 类型对象 */ - public T postForObject(String uri, Object request, Class responseType, Object... uriVariables){ + public T postForObject(String uri, Object request, Class responseType, Object... uriVariables) { return doExecute(URI.create(UriVariables.getUri(uri, uriVariables)), request, responseType, MethodType.POST); } @@ -243,7 +255,7 @@ public class HttpRequestTemplate { return doExecute(URI.create(UriVariables.getUri(uri, uriVariables)), request, responseType, MethodType.POST); } - public T postForObject(URI uri, Object request, Class responseType){ + public T postForObject(URI uri, Object request, Class responseType) { return doExecute(uri, request, responseType, MethodType.POST); } @@ -255,14 +267,13 @@ public class HttpRequestTemplate { * @param responseType 响应类型 * @param uriVariables 用于匹配表达式 * @param 响应类型 - * * @return 类型对象 - *

+ * * * getForObject("http://egan.in/pay/{id}/f/{type}", String.class, "1", "APP") * */ - public T getForObject(String uri, Class responseType, Object... uriVariables){ + public T getForObject(String uri, Class responseType, Object... uriVariables) { return doExecute(URI.create(UriVariables.getUri(uri, uriVariables)), null, responseType, MethodType.GET); } @@ -277,101 +288,179 @@ public class HttpRequestTemplate { * @return 类型对象 * * Map<String, String> uriVariables = new HashMap<String, String>();
- * + * * uriVariables.put("id", "1");
- * + * * uriVariables.put("type", "APP");
- * + * * getForObject("http://egan.in/pay/{id}/f/{type}", String.class, uriVariables)
*
*/ - public T getForObject(String uri, Class responseType, Map uriVariables){ + public T getForObject(String uri, Class responseType, Map uriVariables) { return doExecute(URI.create(UriVariables.getUri(uri, uriVariables)), null, responseType, MethodType.GET); } /** * get 请求 - * @param uri 请求地址 - * @param header 请求头 + * + * @param uri 请求地址 + * @param header 请求头 * @param responseType 响应类型 * @param uriVariables 用于匹配表达式 - * @param 响应类型 - * @return 类型对象 + * @param 响应类型 + * @return 类型对象 * * - * getForObject("http://egan.in/pay/{id}/f/{type}", String.class, "1", "APP") + * getForObject("http://egan.in/pay/{id}/f/{type}", String.class, "1", "APP") * */ - public T getForObject(String uri, HttpHeader header, Class responseType, Object... uriVariables){ + public T getForObject(String uri, HttpHeader header, Class responseType, Object... uriVariables) { - return doExecute(URI.create(UriVariables.getUri(uri, uriVariables)), header, responseType, MethodType.GET); + return getForObjectEntity(uri, header, responseType, uriVariables).getBody(); } /** * get 请求 * * @param uri 请求地址 - * @param header 请求头 + * @param header 请求头 * @param responseType 响应类型 * @param uriVariables 用于匹配表达式 - * @param 响应类型 + * @param 响应类型 + * @return 类型对象 + * + * + * getForObject("http://egan.in/pay/{id}/f/{type}", String.class, "1", "APP") + * + */ + public ResponseEntity getForObjectEntity(String uri, HttpHeader header, Class responseType, Object... uriVariables) { + + return doExecuteEntity(URI.create(UriVariables.getUri(uri, uriVariables)), header, responseType, MethodType.GET); + } + + /** + * get 请求 + * + * @param uri 请求地址 + * @param header 请求头 + * @param responseType 响应类型 + * @param uriVariables 用于匹配表达式 + * @param 响应类型 * @return 类型对象 * * Map<String, String> uriVariables = new HashMap<String, String>();
- * + * * uriVariables.put("id", "1");
- * + * * uriVariables.put("type", "APP");
- * + * * getForObject("http://egan.in/pay/{id}/f/{type}", String.class, uriVariables)
*
*/ - public T getForObject(String uri, HttpHeader header, Class responseType, Map uriVariables){ - return doExecute(URI.create(UriVariables.getUri(uri, uriVariables)), header, responseType, MethodType.GET); + public T getForObject(String uri, HttpHeader header, Class responseType, Map uriVariables) { + return getForObjectEntity(uri, header, responseType, uriVariables).getBody(); + } + /** + * get 请求 + * + * @param uri 请求地址 + * @param header 请求头 + * @param responseType 响应类型 + * @param uriVariables 用于匹配表达式 + * @param 响应类型 + * @return 类型对象 + * + * Map<String, String> uriVariables = new HashMap<String, String>();
+ * + * uriVariables.put("id", "1");
+ * + * uriVariables.put("type", "APP");
+ * + * getForObject("http://egan.in/pay/{id}/f/{type}", String.class, uriVariables)
+ *
+ */ + public ResponseEntity getForObjectEntity(String uri, HttpHeader header, Class responseType, Map uriVariables) { + return doExecuteEntity(URI.create(UriVariables.getUri(uri, uriVariables)), header, responseType, MethodType.GET); } /** * http 请求执行 - * @param uri 地址 - * @param request 请求数据 + * + * @param uri 地址 + * @param request 请求数据 * @param responseType 响应类型 - * @param method 请求方法 - * @param 响应类型 + * @param method 请求方法 + * @param 响应类型 * @return 类型对象 */ - public T doExecute(URI uri, Object request, Class responseType, MethodType method){ + public T doExecute(URI uri, Object request, Class responseType, MethodType method) { + return doExecuteEntity(uri, request, responseType, method).getBody(); + + } + + /** + * http 请求执行 + * + * @param uri 地址 + * @param request 请求数据 + * @param responseType 响应类型 + * @param method 请求方法 + * @param 响应类型 + * @return 类型对象 + */ + public ResponseEntity doExecuteEntity(URI uri, Object request, Class responseType, MethodType method) { + if (LOG.isDebugEnabled()) { LOG.debug(String.format("uri:%s, httpMethod:%s ", uri, method.name())); } - ClientHttpRequest httpRequest = new ClientHttpRequest(uri ,method, request, null == configStorage ? null : configStorage.getCharset()); + ClientHttpRequest httpRequest = new ClientHttpRequest(uri, method, request, null == configStorage ? null : configStorage.getCharset()); //判断是否有代理设置 - if (null != httpProxy){ + if (null != httpProxy) { httpRequest.setProxy(httpProxy); } httpRequest.setResponseType(responseType); try (CloseableHttpResponse response = getHttpClient().execute(httpRequest)) { - return httpRequest.handleResponse(response); - }catch (IOException e){ + int statusCode = response.getStatusLine().getStatusCode(); + Header[] allHeaders = response.getAllHeaders(); + T body = httpRequest.handleResponse(response); + return new ResponseEntity<>(statusCode, allHeaders, body); + } + catch (IOException e) { throw new PayErrorException(new PayException("IOException", e.getLocalizedMessage())); - }finally { + } + finally { httpRequest.releaseConnection(); } - } /** * http 请求执行 - * @param uri 地址 - * @param request 请求数据 + * + * @param uri 地址 + * @param request 请求数据 * @param responseType 响应类型 - * @param method 请求方法 - * @param 响应类型 + * @param method 请求方法 + * @param 响应类型 * @return 类型对象 */ - public T doExecute(String uri, Object request, Class responseType, MethodType method){ + public T doExecute(String uri, Object request, Class responseType, MethodType method) { return doExecute(URI.create(uri), request, responseType, method); } + + /** + * http 请求执行 + * + * @param uri 地址 + * @param request 请求数据 + * @param responseType 响应类型 + * @param method 请求方法 + * @param 响应类型 + * @return 类型对象 + */ + public ResponseEntity doExecuteEntity(String uri, Object request, Class responseType, MethodType method) { + return doExecuteEntity(URI.create(uri), request, responseType, method); + } } diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpStringEntity.java b/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpStringEntity.java index 828c9be..53e5062 100644 --- a/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpStringEntity.java +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpStringEntity.java @@ -1,25 +1,30 @@ package com.egzosn.pay.common.http; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + import org.apache.http.Header; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicHeader; -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.nio.charset.UnsupportedCharsetException; -import java.util.*; - import static com.egzosn.pay.common.http.UriVariables.getMapToParameters; +import com.egzosn.pay.common.util.str.StringUtils; + /** * 请求实体,包含请求头,内容类型,编码类型等 * * @author egan - *

-*               email egzosn@gmail.com
-*               date 2017/12/20
-*           
+ *
+ *               email egzosn@gmail.com
+ *               date 2017/12/20
+ *           
*/ public class HttpStringEntity extends StringEntity { /** @@ -42,12 +47,13 @@ public class HttpStringEntity extends StringEntity { public void requestIsEmpty(Map request) { - if (null == request || request.isEmpty()){ + if (null == request || request.isEmpty()) { this.isEmpty = true; } } + public void requestIsEmpty(String request) { - if (null == request || request.isEmpty()){ + if (StringUtils.isEmpty(request)) { this.isEmpty = true; } @@ -59,7 +65,6 @@ public class HttpStringEntity extends StringEntity { * * @param request 请求体 * @param headers 请求头 - * * @throws UnsupportedEncodingException 不支持默认的HTTP字符集 */ public HttpStringEntity(Map request, Header... headers) throws UnsupportedEncodingException { @@ -73,7 +78,6 @@ public class HttpStringEntity extends StringEntity { * * @param request 请求体 * @param headers 请求头 - * * @throws UnsupportedEncodingException 不支持默认的HTTP字符集 */ public HttpStringEntity(Map request, Map headers) throws UnsupportedEncodingException { @@ -119,7 +123,6 @@ public class HttpStringEntity extends StringEntity { * 构造器 * * @param request 请求体 - * * @throws UnsupportedEncodingException 不支持默认的HTTP字符集 */ public HttpStringEntity(Map request) throws UnsupportedEncodingException { @@ -132,7 +135,6 @@ public class HttpStringEntity extends StringEntity { * * @param request 请求体 * @param contentType 内容类型 - * * @throws UnsupportedCharsetException 不支持默认的HTTP字符集 */ public HttpStringEntity(String request, ContentType contentType) throws UnsupportedCharsetException { @@ -145,7 +147,6 @@ public class HttpStringEntity extends StringEntity { * * @param request 请求体 * @param charset 字符类型 - * * @throws UnsupportedCharsetException 不支持默认的HTTP字符集 */ public HttpStringEntity(String request, String charset) throws UnsupportedCharsetException { @@ -169,7 +170,6 @@ public class HttpStringEntity extends StringEntity { * * @param request 请求体 * @param headers 请求头 - * * @throws UnsupportedEncodingException 不支持默认的HTTP字符集 */ public HttpStringEntity(String request, Header... headers) throws UnsupportedEncodingException { @@ -185,7 +185,6 @@ public class HttpStringEntity extends StringEntity { * * @param request 请求体 * @param headers 请求头 - * * @throws UnsupportedEncodingException 不支持默认的HTTP字符集 */ public HttpStringEntity(String request, Map headers) throws UnsupportedEncodingException { @@ -237,6 +236,7 @@ public class HttpStringEntity extends StringEntity { addHeader(new BasicHeader(entry.getKey(), entry.getValue())); } } + /** * 设置请求头 * diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/http/ResponseEntity.java b/pay-java-common/src/main/java/com/egzosn/pay/common/http/ResponseEntity.java new file mode 100644 index 0000000..995bc67 --- /dev/null +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/http/ResponseEntity.java @@ -0,0 +1,33 @@ +package com.egzosn.pay.common.http; + +import org.apache.http.Header; + +/** + * 响应实体 + * @author Egan + * email egzosn@gmail.com + * date 2021/8/1 + */ +public class ResponseEntity { + private final int statusCode; + private final Header[] headers; + private final T body; + + public ResponseEntity(int statusCode, Header[] headers, T body) { + this.statusCode = statusCode; + this.headers = headers; + this.body = body; + } + + public int getStatusCode() { + return statusCode; + } + + public Header[] getHeaders() { + return headers; + } + + public T getBody() { + return body; + } +} diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/http/UriVariables.java b/pay-java-common/src/main/java/com/egzosn/pay/common/http/UriVariables.java index 8f59338..cff3608 100644 --- a/pay-java-common/src/main/java/com/egzosn/pay/common/http/UriVariables.java +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/http/UriVariables.java @@ -1,6 +1,8 @@ package com.egzosn.pay.common.http; import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URLEncoder; import java.util.List; import java.util.Map; @@ -11,6 +13,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.fastjson.JSONObject; import com.egzosn.pay.common.bean.result.PayException; import com.egzosn.pay.common.exception.PayErrorException; +import com.egzosn.pay.common.util.str.StringUtils; /** * URL表达式处理器 @@ -23,6 +26,7 @@ import com.egzosn.pay.common.exception.PayErrorException; */ public final class UriVariables { private static final Logger LOG = LoggerFactory.getLogger(UriVariables.class); + public static final String QUESTION = "?"; private UriVariables() { } @@ -218,5 +222,28 @@ public final class UriVariables { return str; } + /** + * 去除域名的标准url + * + * @param url url + * @return 去除域名的标准url + */ + public static String getCanonicalUrl(String url) { + if (StringUtils.isEmpty(url)) { + return url; + } + try { + URI uri = new URI(url); + String path = uri.getPath(); + String encodedQuery = uri.getQuery(); + if (StringUtils.isNotEmpty(encodedQuery)) { + path += QUESTION.concat(encodedQuery); + } + return path; + } + catch (URISyntaxException e) { + throw new PayErrorException(new PayException("failure", "去除域名的标准url失败"), e); + } + } }