提交 410c6a6c authored 作者: 黄夏豪's avatar 黄夏豪

fix(base):添加了动作和动态变量的HTTP实现

上级 f545760e
......@@ -17,6 +17,80 @@
<artifactId>kt-kit</artifactId>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.39</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
<!-- httpClient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.10</version>
</dependency>
<!-- httpclient缓存-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient-cache</artifactId>
<version>4.5</version>
</dependency>
<!-- http的mime类型都在这里面-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.3.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.netty/netty-codec-http -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http</artifactId>
<version>4.1.69.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
......
package org.matrix.config;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.NoConnectionReuseStrategy;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;
public class HttpRequestConfig {
/**
* HttpClient的Cookie管理器,可在其他类中调用该Bean清空Cookie缓存。
* 主要针对某些网站Cookie多次使用会造成Cookie失效的问题
* @return
*/
public CookieStore cookieStore(){
CookieStore cookieStore = new BasicCookieStore();
return cookieStore;
}
/**
* HttpClient的配置,所返回的CloseableHttpClient可以用来发送网络请求。
* @return
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public CloseableHttpClient client() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
TrustStrategy acceptingTrustStrategy = (X509Certificate[] x509Certificates, String s) -> true;
SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
.loadTrustMaterial(null, acceptingTrustStrategy)
.build();
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext
,null, null, NoopHostnameVerifier.INSTANCE);
SocketConfig socketConfig = SocketConfig.custom()
.setSoKeepAlive(false)
.setSoLinger(1)
.setSoReuseAddress(true)
.setSoTimeout(5000)
.setTcpNoDelay(true).build();
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", csf)
.build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
//最大连接数3000
connectionManager.setMaxTotal(3000);
//路由链接数400
connectionManager.setDefaultMaxPerRoute(400);
RequestConfig requestConfig = RequestConfig.custom()
.setMaxRedirects(1)
.setRedirectsEnabled(true)
.build();
return HttpClients.custom().setDefaultRequestConfig(requestConfig)
.setConnectionManager(connectionManager)
.setDefaultSocketConfig(socketConfig)
.setConnectionReuseStrategy(new NoConnectionReuseStrategy())
.evictExpiredConnections()
.evictIdleConnections(30, TimeUnit.SECONDS)
.setRetryHandler(new DefaultHttpRequestRetryHandler())
.disableAutomaticRetries()
.disableRedirectHandling()
.setDefaultCookieStore(cookieStore())
.build();
}
}
package org.matrix.entity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.http.Header;
import org.apache.http.message.BasicHeader;
import org.springframework.http.HttpMethod;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Data
public class HttpRequestDetail {
@ApiModelProperty("请求头")
private List<RequestHeader> headers = new ArrayList<>();
@ApiModelProperty("URL")
private String url = new String();
// @ApiModelProperty("请求类型")
private HttpRequestType requestType = HttpRequestType.NONE;
@ApiModelProperty("请求方法")
private HttpMethod method;
@ApiModelProperty("字符串入参")
private String stringValue = new String();
@ApiModelProperty("键值对入参")
private List<RequestBody> requestBodies = new ArrayList<>();
/**
* 增加键值对入参
* @param requestBody
* @return
*/
private Boolean addRequestBody(RequestBody requestBody) {
return requestBodies.add(requestBody);
}
/**
* 增加请求头
* @param name
* @param value
* @return
*/
public Boolean addHeaders(String name, String value) {
return headers.add(new RequestHeader(name, value));
}
/**
* 以数组的形式获取请求头
* @return
*/
public Header[] getHeadersArray() {
List<BasicHeader> collect =
headers.stream().map(RequestHeader::getBasicHeader).collect(Collectors.toList());
return collect.toArray(new Header[collect.size()]);
}
}
package org.matrix.entity;
import org.springframework.lang.Nullable;
import java.util.HashMap;
import java.util.Map;
public enum HttpRequestType {
QUERY,
REST,
FORM_DATA,
X_WWW_FORM_URLENCODED,
TEXT,
JSON,
XML,
BINARY,
NONE;
private static final Map<String, HttpRequestType> mappings = new HashMap(16);
private HttpRequestType() {
}
@Nullable
public static HttpRequestType resolve(@Nullable String method) {
return method != null ? mappings.get(method) : null;
}
public boolean matches(String method) {
return this.name().equals(method);
}
static {
HttpRequestType[] var0 = values();
int var1 = var0.length;
for(int var2 = 0; var2 < var1; ++var2) {
HttpRequestType httpMethod = var0[var2];
mappings.put(httpMethod.name(), httpMethod);
}
}
}
package org.matrix.entity;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.http.client.methods.CloseableHttpResponse;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class HttpResponseDetail {
@ApiModelProperty("HttpClient响应体")
private CloseableHttpResponse response;
@ApiModelProperty("响应的内容,已转换为字符串")
private String responseBody = "error request";
@ApiModelProperty("响应状态,例如:200、401、500")
private Integer statusCode = 500;
@ApiModelProperty("响应时间,单位为 ms ")
private Long responseTime = 0l;
}
package org.matrix.entity;
import org.springframework.lang.Nullable;
import java.util.HashMap;
import java.util.Map;
public enum MultiPartRequestBodyType {
TEXT,
FILE;
private static final Map<String, MultiPartRequestBodyType> mappings = new HashMap(16);
private MultiPartRequestBodyType() {
}
public static MultiPartRequestBodyType resolve( String method) {
return method != null ? mappings.get(method) : null;
}
public boolean matches(String method) {
return this.name().equals(method);
}
static {
MultiPartRequestBodyType[] var0 = values();
int var1 = var0.length;
for(int var2 = 0; var2 < var1; ++var2) {
MultiPartRequestBodyType httpMethod = var0[var2];
mappings.put(httpMethod.name(), httpMethod);
}
}
}
package org.matrix.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RequestBody {
// @ApiModelProperty("键")
private String name;
// @ApiModelProperty("参数类型,文件或者文本")
private MultiPartRequestBodyType type;
// @ApiModelProperty("值")
private String value;
}
package org.matrix.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.http.message.BasicHeader;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RequestHeader {
private String name;
private String value;
public BasicHeader getBasicHeader(){
return new BasicHeader(name,value);
}
}
package org.matrix.util;
import io.netty.handler.codec.http.HttpHeaderValues;
import org.apache.commons.lang3.StringUtils;
import org.matrix.config.HttpRequestConfig;
import org.matrix.entity.*;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.http.HttpMethod;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* HttpClient调用封装
*
* @author HuangXiahao
* @version V1.0
* @class AuthenticationUtils
* @packageName com.example.personnelmanager.common.utils
**/
public class HttpClientUtil {
HttpRequestConfig config;
CookieStore cookieStore;
CloseableHttpClient client;
public HttpClientUtil(HttpRequestConfig config) throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
this.config = config;
this.cookieStore = config.cookieStore();
this.client = config.client();
}
public CloseableHttpClient getClient() {
return client;
}
/**
* 初始化请求内数据并补全动态变量
* @param httpRequestDetail
*/
public void execute(HttpRequestDetail httpRequestDetail){
for (RequestHeader header : httpRequestDetail.getHeaders()) {
//获取动态变量,并将动态变量替换进去
//todo
// header.setValue();
}
for (RequestBody requestBody : httpRequestDetail.getRequestBodies()) {
//todo
}
if (StringUtils.isEmpty(httpRequestDetail.getStringValue())){
//todo
}
//todo
// httpRequestDetail.setUrl();
}
/**
* 发起Http请求
*
* @param httpRequestDetail
* @return
*/
private HttpResponseDetail sendHttpRequest(HttpRequestDetail httpRequestDetail) {
CloseableHttpResponse response = null;
Date startTime = new Date();
String url = initUrlString(httpRequestDetail);
HttpRequestBase requestBase = initHttpRequestBase(url, httpRequestDetail.getMethod());
if (requestBase instanceof HttpEntityEnclosingRequestBase) {
HttpEntity httpRequestBase = initHttpEntity(httpRequestDetail);
((HttpEntityEnclosingRequestBase) requestBase).setEntity(httpRequestBase);
}
requestBase.setHeaders(httpRequestDetail.getHeadersArray());
try {
response = getClient().execute(requestBase);
Date endTime = new Date();
return new HttpResponseDetail(
response,
EntityUtils.toString(response.getEntity(), "UTF-8"),
response.getStatusLine().getStatusCode(),
endTime.getTime() - startTime.getTime()
);
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
//关闭请求request
closeRequest(requestBase);
//关闭response
closeResponse(response);
}
}
/**
* 初始化请求HttpEntity
*
* @param httpRequestDetail
* @return
*/
public HttpEntity initHttpEntity(HttpRequestDetail httpRequestDetail) {
HttpEntity httpEntity = null;
switch (httpRequestDetail.getRequestType()) {
case FORM_DATA:
httpEntity = getMultipartEntity(httpRequestDetail.getRequestBodies());
break;
case X_WWW_FORM_URLENCODED:
httpEntity = getUrlEncodeFormEntity(httpRequestDetail.getRequestBodies());
break;
case JSON:
httpEntity = getStringEntity(httpRequestDetail.getStringValue());
httpRequestDetail.addHeaders(HttpHeaders.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON.toString());
break;
case XML:
httpEntity = getStringEntity(httpRequestDetail.getStringValue());
httpRequestDetail.addHeaders(HttpHeaders.CONTENT_TYPE, HttpHeaderValues.APPLICATION_XML.toString());
break;
case TEXT:
httpEntity = getStringEntity(httpRequestDetail.getStringValue());
break;
case BINARY:
httpEntity = getByteArrayRequestEntity(httpRequestDetail.getStringValue());
break;
default:
httpEntity = getEmptyStringEntity();
}
return httpEntity;
}
public HttpEntity getMultipartEntity(List<RequestBody> requestBodies) {
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
for (RequestBody requestBody : requestBodies) {
switch (requestBody.getType()) {
case TEXT:
multipartEntityBuilder.addTextBody(requestBody.getName(), requestBody.getValue(), ContentType.create("text/plain", Consts.UTF_8));
break;
case FILE:
multipartEntityBuilder.addBinaryBody(requestBody.getName(), getFileByPath(requestBody.getValue()));
break;
}
}
return multipartEntityBuilder.build();
}
public HttpEntity getUrlEncodeFormEntity(List<RequestBody> requestBodies) {
List<NameValuePair> param = new ArrayList<>();
for (RequestBody requestBody : requestBodies) {
param.add(new BasicNameValuePair(requestBody.getName(), requestBody.getValue()));
}
return new UrlEncodedFormEntity(param, StandardCharsets.UTF_8);
}
public StringEntity getEmptyStringEntity() {
return new StringEntity(new String(), StandardCharsets.UTF_8);
}
public StringEntity getStringEntity(String value) {
return new StringEntity(value, StandardCharsets.UTF_8);
}
public File getFileByPath(String path) {
return new File(path);
}
public HttpEntity getByteArrayRequestEntity(String path) {
try {
File file = getFileByPath(path);
byte[] bytesArray = new byte[(int) file.length()];
FileInputStream fis = new FileInputStream(file);
fis.read(bytesArray); // read file into bytes[]
fis.close();
return new ByteArrayEntity(bytesArray);
} catch (IOException ioException) {
ioException.printStackTrace();
return getEmptyStringEntity();
}
}
public String initUrlString(HttpRequestDetail httpRequestDetail) {
String url = httpRequestDetail.getUrl();
try {
switch (httpRequestDetail.getRequestType()) {
case REST:
String regex = "(?<=\\{)(.*?)(?=\\})";
Pattern pattern = Pattern.compile(regex);
Matcher mat = pattern.matcher(url);
while (mat.find()) {
url = url.replaceAll("\\{" + mat.group() + "\\}", "1");
}
break;
case QUERY:
if (httpRequestDetail.getMethod().equals(HttpMethod.GET)) {
URIBuilder uriBuilder = null;
uriBuilder = new URIBuilder(url);
for (RequestBody requestBody : httpRequestDetail.getRequestBodies()) {
switch (requestBody.getType()) {
case TEXT:
uriBuilder.setParameter(requestBody.getName(), requestBody.getValue());
break;
case FILE:
throw new NullPointerException("QUERY请求不能传入文件流");
}
}
url = uriBuilder.build().toString();
}
break;
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
return url;
}
/**
* 初始化HttpRequestBase
*
* @param url
* @param httpMethod
* @return
*/
public HttpRequestBase initHttpRequestBase(String url, HttpMethod httpMethod) {
HttpRequestBase requestBase;
switch (httpMethod) {
case GET:
requestBase = new HttpGet(url);
break;
case POST:
requestBase = new HttpPost(url);
break;
case PUT:
requestBase = new HttpPut(url);
break;
case DELETE:
requestBase = new HttpDelete(url);
break;
case PATCH:
requestBase = new HttpPatch(url);
break;
default:
throw new IllegalStateException("不支持该类型的HTTP请求: " + httpMethod);
}
return requestBase;
}
public static void main(String[] args) throws MalformedURLException, URISyntaxException {
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("method","POST");
// Vo vo = JSON.parseObject(jsonObject.toJSONString(), Vo.class);
// System.out.println("1");
// String regex = "\\{([^\\}]+)\\}";
HttpRequestDetail httpRequestDetail = new HttpRequestDetail();
httpRequestDetail.getRequestBodies().add(new RequestBody("name", MultiPartRequestBodyType.TEXT, "张三"));
httpRequestDetail.getRequestBodies().add(new RequestBody("text", MultiPartRequestBodyType.TEXT, "a1"));
httpRequestDetail.setMethod(HttpMethod.GET);
httpRequestDetail.setUrl("www.baidu.com");
httpRequestDetail.setRequestType(HttpRequestType.QUERY);
}
/**
* 关闭response(注意:用完记得关,不然会一直占用系统资源)
*
* @param response
*/
public void closeResponse(CloseableHttpResponse response) {
if (response != null) {
if (response.getEntity() != null) {
EntityUtils.consumeQuietly(response.getEntity());
}
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 关闭requestBase(注意:用完记得关,不然会一直占用系统资源)
*
* @param requestBase
*/
public void closeRequest(HttpRequestBase requestBase) {
requestBase.abort();
requestBase.releaseConnection();
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论