一、HttpClient 简介

HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。Java后台使用httpclient主要目的是为了模拟客户端的请求。

2、HttpClient的请求类型

实现了所有的Http请求类型,相应的类为:HttpGet、HttpPost、HttpDelete、HttpPut

3、Http的使用流程

1)导包

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5</version>
</dependency>

2)创建连接所需要的配置信息

public class HttpClientConfig {

    static int httpConnectTimeout = 10000;//连接超时时间(单位毫秒)

    static int httpSocketTimeout = 10000;//socket读写超时时间(单位毫秒)

    static int httpMaxPoolSize = 100;

    static int httpMonitorInterval = 3000;

    static int httpIdelTimeout = 2000;

    public static int getHttpIdelTimeout() {
return httpIdelTimeout;
} public static int getHttpSocketTimeout() {
return httpSocketTimeout;
} public static int getHttpMaxPoolSize() {
return httpMaxPoolSize;
} public static int getHttpMonitorInterval() {
return httpMonitorInterval;
} public static int getHttpConnectTimeout() {
return httpConnectTimeout;
}
}

3)封装HttpClientUtils类--包括连接池的信息

public class HttpClientUtils {

    private final static Logger logger = Logger.getLogger(HttpClientUtils.class);
private static CloseableHttpClient httpClient;
private static PoolingHttpClientConnectionManager manager; // 连接池管理类
private static ScheduledExecutorService monitorExecutor; // 监控
private final static Object syncLock = new Object(); // 相当于线程锁,用于线程安全
private static final int CONNECT_TIMEOUT = HttpClientConfig.getHttpConnectTimeout();// 设置连接建立的超时时间为10s
private static final int SOCKET_TIMEOUT = HttpClientConfig.getHttpSocketTimeout();
private static final int MAX_CONN = HttpClientConfig.getHttpMaxPoolSize(); // 最大连接数
private static final int Max_PRE_ROUTE = HttpClientConfig.getHttpMaxPoolSize();
private static final int MAX_ROUTE = HttpClientConfig.getHttpMaxPoolSize(); /**
* 对http请求进行基本设置
*
* @param httpRequestBase
* http请求
*/
private static void setRequestConfig(HttpRequestBase httpRequestBase) {
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(CONNECT_TIMEOUT)
.setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
httpRequestBase.setConfig(requestConfig);
} public static CloseableHttpClient getHttpClient(String url) {
String hostName = url.split("/")[2];
// System.out.println(hostName);
int port = 80;
if (hostName.contains(":")) {
String[] args = hostName.split(":");
hostName = args[0];
port = Integer.parseInt(args[1]);
}
if (httpClient == null) {
// 多线程下多个线程同时调用getHttpClient容易导致重复创建httpClient对象的问题,所以加上了同步锁
synchronized (syncLock) {
if (httpClient == null) {
httpClient = createHttpClient(hostName, port);
// 开启监控线程,对异常和空闲线程进行关闭
monitorExecutor = Executors.newScheduledThreadPool(1);
monitorExecutor.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// 关闭异常连接
manager.closeExpiredConnections();
// 关闭5s空闲的连接
manager.closeIdleConnections(HttpClientConfig.getHttpIdelTimeout(), TimeUnit.MILLISECONDS);
logger.debug("close expired and idle for over 5s connection");
}
}, HttpClientConfig.getHttpMonitorInterval(), HttpClientConfig.getHttpMonitorInterval(),
TimeUnit.MILLISECONDS);
}
}
}
return httpClient;
} /**
* 根据host和port构建httpclient实例
*
* @param host
* 要访问的域名
* @param port
* 要访问的端口
* @return
*/
public static CloseableHttpClient createHttpClient(String host, int port) {
ConnectionSocketFactory plainSocketFactory = PlainConnectionSocketFactory.getSocketFactory();
LayeredConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactory.getSocketFactory();
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create()
.register("http", plainSocketFactory).register("https", sslSocketFactory).build();
manager = new PoolingHttpClientConnectionManager(registry);
// 设置连接参数
manager.setMaxTotal(MAX_CONN); // 最大连接数
manager.setDefaultMaxPerRoute(Max_PRE_ROUTE); // 路由最大连接数
HttpHost httpHost = new HttpHost(host, port);
manager.setMaxPerRoute(new HttpRoute(httpHost), MAX_ROUTE);
// 请求失败时,进行请求重试
HttpRequestRetryHandler handler = new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException e, int i, HttpContext httpContext) {
if (i > 3) {
// 重试超过3次,放弃请求
logger.error("retry has more than 3 time, give up request");
return false;
}
if (e instanceof NoHttpResponseException) {
// 服务器没有响应,可能是服务器断开了连接,应该重试
logger.error("receive no response from server, retry");
return true;
}
if (e instanceof SSLHandshakeException) {
// SSL握手异常
logger.error("SSL hand shake exception");
return false;
}
if (e instanceof InterruptedIOException) {
// 超时
logger.error("InterruptedIOException");
return false;
}
if (e instanceof UnknownHostException) {
// 服务器不可达
logger.error("server host unknown");
return false;
}
if (e instanceof ConnectTimeoutException) {
// 连接超时
logger.error("Connection Time out");
return false;
}
if (e instanceof SSLException) {
logger.error("SSLException");
return false;
}
HttpClientContext context = HttpClientContext.adapt(httpContext);
HttpRequest request = context.getRequest();
if (!(request instanceof HttpEntityEnclosingRequest)) {
// 如果请求不是关闭连接的请求
return true;
}
return false;
}
};
CloseableHttpClient client = HttpClients.custom().setConnectionManager(manager).setRetryHandler(handler)
.build();
return client;
} /**
* 关闭连接池
*/
public static void closeConnectionPool() {
try {
httpClient.close();
manager.close();
monitorExecutor.shutdown();
} catch (IOException e) {
e.printStackTrace();
}
} }
/**
* 对http请求进行基本设置
*
* @param httpRequestBase
* http请求
*/
private static void setRequestConfig(HttpRequestBase httpRequestBase) {
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(CONNECT_TIMEOUT)
.setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
httpRequestBase.setConfig(requestConfig);
}

4)form表单提交

    public static String doPostForm(String url, Map<String, String> params) {
HttpPost httpPost = new HttpPost(url);
setRequestConfig(httpPost);
String resultString = "";
CloseableHttpResponse response = null;
try { MultipartEntityBuilder builder = MultipartEntityBuilder.create(); if (params != null) {
for (String key : params.keySet()) {
builder.addPart(key,
new StringBody(params.get(key), ContentType.create("text/plain", Consts.UTF_8)));
}
} HttpEntity reqEntity = builder.build();
httpPost.setEntity(reqEntity); // 发起请求 并返回请求的响应
response = getHttpClient(url).execute(httpPost, HttpClientContext.create());
resultString = EntityUtils.toString(response.getEntity(), "utf-8"); } catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null)
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}

5)File文件上传

    public static String uploadFile(String url, String localFile, String fileParamName, Map<String, String> params) {
HttpPost httpPost = new HttpPost(url);
setRequestConfig(httpPost);
String resultString = "";
CloseableHttpResponse response = null;
try {
// 把文件转换成流对象FileBody
FileBody bin = new FileBody(new File(localFile)); MultipartEntityBuilder builder = MultipartEntityBuilder.create(); // 相当于<input type="file" name="file"/>
builder.addPart("files", bin);
// 相当于<input type="text" name="userName" value=userName>
builder.addPart("filesFileName",
new StringBody(fileParamName, ContentType.create("text/plain", Consts.UTF_8)));
if (params != null) {
for (String key : params.keySet()) {
builder.addPart(key,
new StringBody(params.get(key), ContentType.create("text/plain", Consts.UTF_8)));
}
} HttpEntity reqEntity = builder.build();
httpPost.setEntity(reqEntity); // 发起请求 并返回请求的响应
response = getHttpClient(url).execute(httpPost, HttpClientContext.create());
resultString = EntityUtils.toString(response.getEntity(), "utf-8"); } catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null)
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}

6) 传输Json数据

    public static String doPostJson(String url, String json) {
HttpPost httpPost = new HttpPost(url);
setRequestConfig(httpPost);
String resultString = "";
CloseableHttpResponse response = null;
try {
// 设置ContentType(注:如果只是传普通参数的话,ContentType不一定非要用application/json)
// httpPost.setHeader("Content-Type",
// "application/json;charset=utf8");
httpPost.setHeader("Content-Type", "application/json"); // 创建请求内容
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
// 执行http请求
response = getHttpClient(url).execute(httpPost, HttpClientContext.create());
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
logger.error("httpclient的get请求失败,url:" + url, e);
// e.printStackTrace();
} finally {
try {
if (response != null)
response.close();
} catch (IOException e) {
logger.error("IOException的错误", e);
// e.printStackTrace();
}
}
return resultString;
}

欢迎关注微信公众号【Java典籍】,收看更多Java技术干货!关注即送java全套资料一份

   ▼微信扫一扫下图↓↓↓二维码关注

 

Java后台使用httpclient入门HttpPost请求(form表单提交,File文件上传和传输Json数据)的更多相关文章

  1. node07---post请求、表单提交、文件上传

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. JavaScript实现form表单的多文件上传

    form表单的多文件上传,具体内容如下 formData对象可以使用一系列的键值对来模拟一个完整的表单,然后使用Ajax来发送这个表单 使用<form>表单初始化FormData对象的方式 ...

  3. [Nginx 2] form表单提交,图片上传

    导读:昨晚恶补了一些Nginx服务器的东西,从整体上对Nginx有一个初步的了解.上午去找师哥问了问目前项目中的使用情况,然后就开始上传图片了.这里就简单总结整理一下今天的成果,以后接着提升.简单粗暴 ...

  4. (27) java web的struts2框架的使用-基于表单的多文件上传

    和单个文件上传配置都是一样的,只是在action中接受参数时候,接受的是数组,不再是单个的文件. 一,action的实现: public class MutableFilesUpload extend ...

  5. form表单系列中文件上传及预览

    文件上传及预览 Form提交 Ajax 上传文件 时机: 如果发送的[文件]:->iframe, jQurey(),伪Ajax 预览 import os img_path = os.path.j ...

  6. form表单提交file

    form表单提交文件,这毫无疑问不是个好办法.但是,存在既有意义.既然H5都还让着东西存在着,呢么必然有其意义. form表单中的input type=file这个空间,不得不说奇丑无比!问题是还不能 ...

  7. form表单提交的时候,传过去的值是键值对的形式

    效果展示 第一种需求,点击input的时候,input的value发生改变 $('.group-wrapper input').click(function(){ $(this).val(0); // ...

  8. 获取html 中的内容 将前台的数据获取到后台 用 jquery 生成一个 form表单 提交数据

    使用js创建一个form表单 ,使用post上传到后台中 下面是代码.在获取html内容的时候使用了js节点来获取内容. parent:父节点.上一级的节点 siblings:兄弟节点.同一级别的节点 ...

  9. form表单提交中文乱码(前台中文到JAVA后台乱码)问题及解决

    form表单提交中文乱码(前台中文到JAVA后台乱码)问题及解决 一.问题: 页面输入框中的中文内容,在后台乱码,导致搜索功能失效:(详细可以见后面的重现) 二.原因: 浏览器对于数据的默认编码格式为 ...

随机推荐

  1. F Energy stones

    题意是,有$n$个石头,每个石头有初始能量$E_i$,每秒能量增长$L_i$,以及能量上限$C_i$,有$m$个收能量的时间点,每次把区间$\left[S_i, T_i\right]$石头的能量都给收 ...

  2. python - django 解决 templates 模板语言语法冲突

    # 在使用某个框架时发现语法与Django的模板语法冲突了,于是找到解决方案: {% verbatim %} // 被 verbatim 包裹起来的地方是不会被 django 渲染的 {% endve ...

  3. Passwords Gym - 101174E (AC自动机上DP)

    Problem E: Passwords \[ Time Limit: 1 s \quad Memory Limit: 256 MiB \] 题意 给出两个正整数\(A,B\),再给出\(n\)个字符 ...

  4. ant-design-vue有v-decorator时defaultValue无效

    <a-input v-decorator="[ 'userName', { rules: [ { required: true, message: '请输入您的账号!' } ], in ...

  5. singer tap-minio-csv 使用

    使用tap-minio-csv 我们可以将s3 中csv 的文件,通过singer 的target 写到不用的系统中,可以兼容 s3 的存储类型,以下是一个集成minio 的测试,将minio 中的c ...

  6. smashing 三方widgets 使用

    smashing 有一套自己的约定,包括widgets 以及dashboard,还有就是关于数据的处理 约定如下 三方widgets 统一在widgets 目录下,一般包含了基于coffee 的js ...

  7. redisql 试用

    redisql 是一个redis 模块,可以让redis 支持sql 查询,基于rust编写 具有以下特性 快速,每秒130k的插入 使用标准sql 容易操作,基于redis,使用标准的redis 二 ...

  8. [Java] Spring boot2 整合 Thymeleaf 后 去除模板缓存

    Spring boot2 整合 Thymeleaf 后 去除模板缓存 网上好多文章只是简单粗暴的说,在 application.properties  做如下配置即可: #Thymeleaf cach ...

  9. 请找出"aaaabbcccdddd"字符串中出现最多的字母

    function getCount(str) { for(var code=32;code<128;code++){ var mych=String.fromCharCode(code); va ...

  10. Tecplot——为动画添加求解时间(翻译)

    翻译自:<Tecplot 360 Getting Started Manual>中的Scenic Detour: Add Solution Time Caption 首先展示效果: 在画图 ...