使用HttpClient发送请求、接收响应。
http协议可以说是现在Internet上面最重要,使用最多的协议之一了,越来越多的java应用需要使用http协议来访问网络资源,HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient,很多的java的爬虫也是通过HttpClient实现的,研究HttpClient对我们来说是非常重要的。
1. 创建HttpClient对象实例。
2. 创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
3. 如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;如果是HttpPost,需要NameValuePair对象来设置请求参数。
4. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。
5. 调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
6. 释放连接。最后必须释放连接
一 pom文件
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4</version>
</dependency>
二,创建HttpClientUtil工具类
package com.htf.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
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.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* * HttpClientUtil工具类
*/
public class HttpClientUtil {
private static final Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
/**
* @param : [url, json]
* @return : java.lang.String
* @date : 2018/11/9 22:31
* @exception:
* @Description: 传入的参数为json的字符串, 返回为字符串
*/
public static String sendPostWithJson(String url, String json) {
// 1.创建httpclient
CloseableHttpClient httpclient = HttpClients.createDefault();
// 2.创建HttpPost
HttpPost httpPost = new HttpPost(url);
// 3.设置请求头及参数
StringEntity entity = new StringEntity(json, "utf-8");// 解决中文乱码问题
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);// 设置参数
// 4.执行POST并返回结果
CloseableHttpResponse response = null;
String responseStr = null;
try {
response = httpclient.execute(httpPost);
responseStr = EntityUtils.toString(response.getEntity());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
response.close();
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return responseStr;
}
/**
* @param : [url, param]
* @return : java.lang.String
* @date : 2018/11/9 22:32
* @exception:
* @Description: 传入的参数为Map, 返回为字符串
*/
public static String sendPostRequest(String url, Map<String, String> param) {
// 1.创建httpclient
CloseableHttpClient httpclient = HttpClients.createDefault();
// 2.创建HttpPost
HttpPost httpPost = new HttpPost(url);
// 3.设置参数
List<NameValuePair> formparams = new ArrayList();
for (Map.Entry<String, String> entry : param.entrySet()) {
formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
UrlEncodedFormEntity entity = null;
String responseStr = null;
CloseableHttpResponse response = null;
try {
entity = new UrlEncodedFormEntity(formparams, "UTF-8");
httpPost.setEntity(entity);// 设置参数
// 4.执行POST并返回结果
response = httpclient.execute(httpPost);
responseStr = EntityUtils.toString(response.getEntity());
} catch (UnsupportedEncodingException e) {
logger.info(ExceptionUtils.getStackTrace(e));
e.printStackTrace();
} catch (ClientProtocolException e) {
logger.info(ExceptionUtils.getStackTrace(e));
e.printStackTrace();
} catch (IOException e) {
logger.info(ExceptionUtils.getStackTrace(e));
e.printStackTrace();
} finally {
try {
response.close();
httpclient.close();
} catch (IOException e) {
logger.info(ExceptionUtils.getStackTrace(e));
e.printStackTrace();
}
}
return responseStr;
}
/**
* @param : [url]
* @return : java.lang.String
* @date : 2018/11/9 22:32
* @exception:
* @Description: 通过GET方式发起http请求
*/
public static String requestByGetMethod(String url) {
// 1.创建httpclient
CloseableHttpClient httpclient = HttpClients.createDefault();
// 用get方法发送http请求
HttpGet get = new HttpGet(url);
CloseableHttpResponse httpResponse = null;
String responseStr = null;
try {
//发送get请求
httpResponse = httpclient.execute(get);
//response实体
HttpEntity entity = httpResponse.getEntity();
responseStr = EntityUtils.toString(entity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpResponse.close();
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return responseStr;
}
public static void main(String[] args) throws Exception {
String string = getBlackList();
System.out.println(string);
}
public static String getBlackList() {
String url = "https://test.liu.com.cn:664d/http.do";
// 定义JSON
JSONObject json = new JSONObject();
JSONObject header = new JSONObject();
JSONObject body = new JSONObject();
JSONObject tail = new JSONObject();
// 封装头部
header.put("orgCode", "20000000");
header.put("chnlId", "qhcs-dcs-sf");
header.put("transNo", "11");
header.put("transDate", "2015-12-31");
header.put("authCode", "QHCXWZXX");
header.put("authDate", "2016-1-4");
json.put("header", header);
// 封装业务数据
body.put("batchNo", "1");
JSONArray arr = new JSONArray();
JSONObject obj = new JSONObject();
obj.put("id", "158222222");
obj.put("idType", "0");
obj.put("name", "李四");
arr.add(obj);
body.put("recorde", arr);
json.put("busiData", body);
// 封装尾部
tail.put("signatureValue", "");
tail.put("userName", "V_PA025_QHCS_DCS");
tail.put("userPassword", "6TNVA35G");
json.put("securityInfo", tail);
String s = HttpClientUtil.sendPostWithJson("urf8", JSON.toJSONString(json));
return s;
}
}
有时候需要下载https数据,优化后
import net.sf.json.JSONObject;
import org.apache.commons.collections.MapUtils;
import org.apache.http.*;
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.config.ConnectionConfig;
import org.apache.http.config.MessageConstraints;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
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.util.EntityUtils;
import java.io.IOException;
import java.io.InputStream;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.charset.CodingErrorAction;
import java.util.Map;
import java.util.Set;
public class HttpClientPool {
private static final int FORWARD_FILE_STEP = 128 * 1024;
private ThreadLocal<byte[]> forwardArray = new ThreadLocal<>();
private CloseableHttpClient client = client();
public static HttpClientPool getInstance() {
return InstanceHolder.instance;
}
public String post(String url, String content) throws IOException {
HttpPost post = new HttpPost(url);
try {
post.setEntity(new StringEntity(content, ContentType.APPLICATION_JSON));
CloseableHttpResponse response = client.execute(post);
return readResponse(response);
} finally {
post.releaseConnection();
}
}
public String post(String url, String content, Map<String, String> headers) throws IOException {
HttpPost post = new HttpPost(url);
try {
if (MapUtils.isNotEmpty(headers)) {
Set<Map.Entry<String, String>> set = headers.entrySet();
for(Map.Entry<String, String> entry : set) {
post.addHeader(entry.getKey(), entry.getValue());
}
}
post.setEntity(new StringEntity(content, ContentType.APPLICATION_JSON));
CloseableHttpResponse response = client.execute(post);
return readResponse(response);
} finally {
post.releaseConnection();
}
}
public String get(String url, Map<String, String> headers) throws IOException {
HttpGet get = new HttpGet(url);
try {
if (MapUtils.isNotEmpty(headers)) {
Set<Map.Entry<String, String>> set = headers.entrySet();
for(Map.Entry<String, String> entry : set) {
get.addHeader(entry.getKey(), entry.getValue());
}
}
CloseableHttpResponse response = client.execute(get);
return readResponse(response);
} finally {
get.releaseConnection();
}
}
public JSONObject postJson(String url, String content) throws IOException {
return JSONObject.fromObject(post(url, content));
}
public String get(String url) throws IOException {
HttpGet get = new HttpGet(url);
try {
HttpResponse response = client.execute(get);
return readResponse(response);
} finally {
get.releaseConnection();
}
}
public int getStatus(String url) throws IOException {
HttpGet get = new HttpGet(url);
try {
HttpResponse response = client.execute(get);
return response.getStatusLine().getStatusCode();
} finally {
get.releaseConnection();
}
}
public byte[] downloadFile(String url, int timeout) throws IOException {
HttpGet get = new HttpGet(url);
try {
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout).build();
get.setConfig(requestConfig);
HttpResponse response = client.execute(get);
StatusLine sl = response.getStatusLine();
if (sl.getStatusCode() == HttpStatus.SC_OK) {
return readResponseContent(response);
} else {
EntityUtils.consume(response.getEntity());
return null;
}
} finally {
get.releaseConnection();
}
}
private String readResponse(HttpResponse response) throws IOException {
InputStream is = null;
try {
is = response.getEntity().getContent();
return StringUtil.isToString(is);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private byte[] readResponseContent(HttpResponse response) throws IOException {
int length = FORWARD_FILE_STEP;
Header lenHeader = response.getFirstHeader("Content-Length");
if (lenHeader != null) {
length = Integer.parseInt(lenHeader.getValue());
}
InputStream input = response.getEntity().getContent();
try {
ByteBuffer buffer = ByteBuffer.allocate(length);
int offset = 0, step = 0;
// 先直接读一遍
while (offset < length && (step = input.read(buffer.array(), offset, length - offset)) >= 0) {
offset += step;
}
buffer.position(offset);
if (buffer.remaining() == 0) {
// 再看还有没有
byte[] tmp = forwardArray.get();
if (tmp == null) {
tmp = new byte[FORWARD_FILE_STEP];
forwardArray.set(tmp);
}
int len = 0;
while ((len = input.read(tmp, 0, FORWARD_FILE_STEP)) > 0) {
int increment = (len == FORWARD_FILE_STEP ? FORWARD_FILE_STEP * 4 : len);
ensureCapacity(buffer, len, increment);
buffer.put(tmp, 0, len);
}
}
if (buffer.remaining() == 0) {
return buffer.array();
} else {
byte[] tmp = new byte[buffer.position()];
System.arraycopy(buffer.array(), 0, tmp, 0, buffer.position());
return tmp;
}
} finally {
try {
input.close();
} catch (Exception ignored) {
}
}
}
private static ByteBuffer ensureCapacity(ByteBuffer buffer, int requirement, int increment) throws BufferOverflowException {
if (buffer.remaining() >= requirement) {
return buffer;
}
int newCapacity = buffer.capacity() + increment;
ByteBuffer newBuffer = ByteBuffer.allocate(newCapacity);
newBuffer.put(buffer);
return newBuffer;
}
private static CloseableHttpClient client() {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setDefaultMaxPerRoute(100);
cm.setMaxTotal(400);
MessageConstraints messageConstraints = MessageConstraints.custom()
.setMaxHeaderCount(200)
.setMaxLineLength(2000)
.build();
ConnectionConfig connectionConfig = ConnectionConfig.custom()
.setMalformedInputAction(CodingErrorAction.IGNORE)
.setUnmappableInputAction(CodingErrorAction.IGNORE)
.setCharset(Consts.UTF_8)
.setMessageConstraints(messageConstraints)
.build();
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setSocketTimeout(50000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.build();
cm.setDefaultConnectionConfig(connectionConfig);
return HttpClients.custom()
.setConnectionManager(cm)
.setDefaultRequestConfig(defaultRequestConfig)
.build();
}
private static class InstanceHolder {
private static HttpClientPool instance = new HttpClientPool();
}
}
下载
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletResponse;
public class HTTPUtil {
public static HttpServletResponse getHTTPServletResonse() {
ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletResponse httpResponse = attrs.getResponse();
return httpResponse;
}
}
下载测试
@ApiOperation(value = "接入列表搜索下载", produces = MediaType.APPLICATION_JSON_VALUE)
@RequestMapping(value = "/list/export/{accessType}", method = RequestMethod.POST)
@RequireLogin(UserType.BSADMIN)
public BaseResponse exportAccessList(@PathVariable Integer accessType,
@RequestBody AccessSearchRequest accessSearchRequest) {
HSSFWorkbook workbook = null;
ServletOutputStream outputStream = null;
try {
HttpServletResponse httpServletResponse = HTTPUtil.getHTTPServletResonse();
httpServletResponse.setContentType("application/vnd.ms-excel;charset=utf-8");
httpServletResponse.setHeader("Content-disposition", "attachment;filename=accessList.xls");
workbook = new HSSFWorkbook();
List<AccessSummaryVO> accessSummaryVOList = accessService.findAccessListBySearch(accessType, accessSearchRequest);
exportProcessor.export(accessSummaryVOList, workbook, AccessSummaryVO.class);
outputStream = httpServletResponse.getOutputStream();
workbook.write(outputStream);
outputStream.flush();
outputStream.close();
return ResponseUtils.newSuccessResponse();
} catch (Exception e) {
log.error("接入列表数据下载异常", e);
return ResponseUtils.newErrorResponse(ErrorCode.SYSTEM_ERROR);
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
log.error("接入列表数据下载异常", e);
}
}
if (workbook != null) {
try {
workbook.close();
} catch (IOException e) {
log.error("接入列表数据下载异常", e);
}
}
}
}
@RequestMapping(value = "/tenant/audit/result/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public BaseResponse auditTenant(@PathVariable Long id) {
if (id == null) {
return ResponseUtils.newErrorResponse(ErrorCode.INPUT_PARAM_ERROR);
}
TenantApply existTenant = tenantApplyService.findOne(id);
if (existTenant != null) {
Business business = businessService.findOne(existTenant.getBusinessLineId());
if (business != null && StringUtils.isNotBlank(business.getReviewCallbackApi())) {
ThirdTenantAuditResult result = new ThirdTenantAuditResult();
result.setTenantId(existTenant.getThirdTenantId());
if (existTenant.getReviewStatus() != null
&& (existTenant.getReviewStatus() == 2 || existTenant.getReviewStatus() == 3)) {
if (existTenant.getReviewStatus() == 3) {
result.setAuditSuccess(false);
result.setRemark(existTenant.getRemark());
} else {
result.setAuditSuccess(true);
}
//调用api,传输审核结果
HttpClientPool httpClient = HttpClientPool.getInstance();
Map<String, String> headers = new HashMap<>();
if (StringUtils.isNotBlank(business.getAccessKey())) {
headers.put(ACCESS_KEY_NAME, business.getAccessKey());
}
try {
httpClient.post(business.getReviewCallbackApi(), JSONObject.toJSONString(result), headers);
} catch (IOException e) {
LOGGER.error("租户审核结构回调异常 by id {}", id, e);
return ResponseUtils.newErrorResponse(ErrorCode.CONNECTION_TIMEOUT);
}
}
}
}
return ResponseUtils.newSuccessResponse();
}