HTTP协议的特点如下:
- 支持客户/服务器模式。
- 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。
由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。 - 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
- 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
- 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
HttpClient
HttpClient 是Apache HttpComponents 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 不是浏览器,它是一个客户端 HTTP 协议传输类库。HttpClient 被用来发送和接受 HTTP 消息。HttpClient 不会处理 HTTP 消息的内容,不会进行 javascript 解析,不会关心 content type,如果没有明确设置,HttpClient 也不会对请求进行格式化、重定向 url,或者其他任何和 HTTP 消息传输相关的功能。
使用步骤
使用HttpClient发送请求、接收响应很简单,一般需要如下几步即可。
-
创建HttpClient对象。
-
创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
-
如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
-
调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。
-
调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
-
释放连接。无论执行方法是否成功,都必须释放连接
具体代码实现如下:
- pom.xml添加httpclient的jar包依赖
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4.1</version>
</dependency>
- 引入HttpDeleteWithBody类
package com.company.project.core;
import java.net.URI;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
public class HttpDeleteWithBody extends HttpEntityEnclosingRequestBase{
public static final String METHOD_NAME = "DELETE";
public HttpDeleteWithBody() {
}
public HttpDeleteWithBody(URI uri) {
setURI(uri);
}
public HttpDeleteWithBody(String uri) {
setURI(URI.create(uri));
}
public String getMethod() {
return METHOD_NAME;
}
}
- 引入httpClientUtil类
package com.company.project.util;
import java.nio.charset.Charset;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.company.project.core.HttpDeleteWithBody;
import com.company.project.core.ServiceException;
public class HttpClientUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientUtil.class);
private static final HttpClient client = HttpClients.createDefault();
/**
* post请求
* @param post post
* @param paramStr json格式的请求体数据
* @return 响应的数据(json)
*/
public static String post(HttpPost post,String paramStr,String cookie){
String data="";
post.addHeader("Content-type","application/json; charset=utf-8");
post.setHeader("Accept", "application/json");
if(StringUtils.isNotEmpty(paramStr)) {
post.setEntity(new StringEntity(paramStr, Charset.forName("UTF-8")));
}
if (StringUtils.isNotEmpty(cookie)) {
post.setHeader("Cookie", cookie);
}
try {
HttpResponse resp = client.execute(post);
//获取HTTP状态码
int statusCode = resp.getStatusLine().getStatusCode();
if(statusCode!=200){
throw new ServiceException("网络错误,状态码:"+statusCode);
}
HttpEntity httpEntity = resp.getEntity();
data = EntityUtils.toString(httpEntity, "UTF-8");
} catch (Exception e) {
LOGGER.error("post获取数据异常",e);
}finally {
post.releaseConnection();
}
return data;
}
/**
* put请求
* @param put put
* @param paramStr json格式的请求体数据
* @return 响应的数据(json)
*/
public static String put(HttpPut put,String paramStr,String cookie){
String data="";
put.addHeader("Content-type","application/json; charset=utf-8");
put.setHeader("Accept", "application/json");
if (StringUtils.isNotEmpty(cookie)) {
put.setHeader("Cookie", cookie);
}
put.setEntity(new StringEntity(paramStr, Charset.forName("UTF-8")));
try {
HttpResponse resp = client.execute(put);
//获取HTTP状态码
int statusCode = resp.getStatusLine().getStatusCode();
if(statusCode!=200){
throw new ServiceException("网络错误,状态码:"+statusCode);
}
HttpEntity httpEntity = resp.getEntity();
data = EntityUtils.toString(httpEntity, "UTF-8");
} catch (Exception e) {
LOGGER.error("put获取数据异常",e);
}finally {
put.releaseConnection();
}
return data;
}
/**
* get请求
* @param get get
* @return 响应的数据(json)
*/
public static String get(HttpGet get,String cookie){
String data="";
get.addHeader("Content-type","application/json; charset=utf-8");
get.setHeader("Accept", "application/json");
if (StringUtils.isNotEmpty(cookie)) {
get.setHeader("Cookie", cookie);
}
try {
HttpResponse resp = client.execute(get);
//获取HTTP状态码
int statusCode = resp.getStatusLine().getStatusCode();
if(statusCode!=200){
throw new ServiceException("网络错误,状态码:"+statusCode);
}
HttpEntity httpEntity = resp.getEntity();
data = EntityUtils.toString(httpEntity, "UTF-8");
} catch (Exception e) {
LOGGER.error("get获取数据异常",e);
}finally {
get.releaseConnection();
}
return data;
}
/**
* delete请求
* @param delete delete
* @return 响应的数据(json)
*/
public static String delete(HttpDelete delete,String cookie){
String data="";
delete.addHeader("Content-type","application/json; charset=utf-8");
delete.setHeader("Accept", "application/json");
if (StringUtils.isNotEmpty(cookie)) {
delete.setHeader("Cookie", cookie);
}
try {
HttpResponse resp = client.execute(delete);
//获取HTTP状态码
int statusCode = resp.getStatusLine().getStatusCode();
if(statusCode!=200){
throw new ServiceException("网络错误,状态码:"+statusCode);
}
HttpEntity httpEntity = resp.getEntity();
data = EntityUtils.toString(httpEntity, "UTF-8");
} catch (Exception e) {
LOGGER.error("get获取数据异常",e);
}finally {
delete.releaseConnection();
}
return data;
}
/**
* delete请求
* @param delete
* @param paramStr json格式的请求体数据
* @return
*/
public static String delete(HttpDeleteWithBody delete,String paramStr,String cookie){
String data="";
delete.addHeader("Content-type","application/json; charset=utf-8");
delete.setHeader("Accept", "application/json");
if (StringUtils.isNotEmpty(cookie)) {
delete.setHeader("Cookie", cookie);
}
delete.setEntity(new StringEntity(paramStr, Charset.forName("UTF-8")));
try {
HttpResponse resp = client.execute(delete);
//获取HTTP状态码
int statusCode = resp.getStatusLine().getStatusCode();
if(statusCode!=200){
throw new ServiceException("网络错误,状态码:"+statusCode);
}
HttpEntity httpEntity = resp.getEntity();
data = EntityUtils.toString(httpEntity, "UTF-8");
} catch (Exception e) {
LOGGER.error("delete获取数据异常",e);
}finally {
delete.releaseConnection();
}
return data;
}
}