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


    在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);
    	}
    
    }
    
    这个类里的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>
    

    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


    一个必须的类,几记得修改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等。



    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    Linux安装RocketMQ
    初识SpringMVC
    事物的锁机制和七种传播行为
    Spring事物
    JdbcTemplate模板
    注解
    AOP代理工厂方式实现增强
    面试题
    Spring框架静态代理和动态代理
    Bootstrap框架(基础篇)之按钮,网格,导航栏,下拉菜单
  • 原文地址:https://www.cnblogs.com/dingxiaoyue/p/4931745.html
Copyright © 2020-2023  润新知