一、概述
- HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包。
- HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。
二、使用示例
2.1 数据提供方
2.1.1 Entity
public class User {
private int age;
private String name;
public User() {
}
public User(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2.1.2 Controller
@RestController
@RequestMapping("/user")
public class UserController {
@RequestMapping
public Object getAll(int age) {
return Arrays.asList(new User(age, "张三"), new User(age, "李四"));
}
}
2.2 数据调用方
2.2.1 导包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.12</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.0.M1</version>
</dependency>
2.2.2 Entity
public class User {
private int age;
private String name;
public User() {}
public User(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2.2.3 HttpClientUtil
public class HttpClientUtil {
protected final static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
private static PoolingHttpClientConnectionManager cm;
private static String EMPTY_STR = "";
private static String UTF_8 = "UTF-8";
private static void init() {
if (cm == null) {
//采用绕过验证的方式处理https请求
SSLContext sslcontext = null;
try {
sslcontext = createIgnoreVerifySSL();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
// 设置协议http和https对应的处理socket链接工厂的对象
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", new SSLConnectionSocketFactory(sslcontext))
.build();
cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
// 整个连接池最大连接数
cm.setMaxTotal(50);
// 每路由最大连接数,默认值是2
cm.setDefaultMaxPerRoute(5);
}
}
/**
* 通过连接池获取HttpClient
*
* @return
*/
private static CloseableHttpClient getHttpClient() {
init();
return HttpClients.custom().setConnectionManager(cm).build();
}
/**
* get请求-不带参数
* @param url
* @return
*/
public static String httpGetRequest(String url) {
HttpGet httpGet = new HttpGet(url);
return getResult(httpGet);
}
/**
* get请求-带参数
* @param url
* @param params
* @return
* @throws URISyntaxException
*/
public static String httpGetRequest(String url, Map<String, Object> params) throws URISyntaxException {
URIBuilder ub = new URIBuilder();
ub.setPath(url);
ArrayList<NameValuePair> pairs = covertParams2NVPS(params);
ub.setParameters(pairs);
HttpGet httpGet = new HttpGet(ub.build());
return getResult(httpGet);
}
/**
* get请求-带参数-带请求头信息
* @param url
* @param headers
* @param params
* @return
* @throws URISyntaxException
*/
public static String httpGetRequest(String url, Map<String, Object> headers, Map<String, Object> params)
throws URISyntaxException {
URIBuilder ub = new URIBuilder();
ub.setPath(url);
ArrayList<NameValuePair> pairs = covertParams2NVPS(params);
ub.setParameters(pairs);
HttpGet httpGet = new HttpGet(ub.build());
for (Map.Entry<String, Object> param : headers.entrySet()) {
httpGet.addHeader(param.getKey(), String.valueOf(param.getValue()));
}
return getResult(httpGet);
}
/**
* post请求-不带参数
* @param url
* @return
*/
public static String httpPostRequest(String url) {
HttpPost httpPost = new HttpPost(url);
return getResult(httpPost);
}
/**
* post请求,参数为json字符串
* @param url
* @param json
* @return
*/
public static String httpPostRequest(String url, String json) {
HttpPost httpPost = new HttpPost(url);
// 解决中文乱码问题
StringEntity entity = new StringEntity(json, "UTF-8");
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
return getResult(httpPost);
}
/**
* post请求-参数为json字符串-带请求头信息
* @param url
* @param json
* @param headers
* @return
*/
public static String httpPostRequest(String url, String json, Map<String, Object> headers) {
HttpPost httpPost = new HttpPost(url);
StringEntity entity = new StringEntity(json, "utf-8");//解决中文乱码问题
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
for (Map.Entry<String, Object> param : headers.entrySet()) {
httpPost.addHeader(param.getKey(), String.valueOf(param.getValue()));
}
return getResult(httpPost);
}
/**
* post请求-带参数
* @param url
* @param params
* @return
* @throws UnsupportedEncodingException
*/
public static String httpPostRequest(String url, Map<String, Object> params) throws UnsupportedEncodingException {
HttpPost httpPost = new HttpPost(url);
ArrayList<NameValuePair> pairs = covertParams2NVPS(params);
httpPost.setEntity(new UrlEncodedFormEntity(pairs, UTF_8));
return getResult(httpPost);
}
/**
* post请求-带参数-带请求头信息
* @param url
* @param headers
* @param params
* @return
* @throws UnsupportedEncodingException
*/
public static String httpPostRequest(String url, Map<String, Object> headers, Map<String, Object> params)
throws UnsupportedEncodingException {
HttpPost httpPost = new HttpPost(url);
for (Map.Entry<String, Object> param : headers.entrySet()) {
httpPost.addHeader(param.getKey(), String.valueOf(param.getValue()));
}
ArrayList<NameValuePair> pairs = covertParams2NVPS(params);
httpPost.setEntity(new UrlEncodedFormEntity(pairs, UTF_8));
return getResult(httpPost);
}
/**
* 参数转换
* @param params
* @return
*/
private static ArrayList<NameValuePair> covertParams2NVPS(Map<String, Object> params) {
ArrayList<NameValuePair> pairs = new ArrayList<NameValuePair>();
for (Map.Entry<String, Object> param : params.entrySet()) {
pairs.add(new BasicNameValuePair(param.getKey(), String.valueOf(param.getValue())));
}
return pairs;
}
/**
* 处理Http请求
*/
private static String getResult(HttpRequestBase request) {
CloseableHttpClient httpClient = getHttpClient();
try {
CloseableHttpResponse response = httpClient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null) {
// long len = entity.getContentLength();// -1 表示长度未知
String result = EntityUtils.toString(entity);
response.close();
return result;
}
} catch (IOException e) {
e.printStackTrace();
}
return EMPTY_STR;
}
/**
* 绕过验证
*
* @return
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sc = SSLContext.getInstance("SSLv3");
// 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sc.init(null, new TrustManager[]{trustManager}, null);
return sc;
}
}
2.2.4 Controller
@RestController
@RequestMapping("/remote")
public class RemoteController {
@RequestMapping
public Object getUser() {
Map<String, String> map = new HashMap<>();
map.put("age","18");
String remoteUrl = "http://localhost:8080/user";
String result = HttpClientUtil.httpGetRequest(remoteUrl, map);
List<User> users = JSON.parseArray(result, User.class);
return users;
}
}
2.2.5 YML
server:
port: 8082
三. 后端上传文件
@Slf4j
public class UpLoadFileUtil {
/**
* 通过httpClient上传文件
* @param fileName 文件名
* @param inputStream 输入流
* @return 文件上传url
*/
public static String UploadFileByHttpClient(String fileName,InputStream inputStream, String url) {
String result = "";
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
try {
HttpPost httpPost = new HttpPost(url);
// RFC6532: 解决中文乱码
MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
// form-data 参数,可填多个
builder.addBinaryBody("file", inputStream, ContentType.MULTIPART_FORM_DATA, fileName);
builder.addTextBody("param1", "1");
builder.addTextBody("param2", "2");
HttpEntity entity = builder.build();
httpPost.setEntity(entity);
response = httpClient.execute(httpPost);
HttpEntity responseEntity = response.getEntity();
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
result = EntityUtils.toString(responseEntity);
log.info("文件上传成功,返回结果:{}",result);
}else {
throw new AKException("文件上传失败");
}
}catch(Exception e) {
log.error("上传文件失败:",e);
}finally {
// 关闭流
IoUtil.close(httpClient);
}
return result;
}
}