在spring MVC中,大多数时候是由客户端的页面通过ajax等方式向controller发送请求,但有时候需要在Java代码中直接向controller发送请求,这时可以使用HttpCilent实现。
首先用到的包是httpclient-4.3.5.jar和httpcore-4.3.2.jar
先看下面代码:
- package module.system.common;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- 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.impl.client.CloseableHttpClient;
- import org.apache.http.impl.client.HttpClients;
- import org.apache.http.message.BasicNameValuePair;
- import org.apache.http.util.EntityUtils;
- /**
- * 在java中处理http请求.
- * @author nagsh
- *
- */
- public class HttpDeal {
- /**
- * 处理get请求.
- * @param url 请求路径
- * @return json
- */
- public String get(String url){
- //实例化httpclient
- CloseableHttpClient httpclient = HttpClients.createDefault();
- //实例化get方法
- HttpGet httpget = new HttpGet(url);
- //请求结果
- CloseableHttpResponse response = null;
- String content ="";
- try {
- //执行get方法
- response = httpclient.execute(httpget);
- if(response.getStatusLine().getStatusCode()==200){
- content = EntityUtils.toString(response.getEntity(),"utf-8");
- System.out.println(content);
- }
- } catch (ClientProtocolException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return content;
- }
- /**
- * 处理post请求.
- * @param url 请求路径
- * @param params 参数
- * @return json
- */
- public String post(String url,Map<String, String> params){
- //实例化httpClient
- CloseableHttpClient httpclient = HttpClients.createDefault();
- //实例化post方法
- HttpPost httpPost = new HttpPost(url);
- //处理参数
- List<NameValuePair> nvps = new ArrayList <NameValuePair>();
- Set<String> keySet = params.keySet();
- for(String key : keySet) {
- nvps.add(new BasicNameValuePair(key, params.get(key)));
- }
- //结果
- CloseableHttpResponse response = null;
- String content="";
- try {
- //提交的参数
- UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nvps, "UTF-8");
- //将参数给post方法
- httpPost.setEntity(uefEntity);
- //执行post方法
- response = httpclient.execute(httpPost);
- if(response.getStatusLine().getStatusCode()==200){
- content = EntityUtils.toString(response.getEntity(),"utf-8");
- System.out.println(content);
- }
- } catch (ClientProtocolException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return content;
- }
- public static void main(String[] args) {
- HttpDeal hd = new HttpDeal();
- hd.get("http://localhost:8080/springMVC/userType/getAll.do");
- Map<String,String> map = new HashMap();
- map.put("id","1");
- hd.post("http://localhost:8080/springMVC/menu/getChildren.do",map);
- }
- }
package module.system.common;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
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.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
/**
* 在java中处理http请求.
* @author nagsh
*
*/
public class HttpDeal {
/**
* 处理get请求.
* @param url 请求路径
* @return json
*/
public String get(String url){
//实例化httpclient
CloseableHttpClient httpclient = HttpClients.createDefault();
//实例化get方法
HttpGet httpget = new HttpGet(url);
//请求结果
CloseableHttpResponse response = null;
String content ="";
try {
//执行get方法
response = httpclient.execute(httpget);
if(response.getStatusLine().getStatusCode()==200){
content = EntityUtils.toString(response.getEntity(),"utf-8");
System.out.println(content);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return content;
}
/**
* 处理post请求.
* @param url 请求路径
* @param params 参数
* @return json
*/
public String post(String url,Map<String, String> params){
//实例化httpClient
CloseableHttpClient httpclient = HttpClients.createDefault();
//实例化post方法
HttpPost httpPost = new HttpPost(url);
//处理参数
List<NameValuePair> nvps = new ArrayList <NameValuePair>();
Set<String> keySet = params.keySet();
for(String key : keySet) {
nvps.add(new BasicNameValuePair(key, params.get(key)));
}
//结果
CloseableHttpResponse response = null;
String content="";
try {
//提交的参数
UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nvps, "UTF-8");
//将参数给post方法
httpPost.setEntity(uefEntity);
//执行post方法
response = httpclient.execute(httpPost);
if(response.getStatusLine().getStatusCode()==200){
content = EntityUtils.toString(response.getEntity(),"utf-8");
System.out.println(content);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return content;
}
public static void main(String[] args) {
HttpDeal hd = new HttpDeal();
hd.get("http://localhost:8080/springMVC/userType/getAll.do");
Map<String,String> map = new HashMap();
map.put("id","1");
hd.post("http://localhost:8080/springMVC/menu/getChildren.do",map);
}
}
这个类里的get和post方法分别可以实现get请求和post请求,如果单单在一个java测试类里边运行是没问题的,但在controller或jsp中调用,会抛异常。为什么呢?由于是在springMVC中,所以,我们应该把它交给spring来管理。
首先是:httpClient-servlet.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:p="http://www.springframework.org/schema/p"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
- http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
- <!-- 配置占位符 -->
- <bean
- class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
- <property name="location" value="classpath:/httpclient.properties" />
- </bean>
- <!-- 定义httpclient连接池 -->
- <bean id="httpClientConnectionManager" class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager" destroy-method="close">
- <!-- 设置连接总数 -->
- <property name="maxTotal" value="${http.pool.maxTotal}"></property>
- <!-- 设置每个地址的并发数 -->
- <property name="defaultMaxPerRoute" value="${http.pool.defaultMaxPerRoute}"></property>
- </bean>
- <!-- 定义 HttpClient工厂,这里使用HttpClientBuilder构建-->
- <bean id="httpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder" factory-method="create">
- <property name="connectionManager" ref="httpClientConnectionManager"></property>
- </bean>
- <!-- 得到httpClient的实例 -->
- <bean id="httpClient" factory-bean="httpClientBuilder" factory-method="build"/>
- <!-- 定期清理无效的连接 -->
- <bean class="module.system.common.IdleConnectionEvictor" destroy-method="shutdown">
- <constructor-arg index="0" ref="httpClientConnectionManager" />
- <!-- 间隔一分钟清理一次 -->
- <constructor-arg index="1" value="60000" />
- </bean>
- <!-- 定义requestConfig的工厂 -->
- <bean id="requestConfigBuilder" class="org.apache.http.client.config.RequestConfig.Builder">
- <!-- 从连接池中获取到连接的最长时间 -->
- <property name="connectionRequestTimeout" value="${http.request.connectionRequestTimeout}"/>
- <!-- 创建连接的最长时间 -->
- <property name="connectTimeout" value="${http.request.connectTimeout}"/>
- <!-- 数据传输的最长时间 -->
- <property name="socketTimeout" value="${http.request.socketTimeout}"/>
- <!-- 提交请求前测试连接是否可用 -->
- <property name="staleConnectionCheckEnabled" value="${http.request.staleConnectionCheckEnabled}"/>
- </bean>
- <!-- 得到requestConfig实例 -->
- <bean id="requestConfig" factory-bean="requestConfigBuilder" factory-method="build" />
- </beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<!-- 配置占位符 -->
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:/httpclient.properties" />
</bean>
<!-- 定义httpclient连接池 -->
<bean id="httpClientConnectionManager" class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager" destroy-method="close">
<!-- 设置连接总数 -->
<property name="maxTotal" value="${http.pool.maxTotal}"></property>
<!-- 设置每个地址的并发数 -->
<property name="defaultMaxPerRoute" value="${http.pool.defaultMaxPerRoute}"></property>
</bean>
<!-- 定义 HttpClient工厂,这里使用HttpClientBuilder构建-->
<bean id="httpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder" factory-method="create">
<property name="connectionManager" ref="httpClientConnectionManager"></property>
</bean>
<!-- 得到httpClient的实例 -->
<bean id="httpClient" factory-bean="httpClientBuilder" factory-method="build"/>
<!-- 定期清理无效的连接 -->
<bean class="module.system.common.IdleConnectionEvictor" destroy-method="shutdown">
<constructor-arg index="0" ref="httpClientConnectionManager" />
<!-- 间隔一分钟清理一次 -->
<constructor-arg index="1" value="60000" />
</bean>
<!-- 定义requestConfig的工厂 -->
<bean id="requestConfigBuilder" class="org.apache.http.client.config.RequestConfig.Builder">
<!-- 从连接池中获取到连接的最长时间 -->
<property name="connectionRequestTimeout" value="${http.request.connectionRequestTimeout}"/>
<!-- 创建连接的最长时间 -->
<property name="connectTimeout" value="${http.request.connectTimeout}"/>
<!-- 数据传输的最长时间 -->
<property name="socketTimeout" value="${http.request.socketTimeout}"/>
<!-- 提交请求前测试连接是否可用 -->
<property name="staleConnectionCheckEnabled" value="${http.request.staleConnectionCheckEnabled}"/>
</bean>
<!-- 得到requestConfig实例 -->
<bean id="requestConfig" factory-bean="requestConfigBuilder" factory-method="build" />
</beans>
httpclient.properties:
- #从连接池中获取到连接的最长时间
- http.request.connectionRequestTimeout=500
- #5000
- http.request.connectTimeout=5000
- #数据传输的最长时间
- http.request.socketTimeout=30000
- #提交请求前测试连接是否可用
- http.request.staleConnectionCheckEnabled=true
- #设置连接总数
- http.pool.maxTotal=200
- #设置每个地址的并发数
- http.pool.defaultMaxPerRoute=100
#从连接池中获取到连接的最长时间
http.request.connectionRequestTimeout=500
#5000
http.request.connectTimeout=5000
#数据传输的最长时间
http.request.socketTimeout=30000
#提交请求前测试连接是否可用
http.request.staleConnectionCheckEnabled=true
#设置连接总数
http.pool.maxTotal=200
#设置每个地址的并发数
http.pool.defaultMaxPerRoute=100
- package module.system.common;
- import org.apache.http.conn.HttpClientConnectionManager;
- /**
- * 定期清理无效的http连接
- */
- public class IdleConnectionEvictor extends Thread {
- private final HttpClientConnectionManager connMgr;
- private Integer waitTime;
- private volatile boolean shutdown;
- public IdleConnectionEvictor(HttpClientConnectionManager connMgr,Integer waitTime) {
- this.connMgr = connMgr;
- this.waitTime = waitTime;
- this.start();
- }
- @Override
- public void run() {
- try {
- while (!shutdown) {
- synchronized (this) {
- wait(waitTime);
- // 关闭失效的连接
- connMgr.closeExpiredConnections();
- }
- }
- } catch (InterruptedException ex) {
- // 结束
- }
- }
- /**
- * 销毁释放资源
- */
- public void shutdown() {
- shutdown = true;
- synchronized (this) {
- notifyAll();
- }
- }
- }
package module.system.common;
import org.apache.http.conn.HttpClientConnectionManager;
/**
* 定期清理无效的http连接
*/
public class IdleConnectionEvictor extends Thread {
private final HttpClientConnectionManager connMgr;
private Integer waitTime;
private volatile boolean shutdown;
public IdleConnectionEvictor(HttpClientConnectionManager connMgr,Integer waitTime) {
this.connMgr = connMgr;
this.waitTime = waitTime;
this.start();
}
@Override
public void run() {
try {
while (!shutdown) {
synchronized (this) {
wait(waitTime);
// 关闭失效的连接
connMgr.closeExpiredConnections();
}
}
} catch (InterruptedException ex) {
// 结束
}
}
/**
* 销毁释放资源
*/
public void shutdown() {
shutdown = true;
synchronized (this) {
notifyAll();
}
}
}
重新部署一下,就可以在controller里实例化HttpDeal类并调用它的方法了。我的spring MVC整合了json,所以返回值是json数据,比如:
- [{"id":1,"type":"管理员","menu":"1,2,3"},{"id":2,"type":"操作员","menu":"1,2,"}]
- [{"id":4,"attributes":null,"children":[],"text":"用户管理","pid":1,"url":"../user/getPage.do","title":null,"ptext":"系统管理"},{"id":5,"attributes":null,"children":[],"text":"部门管理","pid":1,"url":"../department/getPage.do","title":null,"ptext":"系统管理"},{"id":10,"attributes":null,"children":[],"text":"权限管理","pid":1,"url":"../userType/getPage.do","title":null,"ptext":"系统管理"}]
[{"id":1,"type":"管理员","menu":"1,2,3"},{"id":2,"type":"操作员","menu":"1,2,"}]
[{"id":4,"attributes":null,"children":[],"text":"用户管理","pid":1,"url":"../user/getPage.do","title":null,"ptext":"系统管理"},{"id":5,"attributes":null,"children":[],"text":"部门管理","pid":1,"url":"../department/getPage.do","title":null,"ptext":"系统管理"},{"id":10,"attributes":null,"children":[],"text":"权限管理","pid":1,"url":"../userType/getPage.do","title":null,"ptext":"系统管理"}]