Java 发送http请求(get、post)

1.情景展示

  java发送get请求、post请求(form表单、json数据)至另一服务器;

  可设置HTTP请求头部信息,可以接收服务器返回cookie信息,可以上传文件等; 

2.代码实现

所需jar包:httpcore-4.4.1.jar;httpclient-4.4.1.jar;httpmime-4.4.1.jar;epoint-utils-9.3.3.jar

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
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.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import com.epoint.core.utils.string.StringUtil;
/**
 * HttpClient工具类,使用http-client包实现,原先的common-httpclient已经淘汰
 * 
 * @作者 ko
 * @version [版本号, 2017年10月18日]
 */
public class HttpUtil
{
    private static PoolingHttpClientConnectionManager connMgr;
    private static RequestConfig requestConfig;
    private static final int MAX_TIMEOUT =  7000 ;

    /**
     * 直接以流返回
     */
    public static final int RTN_TYPE_1 =  1 ;
    /**
     * 直接以string返回
     */
    public static final int RTN_TYPE_2 =  2 ;
    /**
     * 以map返回,reslut:接口结果string;statusCode:http状态码
     */
    public static final int RTN_TYPE_3 =  3 ;
    /**
     * 以map返回,reslut:接口结果string;statusCode:http状态码;cookie:response的cookie
     * cookie值键值对,格式 key1=value1;key2=value2;...
     */
    public static final int RTN_TYPE_4 =  4 ;
    /**
     * 默认上传文件的文件流或file 的key Name
     */
    private static final String DEFAULT_BINARYBODY_KEYNAME =  "file" ;

    static {
        // 设置连接池
        connMgr =  new PoolingHttpClientConnectionManager();
        // 设置连接池大小
        connMgr.setMaxTotal( 100 );
        connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal());
        // 在提交请求之前 测试连接是否可用
        connMgr.setValidateAfterInactivity( 1 );

        RequestConfig.Builder configBuilder = RequestConfig.custom();
        // 设置连接超时
        configBuilder.setConnectTimeout(MAX_TIMEOUT);
        // 设置读取超时
        configBuilder.setSocketTimeout(MAX_TIMEOUT);
        // 设置从连接池获取连接实例的超时
        configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT);
        requestConfig = configBuilder.build();
    }

    /**
     * 发送 GET请求
     * 
     * @param apiUrl
     *            API接口URL
     * @return String 响应内容
     */
    public static String doGet(String apiUrl) {
        return doHttp(apiUrl,  null ,  "get" , RTN_TYPE_2);
    }

    /**
     * 发送POST请求
     * 
     * @param apiUrl
     *            API接口URL
     * @param params
     *            K-V参数
     * @return String 响应内容
     */
    public static String doPost(String apiUrl, Map<string, object=""> params) {
        return doHttp(apiUrl, params,  "post" , RTN_TYPE_2);
    }

    /**
     * 发送POST请求
     * 
     * @param apiUrl
     *            API接口URL
     * @param json
     *            json参数
     * @return String 响应内容
     */
    public static String doPostJson(String apiUrl, String json) {
        return doHttp(apiUrl, json,  "post" , RTN_TYPE_2);
    }

    /**
     * 发送 http 请求
     * 
     * @param apiUrl
     *            API接口URL
     * @param params
     *            {Map<string, object=""> K-V形式、json字符串}
     * @param method
     *            {null、或者post:POST请求、patch:PATCH请求、delete:DELETE请求、get:GET请求}
     * @param type
     *            {HttpUtil.RTN_TYPE_1:请求返回stream(此时流需要在外部手动关闭);HttpUtil.
     *            RTN_TYPE_2:string;HttpUtil.RTN_TYPE_3:返回一个map,map包含结果(
     *            结果是string形式)以及http状态码;HttpUtil.RTN_TYPE_4:返回一个map,map包含结果(
     *            结果是string形式), http状态码和cookie;其他情况返回string}
     *            如果结果是个map,key为:result,statusCode,cookie,分别返回 结果
     *            string,http状态码,cookie; cookie值键值对,格式
     *            key1=value1;key2=value2;...
     * @return stream或 string 或 map
     */
    public static  T doHttp(String apiUrl, Object params, String method,  int type) {
        return doHttp(apiUrl,  null , params, method, type);
    }

    /**
     * 发送 http 请求
     * 
     * @param apiUrl
     *            API接口URL
     * @param headerMap
     *            header信息Map<string, string="">,可设置cookie
     * @param params
     *            {Map<string, object=""> K-V形式、json字符串}
     * @param method
     *            {null、或者post:POST请求、patch:PATCH请求、delete:DELETE请求、get:GET请求}
     * @param type
     *            {HttpUtil.RTN_TYPE_1:请求返回stream(此时流需要在外部手动关闭);HttpUtil.
     *            RTN_TYPE_2:string;HttpUtil.RTN_TYPE_3:返回一个map,map包含结果(
     *            结果是string形式)以及http状态码;HttpUtil.RTN_TYPE_4:返回一个map,map包含结果(
     *            结果是string形式), http状态码和cookie;其他情况返回string}
     *            如果结果是个map,key为:result,statusCode,cookie,分别返回 结果
     *            string,http状态码,cookie; cookie值键值对,格式
     *            key1=value1;key2=value2;...
     * @return stream或 string 或 map
     */
    public static  T doHttp(String apiUrl, Map<string, string=""> headerMap, Object params, String method,  int type) {
        CloseableHttpClient httpClient =  null ;
        if (isSSL(apiUrl)) {
            httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory())
                    .setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();
        }
        else {
            httpClient = HttpClients.createDefault();
        }
        return doHttp(httpClient, apiUrl, headerMap, params, method, type);
    }

    /**
     * 发送 http 请求
     * 
     * @param httpClient
     *            httpclient对象 由外部传入,用户 需要保持登录状态等情况 此时如果要ssl,那么要在外部加入ssl特性
     *            httpClient =
     *            HttpClients.custom().setSSLSocketFactory(HttpUtil.
     *            createSSLConnSocketFactory())
     *            .setConnectionManager(HttpUtil.getConnMgr()).
     *            setDefaultRequestConfig(HttpUtil..getRequestConfig()).build();
     * @param apiUrl
     *            API接口URL
     * @param headerMap
     *            header信息Map<string, string="">,可设置cookie
     * 
     * @param params
     *            {Map<string, object=""> K-V形式、json字符串}
     * @param method
     *            {null、或者post:POST请求、patch:PATCH请求、delete:DELETE请求、get:GET请求}
     * @param type
     *            {HttpUtil.RTN_TYPE_1:请求返回stream(此时流需要在外部手动关闭);HttpUtil.
     *            RTN_TYPE_2:string;HttpUtil.RTN_TYPE_3:返回一个map,map包含结果(
     *            结果是string形式)以及http状态码;HttpUtil.RTN_TYPE_4:返回一个map,map包含结果(
     *            结果是string形式), http状态码和cookie;其他情况返回string}
     *            如果结果是个map,key为:result,statusCode,cookie,分别返回 结果
     *            string,http状态码,cookie; cookie值键值对,格式
     *            key1=value1;key2=value2;...
     * @return stream或 string 或 map
     */
    @SuppressWarnings ( "unchecked" )
    public static  T doHttp(CloseableHttpClient httpClient, String apiUrl, Map<string, string=""> headerMap,
            Object params, String method,  int type) {
        HttpRequestBase httpPost =  null ;
        if (StringUtil.isNotBlank(method)) {
            if ( "patch" .equalsIgnoreCase(method)) {
                httpPost =  new HttpPatch(apiUrl);
            }
            else if ( "delete" .equalsIgnoreCase(method)) {
                httpPost =  new HttpDelete(apiUrl);
            }
            else if ( "get" .equalsIgnoreCase(method)) {
                httpPost =  new HttpGet(apiUrl);
            }
            else if ( "post" .equalsIgnoreCase(method)) {
                httpPost =  new HttpPost(apiUrl);
            }
        }
        else {
            httpPost =  new HttpPost(apiUrl);
        }
        CloseableHttpResponse response =  null ;

        try {
            // 设置header信息
            if (headerMap !=  null && !headerMap.isEmpty()) {
                for (Map.Entry<string, string=""> entry : headerMap.entrySet()) {
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
            if (isSSL(apiUrl)) {
                httpPost.setConfig(requestConfig);
            }
            // 参数不为null、要处理参数
            if (params !=  null ) {
                // get请求拼接在url后面
                if (httpPost  instanceof HttpGet) {
                    StringBuffer param =  new StringBuffer();
                    if (params  instanceof Map) {
                        Map<string, object=""> paramsConvert = (Map<string, object="">) params;
                        int i =  0 ;
                        for (String key : paramsConvert.keySet()) {
                            if (i ==  0 )
                                param.append( "?" );
                            else
                                param.append( "&" );
                            param.append(key).append( "=" ).append(paramsConvert.get(key));
                            i++;
                        }
                    }
                    else {
                        param.append( "?" + params.toString());
                    }
                    apiUrl += param;
                }
                // delete请求暂不处理
                else if (!(httpPost  instanceof HttpDelete)) {
                    // K-V形式
                    if (params  instanceof Map) {
                        Map<string, object=""> paramsConvert = (Map<string, object="">) params;

                        List pairList =  new ArrayList<>(paramsConvert.size());
                        for (Map.Entry<string, object=""> entry : paramsConvert.entrySet()) {
                            NameValuePair pair =  new BasicNameValuePair(entry.getKey(),
                                    entry.getValue() ==  null ?  "" : entry.getValue().toString());
                            pairList.add(pair);
                        }
                        ((HttpEntityEnclosingRequestBase) httpPost)
                                .setEntity( new UrlEncodedFormEntity(pairList, Charset.forName( "UTF-8" )));
                    }
                    // json格式
                    else {
                        StringEntity stringEntity =  new StringEntity(params.toString(),  "UTF-8" );
                        stringEntity.setContentEncoding( "UTF-8" );
                        stringEntity.setContentType( "application/json" );
                        ((HttpEntityEnclosingRequestBase) httpPost).setEntity(stringEntity);
                    }
                }
            }
            response = httpClient.execute(httpPost);
            // int statusCode = response.getStatusLine().getStatusCode();
            // if (statusCode != HttpStatus.SC_OK) {
            // return null;
            // }

            HttpEntity entity = response.getEntity();
            if (entity !=  null ) {
                if (type == RTN_TYPE_1) {
                    return (T) entity.getContent();
                }
                else if (RTN_TYPE_2 == type) {
                    return (T) EntityUtils.toString(entity,  "UTF-8" );
                }
                else if (RTN_TYPE_3 == type || RTN_TYPE_4 == type) {
                    Map<string, string=""> rtnMap =  new HashMap<string, string="">();
                    rtnMap.put( "result" , EntityUtils.toString(entity,  "UTF-8" ));
                    rtnMap.put( "statusCode" , response.getStatusLine().getStatusCode() +  "" );
                    if (RTN_TYPE_4 == type) {
                        rtnMap.put( "cookie" , getCookie(response));
                    }
                    return (T) rtnMap;
                }
                else {
                    return (T) EntityUtils.toString(entity,  "UTF-8" );
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            if (response !=  null && type != RTN_TYPE_1) {
                try {
                    EntityUtils.consume(response.getEntity());
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null ;
    }

    /**
     * 上传附件(post形式)
     * 
     * @param url
     *            请求地址
     * @param headerMap
     *            header参数map Map<string, string="">
     * @param paramMap
     *            额外的参数map,Map<string, string="">
     * @param file
     *            可以选择本地文件上传;如果传了file,又传了fileName,那么文件名以fileName为准,否则 是file的文件名
     * @param fileName
     *            以流传输时,必须指定文件名
     * @param ssl
     *            是否需要ssl
     * @return result,返回上传结果,如果接口没有返回值,则为状态码
     */
    public static String upload(String url, Map<string, string=""> headerMap, Map<string, string=""> paramMap, File file,
            String fileName,  boolean ssl) {
        return upload(url, headerMap, paramMap, file,  null , fileName, ssl);
    }

    /**
     * 上传附件(post形式)
     * 
     * @param url
     *            请求地址
     * @param headerMap
     *            header参数map Map<string, string="">
     * @param paramMap
     *            额外的参数map,Map<string, string="">
     * @param in
     *            文件流
     * @param fileName
     *            以流传输时,必须指定文件名
     * @param ssl
     *            是否需要ssl
     * @return result,返回上传结果,如果接口没有返回值,则为状态码
     */
    public static String upload(String url, Map<string, string=""> headerMap, Map<string, string=""> paramMap, InputStream in,
            String fileName,  boolean ssl) {
        return upload(url, headerMap, paramMap,  null , in, fileName, ssl);
    }

    /**
     * 上传附件(post形式)
     * 
     * @param httpClient
     *            外部传入httpClient
     * @param url
     *            请求地址
     * @param headerMap
     *            header参数map Map<string, string="">
     * @param paramMap
     *            额外的参数map,Map<string, string="">
     * @param file
     *            可以选择本地文件上传;如果传了file,又传了fileName,那么文件名以fileName为准,否则 是file的文件名
     * @param fileName
     *            以流传输时,必须指定文件名
     * @param ssl
     *            是否需要ssl
     * @return result,返回上传结果,如果接口没有返回值,则为状态码
     */
    public static String upload(CloseableHttpClient httpClient, String url, Map<string, string=""> headerMap,
            Map<string, string=""> paramMap, File file, String fileName,  boolean ssl) {
        return upload(httpClient, url, headerMap, paramMap, file,  null , fileName, ssl);
    }

    /**
     * 上传附件(post形式)
     * 
     * @param httpClient
     *            外部传入httpClient
     * @param url
     *            请求地址
     * @param headerMap
     *            header参数map Map<string, string="">
     * @param paramMap
     *            额外的参数map,Map<string, string="">
     * @param in
     *            文件流
     * @param fileName
     *            以流传输时,必须指定文件名
     * @param ssl
     *            是否需要ssl
     * @return result,返回上传结果,如果接口没有返回值,则为状态码
     */
    public static String upload(CloseableHttpClient httpClient, String url, Map<string, string=""> headerMap,
            Map<string, string=""> paramMap, InputStream in, String fileName,  boolean ssl) {
        return upload(httpClient, url, headerMap, paramMap,  null , in, fileName, ssl);
    }

    /**
     * 上传附件(post形式)
     * 
     * @param url
     *            请求地址
     * @param headerMap
     *            header参数map Map<string, string="">
     * @param paramMap
     *            额外的参数map,Map<string, string="">
     * @param file
     *            可以选择本地文件上传,file,in互斥;如果传了file,又传了fileName,那么文件名以fileName为准,否则
     *            是file的文件名
     * @param in
     *            文件流
     * @param fileName
     *            以流传输时,必须指定文件名
     * @param ssl
     *            是否需要ssl
     * @return result,返回上传结果,如果接口没有返回值,则为状态码
     */
    private static String upload(String url, Map<string, string=""> headerMap, Map<string, string=""> paramMap, File file,
            InputStream in, String fileName,  boolean ssl) {
        CloseableHttpClient httpClient =  null ;
        if (ssl) {
            httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory())
                    .setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();
        }
        else {
            httpClient = HttpClients.createDefault();
        }
        return upload(httpClient, url, headerMap, paramMap, file, in, fileName, ssl);
    }

    /**
     * 上传附件(post形式)
     * 
     * @param httpClient
     *            外部传入httpClient
     * @param url
     *            请求地址
     * @param headerMap
     *            header参数map Map<string, string="">
     * @param paramMap
     *            额外的参数map,Map<string, string="">
     * @param file
     *            可以选择本地文件上传,file,in互斥;如果传了file,又传了fileName,那么文件名以fileName为准,否则
     *            是file的文件名
     * @param in
     *            文件流
     * @param fileName
     *            以流传输时,必须指定文件名
     * @param ssl
     *            是否需要ssl
     * @return result,返回上传结果,如果接口没有返回值,则为状态码
     */
    private static String upload(CloseableHttpClient httpClient, String url, Map<string, string=""> headerMap,
            Map<string, string=""> paramMap, File file, InputStream in, String fileName,  boolean ssl) {
        String result =  "" ;
        CloseableHttpResponse response =  null ;
        try {
            HttpPost httpPost =  new HttpPost(url);
            // 设置header信息
            if (headerMap !=  null && !headerMap.isEmpty()) {
                for (Map.Entry<string, string=""> entry : headerMap.entrySet()) {
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
            if (ssl) {
                httpPost.setConfig(requestConfig);
            }
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            // 选择以file形式上传
            if (file !=  null && file.exists()) {
                if (StringUtil.isNotBlank(fileName)) {
                    builder.addBinaryBody(DEFAULT_BINARYBODY_KEYNAME, file, ContentType.DEFAULT_BINARY, fileName);
                }
                else {
                    builder.addBinaryBody(DEFAULT_BINARYBODY_KEYNAME, file);
                }
            }
            // 以流上传
            else if (in !=  null && StringUtil.isNotBlank(fileName)) {
                builder.addBinaryBody(DEFAULT_BINARYBODY_KEYNAME, in, ContentType.DEFAULT_BINARY, fileName);
            }
            if (paramMap !=  null && !paramMap.isEmpty()) {
                for (Map.Entry<string, string=""> entry : paramMap.entrySet()) {
                    builder.addPart(entry.getKey(),  new StringBody(entry.getValue(), ContentType.TEXT_PLAIN));
                }
            }
            HttpEntity reqEntity = builder.build();
            httpPost.setEntity(reqEntity);

            response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            if (entity !=  null ) {
                result = EntityUtils.toString(entity,  "UTF-8" );
            }
            else {
                result = response.getStatusLine().getStatusCode() +  "" ;
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            if (response !=  null ) {
                try {
                    EntityUtils.consume(response.getEntity());
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    private static String getCookie(HttpResponse httpResponse) {
        Map<string, string=""> cookieMap =  new HashMap<string, string="">( 64 );
        Header headers[] = httpResponse.getHeaders( "Set-Cookie" );
        if (headers ==  null || headers.length ==  0 ) {
            return null ;
        }
        String cookie =  "" ;
        for ( int i =  0 ; i < headers.length; i++) {
            cookie += headers[i].getValue();
            if (i != headers.length -  1 ) {
                cookie +=  ";" ;
            }
        }
        String cookies[] = cookie.split( ";" );
        for (String c : cookies) {
            c = c.trim();
            if (cookieMap.containsKey(c.split( "=" )[ 0 ])) {
                cookieMap.remove(c.split( "=" )[ 0 ]);
            }
            cookieMap.put(c.split( "=" )[ 0 ],
                    c.split( "=" ).length ==  1 ?  "" : (c.split( "=" ).length ==  2 ? c.split( "=" )[ 1 ] : c.split( "=" ,  2 )[ 1 ]));
        }
        String cookiesTmp =  "" ;
        for (String key : cookieMap.keySet()) {
            cookiesTmp += key +  "=" + cookieMap.get(key) +  ";" ;
        }
        return cookiesTmp.substring( 0 , cookiesTmp.length() -  2 );
    }

    /**
     * 创建SSL安全连接
     *
     * @return
     */
    public static SSLConnectionSocketFactory createSSLConnSocketFactory() {
        SSLConnectionSocketFactory sslsf =  null ;
        try {
            SSLContext sslContext =  new SSLContextBuilder().loadTrustMaterial( null ,  new TrustStrategy()
            {

                public boolean isTrusted(X509Certificate[] chain, String authType)  throws CertificateException {
                    return true ;
                }
            }).build();
            sslsf =  new SSLConnectionSocketFactory(sslContext,  new HostnameVerifier()
            {

                @Override
                public boolean verify(String arg0, SSLSession arg1) {
                    return true ;
                }
            });
        }
        catch (GeneralSecurityException e) {
            e.printStackTrace();
        }
        return sslsf;
    }

    public static PoolingHttpClientConnectionManager getConnMgr() {
        return connMgr;
    }

    public static RequestConfig getRequestConfig() {
        return requestConfig;
    }

    private static boolean isSSL(String apiUrl) {
        if (apiUrl.indexOf( "https" ) != - 1 ) {
            return true ;
        }
        else {
            return false ;
        }
    }

}</string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,></string,>

 

写在最后

  哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

 相关推荐:

posted @ 2020-03-30 15:56  Marydon  阅读(3961)  评论(0编辑  收藏  举报