1、http协议(这一块儿有时间的话会做记录)

2、常用的两种RPC方式

  • 基于http协议:HttpClient和JDK自己的Http操作类
  • 基于TCP或UDP协议:mina2和netty(这一部分以后有时间做记录)

3、HttpClient工具类的编写(只列出了两个最常用的方法get和post)

使用场合:我们可以在网页发送get或post请求去访问服务器server1,那我们在Java程序中想要模拟网页向服务器server1发送get和post请求的时候怎么办?--用HttpClient

版本:httpClient4.2.6(jar或者maven坐标自己加上)

maven坐标:

 <dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.6</version>
</dependency>

代码实现(两个类):

MyX509TrustManager(自定义的信任管理器)

 package com.util;

 import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; /**
* 自定义的信任管理器
*/
public class MyX509TrustManager implements X509TrustManager {
/**
* 检查客户端证书,若不信任,抛出异常
*/
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
/**
* 检查服务端证书,若不信任,抛出异常,反之,若不抛出异常,则表示信任(所以,空方法代表信任所有的服务端证书)
*/
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
/**
* 返回受信任的X509证书数组
*/
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}

HttpClientUtil:

 package com.util;

 import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager; import org.apache.commons.collections4.MapUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils; /**
* 对HTTPClient的封装
*/
public class HttpClientUtil { private static final String ENCODING = "UTF-8"; private static HttpClient client = null;
private static SchemeRegistry schemeRegistry; //协议控制
private static PoolingClientConnectionManager ccm; //HttpClient连接池(多连接的线程安全的管理器) static {
try {
/*
* 与https请求相关的操作
*/
SSLContext sslContext = SSLContext.getInstance("SSL","SunJSSE");
sslContext.init(null, new TrustManager[]{new MyX509TrustManager()}, new SecureRandom());
SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext);
/*
* 定义访问协议
*/
schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));//http
schemeRegistry.register(new Scheme("https", 443, socketFactory));//https
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} Properties props = FileUtil.loadProps("http.properties");//加载属性文件 // 连接池管理
ccm = new PoolingClientConnectionManager(schemeRegistry);
ccm.setDefaultMaxPerRoute(FileUtil.getInt(props, "httpclient.max.conn.per.route", 20));//每个路由的最大连接数
ccm.setMaxTotal(FileUtil.getInt(props, "httpclient.max.conn.total", 400));//最大总连接数 HttpParams httpParams = new BasicHttpParams();
httpParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, FileUtil.getInt(props, "httpclient.max.conn.timeout", 1000));//连接超时时间(ms)
httpParams.setParameter(CoreConnectionPNames.SO_TIMEOUT, FileUtil.getInt(props, "httpclient.max.socket.timeout", 2000));//操作超时时间(ms)
httpParams.setParameter(CoreProtocolPNames.PROTOCOL_VERSION,HttpVersion.HTTP_1_1);//设置http1.1或http1.0 client = new DefaultHttpClient(ccm, httpParams);//一个客户端就有一个连接池
} /**
* get请求
* @param url 请求URL
* @param paramMap 请求参数
* @param headerMap 请求头信息
*/
public static String get(String url,
Map<String, String> paramMap,
Map<String, String> headerMap) throws ClientProtocolException,
IOException {
/*
* 拼接URL与参数
*/
if (MapUtils.isNotEmpty(paramMap)) {
List<NameValuePair> params = new ArrayList<NameValuePair>();
for (String key : paramMap.keySet()) {
params.add(new BasicNameValuePair(key, paramMap.get(key)));
}
String queryString = URLEncodedUtils.format(params,ENCODING);
if (url.indexOf("?") > -1) {//存在?,表示这时的URL已经带参数了
url += "&" + queryString;
} else {
url += "?" + queryString;
}
} HttpGet httpGet = new HttpGet(url); /*
* 设置头信息
*/
if (MapUtils.isNotEmpty(headerMap)) {
Set<String> keySet = headerMap.keySet();
for (String key : keySet) {
httpGet.addHeader(key, headerMap.get(key));
}
} String result = ""; HttpResponse response = client.execute(httpGet); //发出get请求
StatusLine status = response.getStatusLine(); //获取返回的状态码
HttpEntity entity = response.getEntity(); //获取返回的响应内容
if (status.getStatusCode() == HttpStatus.SC_OK) { //
result = EntityUtils.toString(entity, ENCODING);
} httpGet.abort();//中止请求,连接被释放回连接池
return result;
} /**
* post请求
* @param url //请求URL
* @param paramMap //请求参数
* @param headerMap //请求头信息
*/
public static String post(String url,
Map<String, String> paramMap,
Map<String, String> headerMap) throws ClientProtocolException,
IOException {
HttpPost httpPost = new HttpPost(url);
/*
* 处理参数
*/
List<NameValuePair> params = new ArrayList<NameValuePair>();
if (MapUtils.isNotEmpty(paramMap)) {
Set<String> keySet = paramMap.keySet();
for (String key : keySet) {
params.add(new BasicNameValuePair(key, paramMap.get(key)));
}
} /*
* 设置头信息
*/
if (MapUtils.isNotEmpty(headerMap)) {
Set<String> keySet = headerMap.keySet();
for (String key : keySet) {
httpPost.addHeader(key, headerMap.get(key));
}
} String result = ""; httpPost.setEntity(new UrlEncodedFormEntity(params, ENCODING));//设置参数
HttpResponse response = client.execute(httpPost); //发出post请求
StatusLine status = response.getStatusLine(); //获取返回的状态码
HttpEntity entity = response.getEntity(); //获取响应内容
if (status.getStatusCode() == HttpStatus.SC_OK) {
result = EntityUtils.toString(entity, ENCODING);
} httpPost.abort();//中止请求,连接被释放回连接池
return result;
} /**
* 测试
*/
public static void main(String[] args) {
try {
System.out.println(HttpClientUtil.get("https://www.baidu.com/", null, null));
//System.out.println(HttpClientUtil.post("http://www.cppblog.com/iuranus/archive/2010/07/04/119311.html", null, null));
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

在该代码中,还有两个部分:一个属性文件http.properties和一个文件操作类FileUtil。这两部分,请查看下边的这个链接:

http://www.cnblogs.com/java-zhao/p/5098813.html

注意:

  • 我们发起的请求可以使http的,也可以是https(相当于http+SSL/TLS+数字证书的组合,是一种安全协议)的,对于https相关的请求而言,我们需要编写一些代码,来做特殊的处理。一般而言,处理https请求有两种方法:

1)将https服务器端的安全证书导入到客户端的TrustStore文件中去,具体的原理见"《微信公众平台应用开发(方法、技巧与案例)》第5章"或者去查看柳峰的博客

    2)实现自定义的信任管理器(eg.MyX509TrustManager),需要实现X509TrustManager接口,并实现其中的三个方法。注意:这个类的注释一定要看

    3)注意http大多数时候用的是8080端口而不是80

第一种方法需要手工导入证书,很费事;第二种方法十分灵活

  • 对于HttpClientUtil中,每一块做什么查看注释,这里:解释httpclient.max.conn.per.route(每个路由的最大连接数):这里路由的概念可以理解为"运行环境机器到目标机器"的一条线路。举例来说,我们使用HttpClient的实现来分别请求 www.baidu.com 的资源和 www.bing.com 的资源那么他就会产生两个route(路由),根据如上设置为20,就可以为上边两条route分别设置最大20个并发连接数。
  • 假如只有HttpClientUtil使用MyX509TrustManager,我们也可以将MyX509TrustManager作为HttpClientUtil的一个内部类,代码如下:
  •  package com.util;
    
     import java.io.IOException;
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.NoSuchProviderException;
    import java.security.SecureRandom;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    import java.util.Set; import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager; import org.apache.commons.collections4.MapUtils;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.HttpStatus;
    import org.apache.http.HttpVersion;
    import org.apache.http.NameValuePair;
    import org.apache.http.StatusLine;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.entity.UrlEncodedFormEntity;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.client.utils.URLEncodedUtils;
    import org.apache.http.conn.scheme.PlainSocketFactory;
    import org.apache.http.conn.scheme.Scheme;
    import org.apache.http.conn.scheme.SchemeRegistry;
    import org.apache.http.conn.ssl.SSLSocketFactory;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.impl.conn.PoolingClientConnectionManager;
    import org.apache.http.message.BasicNameValuePair;
    import org.apache.http.params.BasicHttpParams;
    import org.apache.http.params.CoreConnectionPNames;
    import org.apache.http.params.CoreProtocolPNames;
    import org.apache.http.params.HttpParams;
    import org.apache.http.util.EntityUtils; /**
    * 对HTTPClient的封装
    */
    public class HttpClientUtilWithMyX509TrustMananer { private static final String ENCODING = "UTF-8"; private static HttpClient client = null;
    private static SchemeRegistry schemeRegistry; // 协议控制
    private static PoolingClientConnectionManager ccm; // HttpClient连接池(多连接的线程安全的管理器) static {
    try {
    /*
    * 与https请求相关的操作
    */
    SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
    sslContext.init(null,
    new TrustManager[] { getMyX509TrustManager() },
    new SecureRandom());
    SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext);
    /*
    * 定义访问协议
    */
    schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));// http
    schemeRegistry.register(new Scheme("https", 443, socketFactory));// https
    } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
    } catch (NoSuchProviderException e) {
    e.printStackTrace();
    } catch (KeyManagementException e) {
    e.printStackTrace();
    } Properties props = FileUtil.loadProps("http.properties");// 加载属性文件 // 连接池管理
    ccm = new PoolingClientConnectionManager(schemeRegistry);
    ccm.setDefaultMaxPerRoute(FileUtil.getInt(props,"httpclient.max.conn.per.route", 20));// 每个路由的最大连接数
    ccm.setMaxTotal(FileUtil.getInt(props, "httpclient.max.conn.total", 400));// 最大总连接数 HttpParams httpParams = new BasicHttpParams();
    httpParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,FileUtil.getInt(props, "httpclient.max.conn.timeout", 1000));// 连接超时时间(ms)
    httpParams.setParameter(CoreConnectionPNames.SO_TIMEOUT,FileUtil.getInt(props, "httpclient.max.socket.timeout", 2000));// 操作超时时间(ms)
    httpParams.setParameter(CoreProtocolPNames.PROTOCOL_VERSION,HttpVersion.HTTP_1_1);// 设置http1.1或http1.0 client = new DefaultHttpClient(ccm, httpParams);// 一个客户端就有一个连接池
    } /**
    * get请求
    * @param url 请求URL
    * @param paramMap 请求参数
    * @param headerMap 请求头信息
    */
    public static String get(String url,
    Map<String, String> paramMap,
    Map<String, String> headerMap) throws ClientProtocolException,
    IOException {
    /*
    * 拼接URL与参数
    */
    if (MapUtils.isNotEmpty(paramMap)) {
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    for (String key : paramMap.keySet()) {
    params.add(new BasicNameValuePair(key, paramMap.get(key)));
    }
    String queryString = URLEncodedUtils.format(params, ENCODING);
    if (url.indexOf("?") > -1) {// 存在?,表示这时的URL已经带参数了
    url += "&" + queryString;
    } else {
    url += "?" + queryString;
    }
    } HttpGet httpGet = new HttpGet(url); /*
    * 设置头信息
    */
    if (MapUtils.isNotEmpty(headerMap)) {
    Set<String> keySet = headerMap.keySet();
    for (String key : keySet) {
    httpGet.addHeader(key, headerMap.get(key));
    }
    } String result = ""; HttpResponse response = client.execute(httpGet); // 发出get请求
    StatusLine status = response.getStatusLine(); // 获取返回的状态码
    HttpEntity entity = response.getEntity(); // 获取返回的响应内容
    if (status.getStatusCode() == HttpStatus.SC_OK) { //
    result = EntityUtils.toString(entity, ENCODING);
    } httpGet.abort();// 中止请求,连接被释放回连接池
    return result;
    } /**
    * post请求
    * @param url 请求URL
    * @param paramMap 请求参数
    * @param headerMap 请求头信息
    */
    public static String post(String url,
    Map<String, String> paramMap,
    Map<String, String> headerMap) throws ClientProtocolException,
    IOException {
    HttpPost httpPost = new HttpPost(url);
    /*
    * 处理参数
    */
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    if (MapUtils.isNotEmpty(paramMap)) {
    Set<String> keySet = paramMap.keySet();
    for (String key : keySet) {
    params.add(new BasicNameValuePair(key, paramMap.get(key)));
    }
    } /*
    * 设置头信息
    */
    if (MapUtils.isNotEmpty(headerMap)) {
    Set<String> keySet = headerMap.keySet();
    for (String key : keySet) {
    httpPost.addHeader(key, headerMap.get(key));
    }
    } String result = ""; httpPost.setEntity(new UrlEncodedFormEntity(params, ENCODING));// 设置参数
    HttpResponse response = client.execute(httpPost); // 发出post请求
    StatusLine status = response.getStatusLine(); // 获取返回的状态码
    HttpEntity entity = response.getEntity(); // 获取响应内容
    if (status.getStatusCode() == HttpStatus.SC_OK) {
    result = EntityUtils.toString(entity, ENCODING);
    } httpPost.abort();// 中止请求,连接被释放回连接池
    return result;
    } /**
    * 构建自定义信任管理器内部类
    */
    private static class MyX509TrustManager implements X509TrustManager {
    /**
    * 检查客户端证书,若不信任,抛出异常
    */
    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
    throws CertificateException {
    }
    /**
    * 检查服务端证书,若不信任,抛出异常,反之,若不抛出异常,则表示信任(所以,空方法代表信任所有的服务端证书)
    */
    public void checkServerTrusted(X509Certificate[] arg0, String arg1)
    throws CertificateException {
    }
    /**
    * 返回受信任的X509证书数组
    */
    public X509Certificate[] getAcceptedIssuers() {
    return null;
    }
    } /**
    * 为外部类获取内部类提供方法
    */
    public static MyX509TrustManager getMyX509TrustManager() {
    return new MyX509TrustManager();
    } /**
    * 测试
    */
    public static void main(String[] args) {
    try {
    System.out.println(HttpClientUtilWithMyX509TrustMananer.get("https://www.baidu.com/", null, null));
    // System.out.println(HttpClientUtil.post("http://www.cppblog.com/iuranus/archive/2010/07/04/119311.html", null, null));
    } catch (ClientProtocolException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }

    注:在这里我定义了一个成员内部类,并提供了一个获取成员内部类的方法getMyX509TrustManager(),用于外部类来获取该内部类的实例。当然,如果对于内部类不熟的话,可以不使用内部类,直接使用上边的方式也好。

  

第一章 HttpClient的使用的更多相关文章

  1. 《进击吧!Blazor!》系列入门教程 第一章 8.部署

    <进击吧!Blazor!>是本人与张善友老师合作的Blazor零基础入门教程视频,此教程能让一个从未接触过Blazor的程序员掌握开发Blazor应用的能力. 视频地址:https://s ...

  2. 《Django By Example》第一章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:本人目前在杭州某家互联网公司工作, ...

  3. MyBatis3.2从入门到精通第一章

    第一章一.引言mybatis是一个持久层框架,是apache下的顶级项目.mybatis托管到goolecode下,再后来托管到github下.(百度百科有解释)二.概述mybatis让程序将主要精力 ...

  4. Nova PhoneGap框架 第一章 前言

    Nova PhoneGap Framework诞生于2012年11月,从第一个版本的发布到现在,这个框架经历了多个项目的考验.一直以来我们也持续更新这个框架,使其不断完善.到现在,这个框架已比较稳定了 ...

  5. 第一章 MYSQL的架构和历史

    在读第一章的过程中,整理出来了一些重要的概念. 锁粒度  表锁(服务器实现,忽略存储引擎). 行锁(存储引擎实现,服务器没有实现). 事务的ACID概念 原子性(要么全部成功,要么全部回滚). 一致性 ...

  6. 第一章 Java多线程技能

    1.初步了解"进程"."线程"."多线程" 说到多线程,大多都会联系到"进程"和"线程".那么这两者 ...

  7. 【读书笔记】《编程珠玑》第一章之位向量&位图

    此书的叙述模式是借由一个具体问题来引出的一系列算法,数据结构等等方面的技巧性策略.共分三篇,基础,性能,应用.每篇涵盖数章,章内案例都非常切实棘手,解说也生动有趣. 自个呢也是头一次接触编程技巧类的书 ...

  8. 《JavaScript高级程序设计(第3版)》阅读总结记录第一章之JavaScript简介

    前言: 为什么会想到把<JavaScript 高级程序设计(第 3 版)>总结记录呢,之前写过一篇博客,研究的轮播效果,后来又去看了<JavaScript 高级程序设计(第3版)&g ...

  9. 《Entity Framework 6 Recipes》翻译系列 (1) -----第一章 开始使用实体框架之历史和框架简述

    微软的Entity Framework 受到越来越多人的关注和使用,Entity Framework7.0版本也即将发行.虽然已经开源,可遗憾的是,国内没有关于它的书籍,更不用说好书了,可能是因为EF ...

随机推荐

  1. Scala入门4(_的用法)

    从网上找了一篇博客,详细讲解了Scala下划线的用法,这里做保留 博客链接

  2. 大数据技术之_16_Scala学习_04_函数式编程-基础+面向对象编程-基础

    第五章 函数式编程-基础5.1 函数式编程内容说明5.1.1 函数式编程内容5.1.2 函数式编程授课顺序5.2 函数式编程介绍5.2.1 几个概念的说明5.2.2 方法.函数.函数式编程和面向对象编 ...

  3. OSI、TCP、IP、UDP 这些都是啥??

    一个大大的问号首先抛出,计算机之间是如何进行通信的? 计算机网络是通过传输介质.通信设施和网络通信协议,把分散在不同地点的计算机设备互连起来,实现资源共享和数据传输的系统. 网络协议就是数据按照一定的 ...

  4. 手动制作用于启动BeagleBoneBlack(am335x)的SD

    1.需求MLO.u-boot.img.uImage.Systemfile 获取MLO.u-boot.img下载U-boot源码,解压获得源码,进入源码目录 cd /home/zyr/Source_co ...

  5. 第4天:Django的cookie和session

    Cookie Session Cookie 浏览器请求服务器是无状态的,它的每一次请求对于服务器来说都是新的,服务器默认不会保存用户的状态数据.但很多时候,服务器需要保存用户的一些状态数据,比如用户是 ...

  6. Linux驱动之PCI

    <背景> PCI设备有许多地址配置的寄存器,初始化时这寄存器来配置设备的总线地址,配置好后CPU就可以访问该设备的各项资源了.(提炼:配置总线地址)   <配置寄存器>   ( ...

  7. SPOJ8791 DYNALCA LCT

    考虑\(LCT\) 不难发现,我们不需要换根... 对于操作\(1\),\(splay(u)\)然后连虚边即可 对于操作\(3\),我们可以先\(access(u)\),然后再\(access(v)\ ...

  8. 解决CIFilter滤镜后图片大小和方向发生变化

    调用contextWithOptions:和createCGImage: fromRect:方法创建CIContext.与以往不同的地方是CIImage没有frame与bounds属性:只有exten ...

  9. 记一次帮朋友解决apache站点403错误的过程

    apache版本: [root@iZ25eby2utyZ web]# rpm -qa | grep httpd httpd-tools--.el6.centos..x86_64 httpd--.el6 ...

  10. Set常用子类特点

    HashSet:       重写   hashCode和equals方法                                        特点:无序,唯一      底层结构是:    ...