import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author zhangpcxy@163.com
* @comment All Rights Reserved.http工具类
* @version 1.0
* @date 2018年01月18日 上午09:43:14
*/
public class HttpClientUtils {
private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class);
public static final String URL_PARAM_CHARSET_UTF8 = "UTF-8"; // 定义编码格式 UTF-8
public static final String URL_PARAM_CHARSET_GBK = "GBK"; // 定义编码格式 GBK
private static final String EMPTY = "";
private static MultiThreadedHttpConnectionManager connectionManager = null;
private static int connectionTimeOut = 10000;
private static int socketTimeOut = 60000;
private static int maxConnectionPerHost = 20;
private static int maxTotalConnections = 20;
private static HttpClient client;
static {
connectionManager = new MultiThreadedHttpConnectionManager();
connectionManager.getParams().setConnectionTimeout(connectionTimeOut);
connectionManager.getParams().setSoTimeout(socketTimeOut);
connectionManager.getParams().setDefaultMaxConnectionsPerHost(maxConnectionPerHost);
connectionManager.getParams().setMaxTotalConnections(maxTotalConnections);
client = new HttpClient(connectionManager);
}
public static String getResponseBody(String url,String requestBody,String charset ,String contentType)throws Exception{
StringBuffer response = new StringBuffer();
InputStream inputStream = null;
BufferedReader reader = null;
PostMethod postMethod = new PostMethod(url);
postMethod.setRequestHeader("Content-Type", contentType);
// 将要提交的数据放入postMethod中
// postMethod.setRequestBody(requestBody);
RequestEntity entity = new StringRequestEntity(requestBody, contentType, charset);
postMethod.setRequestEntity( entity );
try {
// 执行postMethod
int statusCode = client.executeMethod(postMethod);
if(statusCode != HttpStatus.SC_OK){
logger.error( "服务器返回状态码为"+statusCode );
}
inputStream = postMethod.getResponseBodyAsStream();
reader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
String inputLine = null;
while ((inputLine = reader.readLine()) != null) {
response.append(inputLine);
}
} catch (Exception e) {
throw new Exception(String.format("POST方式提交数据异常(%s)", e.getMessage()), e);
} finally {
if (reader != null) {
reader.close();
}
if (inputStream != null) {
inputStream.close();
}
if (postMethod != null) {
postMethod.releaseConnection();
}
}
return response.toString();
}
/**
* POST方式提交数据
*
* @param url 待请求的URL
* @param params 要提交的数据
* @param charset 编码
* @return 响应结果
* @throws IOException IO异常
*/
public static String sendPost(String url, Map<String, String> params, String charset) throws Exception {
String response = EMPTY;
PostMethod postMethod = new PostMethod(url);
postMethod.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=" + charset);
// 将表单的值放入postMethod中
Set<String> keySet = params.keySet();
for (String key : keySet) {
String value = params.get(key);
postMethod.addParameter(key, value);
}
try {
// 执行postMethod
int statusCode = client.executeMethod(postMethod);
if (statusCode == HttpStatus.SC_OK) {
response = postMethod.getResponseBodyAsString();
} else {
throw new RuntimeException("响应状态码 = " + postMethod.getStatusCode());
}
} catch (HttpException e) {
throw new HttpException("发生致命的异常,可能是协议不对或者返回的内容有问题", e);
} catch (IOException e) {
throw new IOException("发生网络异常", e);
} catch (Exception e) {
throw new Exception(String.format("POST方式提交数据异常(%s)", e.getMessage()), e);
} finally {
if (postMethod != null) {
postMethod.releaseConnection();
}
}
return response;
}
/**
* POST方式提交数据
*
* @param url 待请求的URL
* @param body 要提交的数据
* @param charset 编码
* @return 响应结果
* @throws IOException IO异常
*/
@SuppressWarnings("deprecation")
public static String sendPost2Body(String url, String body, String charset) throws Exception {
StringBuffer response = new StringBuffer(EMPTY);
InputStream inputStream = null;
BufferedReader reader = null;
PostMethod postMethod = new PostMethod(url);
postMethod.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=" + charset);
// 将要提交的数据放入postMethod中
postMethod.setRequestBody(body);
try {
// 执行postMethod
int statusCode = client.executeMethod(postMethod);
if (statusCode == HttpStatus.SC_OK) {
inputStream = postMethod.getResponseBodyAsStream();
reader = new BufferedReader(new InputStreamReader(inputStream, postMethod.getResponseCharSet()));
String inputLine = null;
while ((inputLine = reader.readLine()) != null) {
response.append(inputLine);
}
} else {
throw new Exception("响应状态码 = " + postMethod.getStatusCode());
}
} catch (HttpException e) {
throw new HttpException("发生致命的异常,可能是协议不对或者返回的内容有问题", e);
} catch (IOException e) {
throw new IOException("发生网络异常", e);
} catch (Exception e) {
throw new Exception(String.format("POST方式提交数据异常(%s)", e.getMessage()), e);
} finally {
if (reader != null) {
reader.close();
}
if (inputStream != null) {
inputStream.close();
}
if (postMethod != null) {
postMethod.releaseConnection();
}
}
return response.toString();
}
/**
* POST方式提交数据
*
* @param url 待请求的URL
* @param body 要提交的数据
* @param charset 编码
* @param contentType MIME类型
* @return 响应结果
* @throws IOException IO异常
*/
@SuppressWarnings("deprecation")
public static String sendPost2Body(String url, String body, String charset, String contentType) throws Exception {
StringBuffer response = new StringBuffer(EMPTY);
InputStream inputStream = null;
BufferedReader reader = null;
PostMethod postMethod = new PostMethod(url);
postMethod.setRequestHeader("Content-Type", contentType + ";charset=" + charset);
// 将要提交的数据放入postMethod中
postMethod.setRequestBody(body);
try {
// 执行postMethod
int statusCode = client.executeMethod(postMethod);
if (statusCode == HttpStatus.SC_OK) {
inputStream = postMethod.getResponseBodyAsStream();
reader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
String inputLine = null;
while ((inputLine = reader.readLine()) != null) {
response.append(inputLine);
}
} else {
throw new Exception("响应状态码 = " + postMethod.getStatusCode());
}
} catch (HttpException e) {
throw new HttpException("发生致命的异常,可能是协议不对或者返回的内容有问题", e);
} catch (IOException e) {
throw new IOException("发生网络异常", e);
} catch (Exception e) {
throw new Exception(String.format("POST方式提交数据异常(%s)", e.getMessage()), e);
} finally {
if (reader != null) {
reader.close();
}
if (inputStream != null) {
inputStream.close();
}
if (postMethod != null) {
postMethod.releaseConnection();
}
}
return response.toString();
}
/**
* Description: 发送参数为xml格式的post请求
* @Version1.0 2018年02月02日 上午10:40:11 by 张鹏程(zhangpcxy@163.com) create
* @param url
* @param object2Xml
* @return
*/
public static String doPost(String url, Object object2Xml) throws UnsupportedEncodingException {
String result = "";
// 创建HttpClientBuilder
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
// HttpClient
CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
HttpPost httpPost = new HttpPost(url);
String postDataXML = XMLParser.toXML(object2Xml);
logger.info("API POST DATA:");
logger.info(postDataXML);
StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");
httpPost.addHeader("Content-Type", "text/xml");
httpPost.setEntity(postEntity);
logger.info("executing request" + httpPost.getRequestLine());
try {
HttpResponse response = closeableHttpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, "UTF-8");
} catch (ConnectionPoolTimeoutException e) {
logger.error("http get throw ConnectionPoolTimeoutException(wait time out)", e);
} catch (ConnectTimeoutException e) {
logger.error("http get throw ConnectTimeoutException", e);
} catch (SocketTimeoutException e) {
logger.error("http get throw SocketTimeoutException", e);
} catch (Exception e) {
logger.error("http get throw Exception", e);
} finally {
httpPost.releaseConnection();
}
return result;
}
/**
* Description: GET请求
* @Version1.0 2018年02月02日 上午10:50:14 by zhangpcxy@163.com create
* @param requestUrl
* @return
* @throws Exception
*/
public static String doGet(String requestUrl) throws Exception {
// 创建HttpClientBuilder
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
// HttpClient
CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
HttpGet httpget = new HttpGet(requestUrl);
httpget.addHeader("Content-Type", "text/html;charset=UTF-8");
try {
logger.debug("Executing request " + httpget.getRequestLine());
// Create a custom response handler
ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
@Override
public String handleResponse(
final HttpResponse response) throws ClientProtocolException, IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 && status < 300) {
HttpEntity entity = response.getEntity();
return entity != null ? EntityUtils.toString(entity) : null;
} else {
throw new ClientProtocolException("Unexpected response status: " + status);
}
}
};
return closeableHttpClient.execute(httpget, responseHandler);
} finally {
httpget.releaseConnection();
}
}
public static byte[] sendGet(String url) {
ByteArrayOutputStream bos=new ByteArrayOutputStream();
InputStream in = null;
try {
String urlNameString = url ;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
in = connection.getInputStream();
byte[] buffer=new byte[1024];
int len=0;
while ((len=in.read(buffer))!=-1) {
bos.write(buffer,0,len);
}
bos.flush();
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
bos.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return bos.toByteArray();
}
/**
* POST方式提交数据
*
* @param url 待请求的URL
* @param body 要提交的数据
* @param charset 编码
* @return 响应结果
* @throws IOException IO异常
*/
@SuppressWarnings("deprecation")
public static byte[] sendPostBody(String url, String body, String charset,String contentType,String acceptEncoding) throws Exception {
ByteArrayOutputStream bos=new ByteArrayOutputStream();
InputStream inputStream = null;
PostMethod postMethod = new PostMethod(url);
postMethod.setRequestHeader("Content-Type", contentType + ";charset=" + charset);
if(StringUtils.isNotEmpty(acceptEncoding)){
postMethod.setRequestHeader("Accept-Encoding", acceptEncoding);
}
// 将要提交的数据放入postMethod中
postMethod.setRequestBody(body);
try {
// 执行postMethod
int statusCode = client.executeMethod(postMethod);
if (statusCode == HttpStatus.SC_OK) {
inputStream = postMethod.getResponseBodyAsStream();
byte[] buffer=new byte[1024];
int len=0;
while ((len=inputStream.read(buffer))!=-1) {
bos.write(buffer,0,len);
}
bos.flush();
} else {
throw new Exception("响应状态码 = " + postMethod.getStatusCode());
}
} catch (HttpException e) {
throw new HttpException("发生致命的异常,可能是协议不对或者返回的内容有问题", e);
} catch (IOException e) {
throw new IOException("发生网络异常", e);
} catch (Exception e) {
throw new Exception(String.format("POST方式提交数据异常(%s)", e.getMessage()), e);
} finally {
if (inputStream != null) {
inputStream.close();
bos.close();
}
if (postMethod != null) {
postMethod.releaseConnection();
}
}
return bos.toByteArray();
}
参数为xml格式的POST请求 单独分出来来一个类,使用上面的Api时需要引入XMLParser.java这个类
import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.DomDriver; import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; public class XMLParser { @SuppressWarnings("unchecked") public static <T> T getObjectFromXML(String xml, Class<T> tClass) { //将从API返回的XML数据映射到Java对象 XStream xStreamForResponseData = new XStream(); xStreamForResponseData.alias("xml", tClass); xStreamForResponseData.ignoreUnknownElements();//暂时忽略掉一些新增的字段 return (T) xStreamForResponseData.fromXML(xml); } public static InputStream getStringStream(String sInputString) throws UnsupportedEncodingException { ByteArrayInputStream tInputStringStream = null; if (sInputString != null && !sInputString.trim().equals("")) { tInputStringStream = new ByteArrayInputStream(sInputString.getBytes("UTF-8")); } return tInputStringStream; } public static Map<String,Object> getMapFromXML(String xmlString) throws ParserConfigurationException, IOException, SAXException { //这里用Dom的方式解析回包的最主要目的是防止API新增回包字段 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); InputStream is = getStringStream(xmlString); Document document = builder.parse(is); //获取到document里面的全部结点 NodeList allNodes = document.getFirstChild().getChildNodes(); Node node; Map<String, Object> map = new HashMap<String, Object>(); int i=0; while (i < allNodes.getLength()) { node = allNodes.item(i); if(node instanceof Element){ map.put(node.getNodeName(),node.getTextContent()); } i++; } return map; } public static String toXML(Object o) { XStream xStream = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_"))); xStream.autodetectAnnotations(true); return xStream.toXML(o); } }
当然,也需要引入一些pom依赖,下面就是这个使用这个工具类所需要的pom.xml
<!--HttpClientUtils--> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.3</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.1</version> </dependency> <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.0</version> </dependency> <dependency> <groupId>org.glassfish.main.common</groupId> <artifactId>common-util</artifactId> <version>3.1.2</version> </dependency> <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.7</version> </dependency>