服务器请求



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
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.entity.BasicHttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.pool.PoolStats;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

/**
 * 通过http连接池来管理连接
 * 注:closeConnections()方法需要另起一个线程,每隔一段时间执行一次回收已成功或者已过期的连接。(如用spring的定时任务)
 * @author liluqing
 * @date 2016-06-01
 */
public class HttpUtils {
    static Logger logger=Logger.getLogger(HttpUtils.class);
    
    private static PoolingHttpClientConnectionManager cm =null;
    
    //定义编码格式 UTF-8
    public static final String URL_PARAM_DECODECHARSET_UTF8 = "UTF-8";
    //定义编码格式 GBK
    public static final String URL_PARAM_DECODECHARSET_GBK = "GBK";
    private static final String URL_PARAM_CONNECT_FLAG = "&";
    private static final String EMPTY = "";
    private static int connectionTimeOut = 20*60*1000;
    private static int socketTimeOut = 20*60*1000;
    //链接管理器容量,将每个路由的最大连接数增加到200
    private static int maxTotal =100;
     //将每个路由的默认最大并发数。超过最大并发数的线程将进入阻塞状态。直到有链接过期或被关闭。
    private static int maxPerRoute = 20;
    
    static{
        //创建链接管理器
        cm=new PoolingHttpClientConnectionManager();
        //链接管理器容量,将每个路由的最大连接数增加到200
        cm.setMaxTotal(maxTotal);
        //将每个路由的默认最大并发数。超过最大并发数的线程将进入阻塞状态。直到有链接过期或被关闭。
        cm.setDefaultMaxPerRoute(maxPerRoute);  
        //定义将某个路由的最大并发数
        //HttpHost localhost = new HttpHost("locahost", 80);  
        //cm.setMaxPerRoute(new HttpRoute(localhost), 50);//设置对于某个目标主机的最大并发数
    }
    
    /**
     * 重连接管理器中获取CloseableHttpClient对象
     * @return
     */
    public static CloseableHttpClient getCloseableHttpClient(){
        return HttpClients.custom().setConnectionManager(cm).build();
    }
    
    /**
     * 关闭回收所有已经请求成功,或者请求超时的连接
     * 该方法需用spring做一个定时任务每隔5秒(根据具体情况来配置)执行一次
     */
    public static void closeConnections(){
        cm.closeExpiredConnections();  
        cm.closeIdleConnections(30, TimeUnit.SECONDS);
    }
    
    /**
     * 获取连接管理器状态。
     */
    public static String getState(){
        PoolStats state=cm.getTotalStats();
        return "http连接池信息:[可用连接:"+state.getAvailable()+"; 正在执行的连接:"+state.getLeased()+"; 被阻塞的连接:"+state.getPending()+"; 最大可用连接数:"+state.getMax()+"]";
    }
    
    /**
     * 以UTF8的方式发送报文。当目标服务器采用UTF8时,需用该方法。否则会导致请求参数乱码,目标服务器无法解析
     * @param url  连接地址
     * @param xml   报文
     * @param decode  响应报文的编码
     * @return
     */
    public static String httpPostForXMLUTF8(String url,String xml,String decode){
        String result=null;
        CloseableHttpClient client=getCloseableHttpClient();//创建会话
        HttpPost httppost= new HttpPost(url);
        httppost.setHeader("Content-Type", "text/xml;charset=UTF-8");//设置请求头
        StringEntity entity = new StringEntity(xml,  
                ContentType.create("text/xml", Consts.UTF_8));//定义请求消息实体
        entity.setChunked(false);
        RequestConfig requestConfig = RequestConfig.custom().
                setSocketTimeout(socketTimeOut).setConnectTimeout(connectionTimeOut).build();//设置连接超时和socket超时时间
        httppost.setConfig(requestConfig);
        httppost.setEntity(entity);
        CloseableHttpResponse response=null;
        try {
             response=client.execute(httppost);//执行请求
             HttpEntity ety=response.getEntity();//获取响应实体
             result=EntityUtils.toString(ety,decode);//由于税控服务器的编码格式为GBK,故需将返回内容按GBK的方式来解码
        } catch (ClientProtocolException e) {
            logger.error("request url=" + url + ", exception, msg=" + e.getMessage(),e);
        } catch (IOException e) {
            logger.error("request url=" + url + ", exception, msg=" + e.getMessage(),e);
        }finally{
            try {
                if(response!=null){
                    response.close();//关闭响应流
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
    
    /**
     * 以GBK的方式发送报文。当目标服务器采用GBK时,需用该方法。否则会导致请求参数乱码,目标服务器无法解析
     * @param url  连接地址
     * @param xml   报文
     * @param decode  响应报文的编码
     * @return
     */
    public static String httpPostForXMLGBK(String url,String xml,String decode){
        String result=null;
        CloseableHttpClient client=getCloseableHttpClient();//创建会话
        HttpPost httppost= new HttpPost(url);
        httppost.setHeader("Content-Type", "text/xml;charset=UTF-8");//设置请求头
        StringEntity entity = new StringEntity(xml,"gbk");//定义请求消息实体
        entity.setChunked(true);
        RequestConfig requestConfig = RequestConfig.custom().
                setSocketTimeout(socketTimeOut).setConnectTimeout(connectionTimeOut).build();//设置连接超时和socket超时时间
        httppost.setConfig(requestConfig);
        httppost.setEntity(entity);
        CloseableHttpResponse response=null;
        try {
             response=client.execute(httppost);//执行请求
             HttpEntity ety=response.getEntity();//获取响应实体
             result=EntityUtils.toString(ety,decode);//由于税控服务器的编码格式为GBK,故需将返回内容按GBK的方式来解码
        } catch (ClientProtocolException e) {
            logger.error("request url=" + url + ", exception, msg=" + e.getMessage(),e);
        } catch (IOException e) {
            logger.error("request url=" + url + ", exception, msg=" + e.getMessage(),e);
        }finally{
            try {
                if(response!=null){
                    response.close();//关闭响应流
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
    
    /**
     * post请求模拟form表单提交
     * @param url  连接地址
     * @param params  post请求参数
     * @param enc  请求参数编码
     * @return
     */
    public static String httpPost(String url, Map<String, String> params, String enc){
        String result=null;
        CloseableHttpClient client=getCloseableHttpClient();//创建会话
        //设置超时禁止自动提交的2种方法
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(0,false));
        HttpPost httppost= new HttpPost(url);
        //设置头类型为from表单提交
        httppost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=" + enc);
        RequestConfig requestConfig = RequestConfig.custom().
                setSocketTimeout(socketTimeOut).setConnectTimeout(connectionTimeOut).build();//设置连接超时和socket超时时间
        httppost.setConfig(requestConfig);
        
        UrlEncodedFormEntity entity=getUrlEncodedFormEntity(params);
        httppost.setEntity(entity);
        
        CloseableHttpResponse response=null;
        try {
             response=client.execute(httppost);//执行请求
             HttpEntity ety=response.getEntity();//获取响应实体
             result=EntityUtils.toString(ety,URL_PARAM_DECODECHARSET_UTF8);
        } catch (ClientProtocolException e) {
            logger.error("request url=" + url + ", exception, msg=" + e.getMessage(),e);
        } catch (IOException e) {
            logger.error("request url=" + url + ", exception, msg=" + e.getMessage(),e);
        }finally{
            try {
                if(response!=null){
                    response.close();//关闭响应流
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
    
    /**
     * get请求
     * @param url
     * @return
     */
    public static String httpGet(String url){
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = null;
        CloseableHttpClient httpClient = getCloseableHttpClient();
        RequestConfig requestConfig = RequestConfig.custom().
                setSocketTimeout(socketTimeOut).setConnectTimeout(connectionTimeOut).build();
        httpGet.setConfig(requestConfig);
        try {
            response = httpClient.execute(httpGet, new BasicHttpContext());
            if (response.getStatusLine().getStatusCode() != 200) {
                return null;
            }
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String resultStr = EntityUtils.toString(entity,URL_PARAM_DECODECHARSET_UTF8);
                return resultStr;
            }
        } catch (IOException e) {
            logger.error("request url=" + url + ", exception, msg=" + e.getMessage(),e);
        } finally {
            if (response != null) try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    
    /**
     * get请求模拟表单提交
     * @param url
     * @param params
     * @param enc
     * @return
     */
    public static String httpGet(String url, Map<String, String> params, String enc){
        StringBuilder strtTotalURL = new StringBuilder(EMPTY);
        if(strtTotalURL.indexOf("?") == -1) {
            strtTotalURL.append(url).append("?").append(getUrl(params, enc));
        } else {
            strtTotalURL.append(url).append("&").append(getUrl(params, enc));
        }
        HttpGet httpGet = new HttpGet(strtTotalURL.toString());
        //设置头类型为from表单提交
        httpGet.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=" + enc);
        CloseableHttpResponse response = null;
        CloseableHttpClient httpClient = getCloseableHttpClient();
        RequestConfig requestConfig = RequestConfig.custom().
                setSocketTimeout(socketTimeOut).setConnectTimeout(connectionTimeOut).build();
        httpGet.setConfig(requestConfig);
        try {
            response = httpClient.execute(httpGet, new BasicHttpContext());
            if (response.getStatusLine().getStatusCode() != 200) {
                return null;
            }
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String resultStr = EntityUtils.toString(entity,URL_PARAM_DECODECHARSET_UTF8);
                return resultStr;
            }
        } catch (IOException e) {
            logger.error("request url=" + strtTotalURL.toString() + ", exception, msg=" + e.getMessage(),e);
        } finally {
            if (response != null) try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    
    
    
    /**
     * 据Map生成URL字符串
     * @param map
     *             Map
     * @param valueEnc
     *             URL编码
     * @return
     *             URL
     */
    private static String getUrl(Map<String, String> map, String valueEnc) {
        
        if (null == map || map.keySet().size() == 0) {
            return (EMPTY);
        }
        StringBuffer url = new StringBuffer();
        Set<String> keys = map.keySet();
        for (Iterator<String> it = keys.iterator(); it.hasNext();) {
            String key = it.next();
            if (map.containsKey(key)) {
                String val = map.get(key);
                String str = val != null ? val : EMPTY;
                try {
                    str = URLEncoder.encode(str, valueEnc);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                url.append(key).append("=").append(str).append(URL_PARAM_CONNECT_FLAG);
            }
        }
        String strURL = EMPTY;
        strURL = url.toString();
        if (URL_PARAM_CONNECT_FLAG.equals(EMPTY + strURL.charAt(strURL.length() - 1))) {
            strURL = strURL.substring(0, strURL.length() - 1);
        }
        return (strURL);
    }
    
    public static UrlEncodedFormEntity getUrlEncodedFormEntity(Map<String, String> params){
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        if(params!=null&&params.size()>0){
            Iterator<Entry<String, String>> it=params.entrySet().iterator();
            while(it.hasNext()){
                Entry<String, String> en=it.next();
                formparams.add(new BasicNameValuePair(en.getKey(),en.getValue()));
            }
        }
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams,  
                                                                  Consts.UTF_8);
        entity.setChunked(true);
        return entity;
    }
    
    public static String dopostXmlStr(String surl,String xml) throws IOException{
        URL url=null;
        HttpURLConnection connection = null;

        url = new URL(surl);   
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestProperty("Content-Type", "text/xml");
        connection.setDoOutput(true);
        OutputStreamWriter out = new OutputStreamWriter(connection     
                .getOutputStream(), "utf-8");
        out.write(xml);
        out.flush();
        out.close();
        
        // 一旦发送成功,用以下方法就可以得到服务器的回应:
        String responseContent = "";
          
        //读取数据并按GBK方式进行解码
        InputStreamReader l_urlStream = new InputStreamReader(connection.getInputStream(),"utf-8");
        // 传说中的三层包装阿
        BufferedReader l_reader = new BufferedReader(l_urlStream);
        
        String sCurrentLine="";//按行读取xml
        while ((sCurrentLine = l_reader.readLine()) != null) {
            responseContent += sCurrentLine + " ";     
        }
        if (connection != null) {
            connection.disconnect();//销毁连接
        }
        return responseContent;
    }

}

原文地址:https://www.cnblogs.com/alanming/p/8144922.html