Spring Boot 2關於http介面呼叫1
阿新 • • 發佈:2018-12-17
使用HttpClient
HttpClient介面中常用方法
HttpResponse execute(HttpUriRequest request) throws IOException, ClientProtocolException; HttpResponse execute(HttpUriRequest request, HttpContext context) throws IOException, ClientProtocolException; HttpResponse execute(HttpHost target, HttpRequest request) throws IOException, ClientProtocolException; HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws IOException, ClientProtocolException; <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException; <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException; <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException; <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException;
HttpClient重要的實現類CloseableHttpClient
封裝HttpClient
public static <T> T doPostWithJson(String url, Object params, Class<T> t); public static <T> T doPostWithJson(String url, Object params, TypeReference<T> typeReference); public static <T> T doPostWithJson(String url, Object params, ParameterizedType parameterizedType); public static <T> T doPostWithJson(String url, Object params, Class rawType, Type ownerType, Type... argType); public static <T> T doGet(String url, Map params, Class<T> t); public static <T> T doGet(String url, Map params, TypeReference<T> typeReference); public static <T> T doGet(String url, Map params, ParameterizedType parameterizedType) ; public static <T> T doGet(String url, Map params, Class rawType, Type ownerType, Type... argType); // 這裡在JSON的反序列化採用了Jackson庫,下面是ObjectMapper幾個常用的反序列化方法 public <T> T readValue(String content, Class<T> valueType) throws IOException, JsonParseException, JsonMappingException; public <T> T readValue(String content, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException; public <T> T readValue(String content, JavaType valueType) throws IOException, JsonParseException, JsonMappingException; // 泛型型別的構造 // List<String>型別構造 ParameterizedType listType = ParameterizedTypeImpl.make(List.class, new Type[]{String.class}, ArrayList.class); // Map<String,Object>型別構造 ParameterizedType mapType = ParameterizedTypeImpl.make(Map.class, new Type[]{String.class, Object.class}, HashMap.class); // List<Map<String, Object>>型別構造 ParameterizedType listMapType = ParameterizedTypeImpl.make(List.class, new Type[]{mapType}, ArrayList.class); // TypeReference型別構造 TypeReference<List<Map<String, Object>>> typeReference = new TypeReference<List<Map<String, Object>>>() { @Override public Type getType() { return listMapType; } };
進一步封裝HttpClient
public static void invoke(HttpRequestBuilder builder); public static <T> T invoke(HttpRequestBuilder builder, Class<T> cls); public static <T> T invoke(HttpRequestBuilder builder, TypeReference<T> typeReference); public static <T> T invoke(HttpRequestBuilder builder, ParameterizedType parameterizedType); public static <T> T invoke(HttpRequestBuilder builder, Class rawType, Type ownerType, Type... argType);
HttpRequestBuilder類構造請求引數
package org.ghost.springboot2.demo.common.http;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.auth.Credentials;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicNameValuePair;
import org.ghost.springboot2.demo.util.ExceptionUtil;
import org.ghost.springboot2.demo.util.JacksonUtil;
import org.ghost.springboot2.demo.util.UriUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
public class HttpRequestBuilder {
private static final transient Logger logger = LoggerFactory.getLogger(HttpRequestBuilder.class);
private transient HttpRequestBase httpRequestBase;
private transient Credentials credentials;
public HttpRequestBase getHttpRequestBase() {
return httpRequestBase;
}
public HttpRequestBuilder() {
}
public HttpRequestBuilder(final HttpMethod method, final String url) {
this.build(method, url);
}
public HttpRequestBuilder build(final HttpMethod method, final String url) {
switch (method) {
case GET:
httpRequestBase = new HttpGet(url);
break;
case POST:
httpRequestBase = new HttpPost(url);
break;
case PUT:
httpRequestBase = new HttpPut(url);
break;
case DELETE:
httpRequestBase = new HttpDelete(url);
break;
case PATCH:
httpRequestBase = new HttpPatch(url);
break;
case OPTIONS:
httpRequestBase = new HttpOptions(url);
break;
case HEAD:
httpRequestBase = new HttpHead(url);
break;
case TRACE:
httpRequestBase = new HttpTrace(url);
break;
default:
ExceptionUtil.throwRuntimeException("HttpRequestBuilder.build", "方法未實現", logger);
break;
}
return this;
}
/**
* 新增請求頭
*
* @param name
* @param value
* @return
*/
public HttpRequestBuilder addHeader(String name, String value) {
if (StringUtils.isNotEmpty(name) && StringUtils.isNotBlank(value)) {
httpRequestBase.addHeader(name, value);
}
return this;
}
/**
* 新增請求頭
*
* @param headers
* @return
*/
public HttpRequestBuilder addHeaders(Map<String, String> headers) {
if (MapUtils.isNotEmpty(headers)) {
headers.forEach(
(key, value) -> {
if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) {
httpRequestBase.addHeader(key, value);
}
});
}
return this;
}
/**
* 拼接url引數
*
* @param name
* @param value
* @return
*/
public HttpRequestBuilder addUrlPara(String name, String value) {
if (StringUtils.isNotBlank(name)) {
if (httpRequestBase.getURI().toString().contains("?")) {
this.httpRequestBase.setURI(URI.create(httpRequestBase.getURI().toString() + "&" + name + "=" + value));
} else {
this.httpRequestBase.setURI(URI.create(httpRequestBase.getURI().toString() + "?" + name + "=" + value));
}
}
return this;
}
/**
* 拼接url引數
*
* @param param
* @return
*/
public HttpRequestBuilder addUrlPara(Object param) {
if (param != null) {
String value = UriUtil.urlParaEncode(param);
if (StringUtils.isNotBlank(value)) {
if (httpRequestBase.getURI().toString().contains("?")) {
this.httpRequestBase.setURI(URI.create(httpRequestBase.getURI().toString() + "&" + value));
} else {
this.httpRequestBase.setURI(URI.create(httpRequestBase.getURI().toString() + "?" + value));
}
}
}
return this;
}
/**
* 拼接url引數
*
* @param params
* @return
*/
public HttpRequestBuilder addUrlPara(Map<String, String> params) {
if (MapUtils.isNotEmpty(params)) {
StringBuilder builder = new StringBuilder();
params.forEach((key, value) -> {
if (StringUtils.isNotBlank(key)) {
try {
if (builder.length() > 0) {
builder.append("&");
}
builder.append(URLEncoder.encode(key, "UTF-8")).append("=").append(URLEncoder.encode(value, "UTF-8"));
} catch (UnsupportedEncodingException e) {
logger.error("*****HttpRequestBuilder.addUrlPara:{}", e);
}
}
});
if (builder.length() > 0) {
if (httpRequestBase.getURI().toString().contains("?")) {
this.httpRequestBase.setURI(URI.create(httpRequestBase.getURI().toString() + "&" + builder.toString()));
} else {
this.httpRequestBase.setURI(URI.create(httpRequestBase.getURI().toString() + "?" + builder.toString()));
}
}
}
return this;
}
/**
* Form表單鍵值對引數
*
* @param params
* @return
* @throws UnsupportedEncodingException
*/
public HttpRequestBuilder addFormPara(Map<String, String> params) throws UnsupportedEncodingException {
if (this.httpRequestBase instanceof HttpEntityEnclosingRequestBase && MapUtils.isNotEmpty(params)) {
List<NameValuePair> nameValuePairs = params.entrySet().stream()
.filter(it -> StringUtils.isNotBlank(it.getKey()))
.map(it -> new BasicNameValuePair(it.getKey(), it.getValue()))
.collect(Collectors.toList());
((HttpEntityEnclosingRequestBase) httpRequestBase).setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
}
return this;
}
/**
* Body存放json資料
*
* @param body
* @return
*/
public HttpRequestBuilder addBody(Object body) {
if (this.httpRequestBase instanceof HttpEntityEnclosingRequestBase) {
StringEntity stringEntity = new StringEntity(Objects.requireNonNull(JacksonUtil.nonNull().toJson(body)), Charset.forName("UTF-8"));
((HttpEntityEnclosingRequestBase) httpRequestBase).setEntity(stringEntity);
}
return this;
}
public Credentials getCredentials() {
return credentials;
}
public HttpRequestBuilder setCredentials(Credentials credentials) {
this.credentials = credentials;
return this;
}
}
單元測試
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class HttpClientHelperTest {
@Autowired
private TaskExecutorConfig taskExecutorConfig;
/**
* HttpClient
*/
@Test
public void test1() {
long begin = System.currentTimeMillis();
HttpRequestBuilder httpRequestBuilder = new HttpRequestBuilder()
.build(HttpMethod.GET, "http://localhost:9999/demo/hello")
.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
HttpRspDTO<String> rspDTO = HttpClientHelper.invoke(httpRequestBuilder, HttpRspDTO.class, null, String.class);
long end = System.currentTimeMillis();
System.out.println("*****消耗時間(秒):" + (end - begin) / 1000.0);
System.out.println(rspDTO);
}
/**
* 自定義執行緒池 + HttpClient
*/
@Test
public void test2() {
long begin = System.currentTimeMillis();
List<Future<HttpRspDTO<String>>> futureList = new ArrayList<Future<HttpRspDTO<String>>>();
for (int i = 0; i < 100; i++) {
HttpRequestBuilder httpRequestBuilder = new HttpRequestBuilder()
.build(HttpMethod.GET, "http://localhost:9999/demo/hello")
.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
Future<HttpRspDTO<String>> future = taskExecutorConfig.getAsyncTaskExecutor().submit(new Callable<HttpRspDTO<String>>() {
@Override
public HttpRspDTO<String> call() throws Exception {
return HttpClientHelper.invoke(httpRequestBuilder, HttpRspDTO.class, null, String.class);
}
});
futureList.add(future);
}
List<String> resultList = new ArrayList<String>();
for (Future<HttpRspDTO<String>> future : futureList) {
try {
HttpRspDTO<String> rspDTO = future.get();
if (rspDTO != null && Objects.equals(Boolean.TRUE, rspDTO.getSuccess())) {
resultList.add(rspDTO.getData());
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("*****消耗時間(秒):" + (end - begin) / 1000.0);
System.out.println(resultList.size());
}
/**
* ParallelStream + HttpClient
*/
@Test
public void test3() {
long begin = System.currentTimeMillis();
List<String> resultList = IntStream.range(0, 100)
.parallel()
.mapToObj(it -> {
HttpRequestBuilder httpRequestBuilder = new HttpRequestBuilder()
.build(HttpMethod.GET, "http://localhost:9999/demo/hello")
.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
.addUrlPara("msg", String.valueOf(it));
HttpRspDTO<String> rspDTO = HttpClientHelper.invoke(httpRequestBuilder, HttpRspDTO.class, null, String.class);
if (rspDTO != null && Objects.equals(Boolean.TRUE, rspDTO.getSuccess())) {
return rspDTO.getData();
} else {
return null;
}
}).filter(Objects::nonNull).collect(Collectors.toList());
long end = System.currentTimeMillis();
System.out.println("*****消耗時間(秒):" + (end - begin) / 1000.0);
System.out.println(resultList.size());
}
}