zoukankan      html  css  js  c++  java
  • HttpClient常用的一些常识

    HttpClient是目前我们通讯组件中最常见的一个Api了吧。至少从我目前接触到与外部系统通讯的话是这样的。下面我将我自己常用的一些知识总结一下。

    因为本猿也是边写边总结,有啥不对的还望多多指出。

    1:利用httpClient发送https请求。

    第一次遇到这种情况是开发与微信支付的接口。适用情形https请求,报文格式:字符串(包含json字符串和xml字符串)。

    public String doPost(String url,String charset,String reqXmlData){
      HttpClient httpClient = null;
      HttpPost httpPost = null;
      String result = null;
      try{
       //这里是关键,SSLClient继承了DefaultHttpClient 忽略https校验过程。SSLClient具体如下。
       httpClient = new SSLClient();
       logger.info("call weixin pay url:"+url);
       httpPost = new HttpPost(url);
       logger.info("call weixin pay requestXmlData:"+reqXmlData);
       //设置最简单的字符串请求参数
       StringEntity strEntity = new StringEntity(reqXmlData, charset);
       httpPost.setEntity(strEntity);
       HttpResponse response = httpClient.execute(httpPost);
       int code = response.getStatusLine().getStatusCode();   
       if(code == 200){
        HttpEntity resEntity = response.getEntity();
        if(resEntity != null){
         result = EntityUtils.toString(resEntity,charset);
        }
       }else{
        //这里就不对其他code处理了
       }
       logger.info("call weixin pay responseXmlData:"+result);
      }catch(Exception ex){
       ex.printStackTrace();
      }finally{
       if (httpClient != null){
        httpClient = null;
       }
      }
      return result;
     }

    /**
     * 用于进行Https请求的HttpClient
     */
    public class SSLClient extends DefaultHttpClient{
     public SSLClient() throws Exception{
            super();
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain,
                            String authType) throws CertificateException {
                    }
                    @Override
                    public void checkServerTrusted(X509Certificate[] chain,
                            String authType) throws CertificateException {
                    }
                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
            };
            ctx.init(null, new TrustManager[]{tm}, null);
            SSLSocketFactory ssf = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            ClientConnectionManager ccm = this.getConnectionManager();
            SchemeRegistry sr = ccm.getSchemeRegistry();
            sr.register(new Scheme("https", 443, ssf));
        }
    }

    好了,今天就先更新到这里了。下班肥家。20151207

    第二点:利用httpclient来模拟表单提交(兼容http请求和https请求)

    相信有很多人遇到过和我一样的情形,与外部系统对接时。经常是测试环境使用的是http请求而生产正式环境则是https请求。这时候我是这样做的。

    public static String httpPost(String reqUrl, BaseDto baseDto){
      DefaultHttpClient httpclient = new DefaultHttpClient();
      String result = "";
       try {
        if(reqUrl.startsWith("https")){
         logger.debug("请求地址为https请求");
         httpclient = new SSLClient();
        }

     //设置超时时间
        httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, TIME_OUT * 1000);
        httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, TIME_OUT * 1000);
        HttpPost httppost = new HttpPost(reqUrl);
        logger.debug("调用地址"+reqUrl);

        //定义一个用来存储表单数据的集合
        List<BasicNameValuePair> formParams = new ArrayList<BasicNameValuePair>();
        formParams.add(new BasicNameValuePair("merchant_id", baseDto.getMerchant_id()));
        formParams.add(new BasicNameValuePair("key_enc", baseDto.getKey_enc()));
        formParams.add(new BasicNameValuePair("sign", baseDto.getSign()));
        formParams.add(new BasicNameValuePair("xml_enc", baseDto.getXml_enc()));

        //UrlEncodedFormEntity与StringEntity相比较的话只能接受键值对的形式,试用与表单提交
        HttpEntity entity = new UrlEncodedFormEntity(formParams, "UTF-8");
        httppost.setEntity(entity);
        HttpResponse response=httpclient.execute(httppost);
        int httpCode = response.getStatusLine().getStatusCode();
        logger.debug("返回的code:"+httpCode);
        switch (httpCode) {
        case 200:
         HttpEntity resEntity=response.getEntity();
         result = EntityUtils.toString(resEntity,"UTF-8");
         logger.debug("通讯原始结果:"+result);
         return result;
        case 401:
         logger.debug("请求要求进行身份验证");
        case 403:
         logger.debug("请求被拒绝,请检查IP地址是否已经加入对方白名单");
        case 404:
         logger.debug("未找到,服务器找不到请求的地址");
        case 405:
         logger.debug("方法不允许,请确认是否为POST请求方式");
        case 500:
         logger.debug("查询请求失败,内部错误");
        default:
         logger.debug("未知的返回码:" + httpCode);
        }
       }  catch (Exception e) {
        e.printStackTrace();
        throw new ServiceException(e,"0006","获取渠道返回信息失败了,可能是超时了");
       }
     }

    好了,今天就先更新到这里了,后面继续来整理利用httpclient来进行爬虫。httpclient的超时设置等等。20151208

  • 相关阅读:
    RocketMQ
    Docker的基本使用
    logstash、ELK
    spring cloud杂文总结
    手写一个starter
    @SpringBootApplication你知多少?
    使用ElasticSearch
    ElasticSearch安装
    啥是ElasticSearch???
    socket、端口、进程的关系
  • 原文地址:https://www.cnblogs.com/hisunhyx/p/5027419.html
Copyright © 2011-2022 走看看