1

问题:

最近项目上面遇到和App对接,测试库他们使用的是 HTTP,但是正式库使用的是 HTTPS。之前没有做过,在网上找过好多文章,最后还是借鉴别人的,自己重新封装之后才在项目上面使用。

使用的jar的版本:

httpclient-4.3.1.jar

源码:

下面给出忽略证书的方式,因为App对接又不能给证书,并且证书是通过CA验证,只好通过此种方式去试试:

1.代码中用到的两个工具方法,以及请求的参数设置

    private static final int SOCKET_TIME_OUT = 60000;    // 设置读取超时
    private static final int CONNECT_TIME_OUT = 60000;    // 设置连接超时 
    

    /**
     * 设置请求的参数值
     * @return
     */
    private static RequestConfig getRequestConfig() {
        return RequestConfig.custom().setSocketTimeout(SOCKET_TIME_OUT).setConnectTimeout(CONNECT_TIME_OUT).build();
    }

    /**
     * 设置参数列表
     * @param param
     * @return
     */
    private static List<NameValuePair> createParam(Map<String, Object> param) {
        List<NameValuePair> nvps = new ArrayList <NameValuePair>();
        if(param != null) {
            for(String k : param.keySet()) {
                nvps.add(new BasicNameValuePair(k, param.get(k).toString()));
            }
        }
        return nvps;
    }

2.HTTPS 处理

2.1创建连接对象:
    /**
     * 创建一个SSL信任所有证书的httpClient对象
     * @return
     */
    public static CloseableHttpClient createSSLInsecureClient() {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                // 默认信任所有证书
                public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                    return true;
                }
            }).build();
            // AllowAllHostnameVerifier: 这种方式不对主机名进行验证,验证功能被关闭,是个空操作(域名验证)
            SSLConnectionSocketFactory sslcsf = new SSLConnectionSocketFactory(sslContext,
                    SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            return HttpClients.custom().setSSLSocketFactory(sslcsf).build();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
    
        //如果创建失败,就创建一个默认的Http的连接
        return HttpClients.createDefault();
    }
 2.2调用方法:
     /**
     * 无需本地证书keyStore的SSL https带参数请求
     * post K - V 格式的数据
     * @param url
     * @param paramsMap
     * @param encoding
     * @return
     */
    public static String postSSLParams(String url, Map<String, Object> params, Map<String, Object> headers) {
        //创建一个信任的连接
        CloseableHttpClient httpClient = createSSLInsecureClient();
        //发送请求的实体类
        HttpPost httpPost = new HttpPost(url);
        //接收返回值
        StringBuilder sb = new StringBuilder();
        BufferedReader br = null;
        try {
            // 设置客户端请求的头参数getParams已经过时,现在用requestConfig对象替换
            httpPost.setConfig(getRequestConfig());
            
            //设置请求的头信息
            Set<String> keys = headers.keySet();
            for (String key : keys) {
                httpPost.setHeader(key, headers.get(key).toString());
            }
            
            //这个是设置请求的类型,这个可能需要重点注意下,需要看对方接收的是什么
            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
            
            //添加参数, 设置编码格式
            httpPost.setEntity(new UrlEncodedFormEntity( createParam(params) , Charset.forName("utf-8")));
                        
            //发送请求
            HttpResponse response = httpClient.execute(httpPost);
            
            //接收返回值
            HttpEntity httpEntity = response.getEntity();

            //返回值处理
            br = new BufferedReader(new InputStreamReader(httpEntity.getContent(),"utf-8"));
            String s = null;
            while((s=br.readLine())!=null){
                sb.append(s);
            }
            
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("指定的编码集不对,您目前指定的编码集是:" + "utf-8");
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            throw new RuntimeException("读取流文件异常",e);
        }catch (Exception e) {
            throw new RuntimeException("通讯未知系统异常",e);
        }finally{
            if(br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }

3.调用HTTP的方法

3.1 发送 HTTP,K-V形式
    /**
     * 发送 POST 请求(HTTP),K-V形式
     * @param url
     * @param param
     * @return
     * @throws Exception
     */
    public static String defaultPost(String url, Map<String, Object> param) throws Exception{
        String returnString = "";
        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        
        //设置字符集的两种方式
        //new UrlEncodedFormEntity( createParam(params), Charset.forName("UTF-8"))
        HttpEntity entity = new UrlEncodedFormEntity(createParam(param), Consts.UTF_8);
        try {
            HttpPost httpPost = new HttpPost(url);
            
            httpPost.setConfig(getRequestConfig());
            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
            httpPost.setEntity(entity);
            
            response = client.execute(httpPost);
            returnString = EntityUtils.toString(response.getEntity(), "UTF-8");
            
            EntityUtils.consume(response.getEntity());    //关闭请求
            return returnString;
        } catch(Exception e) {
            e.printStackTrace();
        } 
        
        return returnString;
    }
3.2 发送 HTTP,JSON形式
    /**
     * 发送 POST 请求(HTTP),JSON形式
     * @param url 调用的地址
     * @param jsonParams 调用的参数
     * @return
     * @throws Exception
     */
    public static String postJson(String url, String jsonParams) throws Exception {
        //创建一个默认的连接对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        HttpPost httpPost = new HttpPost(url);

        String httpStr;
        try {
            StringEntity entity = new StringEntity(jsonParams);
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");

            httpPost.setEntity(entity);
            response = httpClient.execute(httpPost);
            httpStr = EntityUtils.toString(response.getEntity(), "UTF-8");

        } finally {
            if (response != null) {
                EntityUtils.consume(response.getEntity());
            }
        }
        return httpStr;
    }

另外几点说明下:

1.由于我觉得get请求的方式实在是不安全,就没有去研究get。
2.以上是我在项目上面使用的,没有添加全部的代码,但是对应的方法都是可以使用的。

Wayfreem
241 声望33 粉丝

一个后端工程师,偏偏喜欢前端。