spring MVC 管理HttpClient---实现在java中直接向Controller发送请求

来源:互联网 发布:瑜伽师地论 知乎 编辑:程序博客网 时间:2024/05/17 07:32

在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){//实例化httpclientCloseableHttpClient 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){//实例化httpClientCloseableHttpClient 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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsdhttp://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.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">    <!-- 配置占位符 --><beanclass="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#5000http.request.connectTimeout=5000#数据传输的最长时间http.request.socketTimeout=30000#提交请求前测试连接是否可用http.request.staleConnectionCheckEnabled=true#设置连接总数http.pool.maxTotal=200#设置每个地址的并发数http.pool.defaultMaxPerRoute=100


一个必须的类,几记得修改xml里的该类的路径:

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":"系统管理"}]

可以通过我另一篇文章http://blog.csdn.net/u012116457/article/details/24371877里的方法将json转为map等。



0 0