一、HttpClient之用CloseableHttpClient发送Post请求
1、使用HttpClient发送请求的一般步骤
- 创建HttpClient对象。
- 创建请求方法实例,并指定请求的URL,如果需要发送GET请求,需要创建HttpGet对象;如果是POST,创建HttpPost对象。
- 如果需要发送请求参数,可调用HttpGet中的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,可调用setEntity(HttpEntity entity)方法来设置请求参数。
- 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。
- 调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
- 释放连接。无论执行方法是否成功,都必须释放连接。
二、代码实现
1、导入依赖
<!--导入json-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.49</version>
</dependency>
<!--导入httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
2、yml配置文件
# 远程路径
busData:
platformUrl: http://localhost:9092
3、HttpClientUtils类
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Map;
/**
* @Author: yeyanbin
* @Date: 2020/12/28
* HTTP请求工具类
*/
@Slf4j
public class HttpClientUtils {
/**
* 发送Json格式的POST请求
* @param url
* @param jsonParam
* @return
*/
public static String sendJsonPost(String url, String jsonParam) {
log.info("请求url:" + url + "请求参数:" + jsonParam);
//创建CloseableHttpResponse
CloseableHttpResponse response = null;
//创建CloseableHttpClient
CloseableHttpClient httpClient = null;
//建立httpPost的对象,一般用目标url来构造,httpPost一般配置addHeader、setEntity、setConfig
HttpPost httpPost = null;
try {
httpClient = HttpClients.custom().disableAutomaticRetries().build();
httpPost = new HttpPost(url);
//设置默认超时时间和链接超时时间
httpPost.setConfig(requestConfig());
StringEntity entity = new StringEntity(jsonParam, "utf-8");
//设置字符编码
entity.setContentEncoding("UTF-8");
//设置数据类型
entity.setContentType("application/json");
//设置请求实体
httpPost.setEntity(entity);
//执行Request请求,CloseableHttpClient的execute方法返回的response都是CloseableHttpResponse类型
response = httpClient.execute(httpPost);
//获取状态码
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK){
//终止请求
httpPost.abort();
log.info("HttpClient错误状态代码" + statusCode);
return null;
}
//获取返回实体
HttpEntity resultEntity = response.getEntity();
String result = null;
if (resultEntity != null){
result = EntityUtils.toString(resultEntity,"utf-8");
}
//关闭HttpEntity流
EntityUtils.consume(resultEntity);
//返回结果
return result;
} catch (Exception e) {
log.info("HttpClient远程调用失败" + e.getMessage());
} finally {
//释放底层HTTP连接以允许它被重用
if (httpPost != null) {
httpPost.releaseConnection();
}
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
/**
* 发送GET请求
* @param url
* @param params
* @return
*/
public static String sendGet(String url, Map<String,Object> params) {
CloseableHttpClient httpClient = null;
try {
StringBuilder sb = new StringBuilder();
if(params != null && params.size() > 0) {
for(String key : params.keySet()) {
sb.append(key + "=" + params.get(key) + "&");
}
}
if(!url.endsWith("?")) {
url += "?";
}
url+=sb.toString();
httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = httpClient.execute(httpGet);
return EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
} catch (Exception e) {
log.info("HttpClient远程调用失败" + e.getMessage());
throw new RuntimeException(e);
}
finally {
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
log.error(e.getLocalizedMessage());
}
}
}
}
/**
* 发送utf8格式数据的GET请求
* @param url
* @param params
* @return
*/
public static String sendGetUtf8(String url, Map<String,String> params) {
CloseableHttpClient httpClient = null;
//若url不是以?结尾,则拼接
if(!url.endsWith("?")) {
url += "?";
}
try {
StringBuilder sb = new StringBuilder();
if(params != null && params.size() > 0) {
for(Map.Entry<String, String> entry : params.entrySet()) {
if (entry.getValue() == null || entry.getValue().length() == 0) {
sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
} else {
//参数内容使用utf-8编码
sb.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "utf-8")).append("&");
}
}
}
//拼接url
url += sb.toString();
log.info("url:{}",url);
httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = httpClient.execute(httpGet);
return EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
} catch (Exception e) {
log.info("HttpClient远程调用失败" + e.getMessage());
throw new RuntimeException(e);
}
finally {
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
log.error(e.getLocalizedMessage());
}
}
}
}
/**
* 发送form-data格式POST请求
* @param urlStr
* @param textMap
* @return
*/
public static String sendFromDataPost(String urlStr, Map<String, String> textMap) {
String result = "";
HttpURLConnection conn = null;
// boundary就是request头和上传文件内容的分隔符
String BOUNDARY = "-";
try {
URL url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setReadTimeout(30000);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type","multipart/form-data; boundary=" + BOUNDARY);
OutputStream out = new DataOutputStream(conn.getOutputStream());
StringBuffer sb = new StringBuffer();
Iterator iter = textMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
String keyName = (String) entry.getKey();
String keyValue = (String) entry.getValue();
if (keyValue == null) {
continue;
}
sb.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
sb.append("Content-Disposition: form-data; name=\"" + keyName + "\"\r\n\r\n");
sb.append(keyValue);
}
out.write(sb.toString().getBytes());
byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
out.write(endData);
out.flush();
out.close();
// 读取返回数据
StringBuffer strBuf = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
strBuf.append(line);
}
result = strBuf.toString();
reader.close();
} catch (Exception e) {
log.info("HttpClient远程调用失败:{}",e.getMessage());
} finally {
if (conn != null) {
conn.disconnect();
}
}
return result;
}
/**
* 设置默认的超时时间和链接超时间(这里的时间设置为10秒)
* @return
*/
private static RequestConfig requestConfig(){
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(10000)
.setSocketTimeout(10000)
.build();
return config;
}
}
4、JsonDataDtoFacade接口
public interface JsonDataDtoFacade {
/**
* 测试httpclient
*/
public String postJson();
}
5、Impl类
@Service
public class JsonDataDtoFacadeImpl implements JsonDataDtoFacade {
@Autowired
private JsonDataDtoServiceImpl jsonDataDtoService;
/**
* 读取配置中的url
*/
@Value("${busData.platformUrl}")
private String busDataUrl;
@Override
public String postJson() {
Map<String,Object> map = new HashMap<>();
map.put("cityCode","432000");
map.put("lineId","432000-A3HX-1");
String url = busDataUrl + "/bus/detailData";
String jsonStr = JSON.toJSONString(map);
String resultStr = HttpClientUtils.postJsonStr(url, jsonStr);
return resultStr;
}
}
6、Controller类
@RestController
@RequestMapping("h5")
public class JsonDataDtoController {
@Autowired
private JsonDataDtoFacade jsonDataDtoFacade;
@PostMapping("line1")
public Object postJson(){
return jsonDataDtoFacade.postJson();
}
}
7、启动测试
http://localhost:8080/h5/line1