HTTP和HTTPS详解

<div class="post">
        <h1 class="postTitle">
            <a id="cb_post_title_url" class="postTitle2" href="https://www.cnblogs.com/ok-lanyan/archive/2012/07/14/2591204.html">HTTP HTTPS WebService</a>
        </h1>
        <div class="clear"></div>
        <div class="postBody">
            <div id="cnblogs_post_body" class="blogpost-body"><p><span>  HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出。</span><br><span>HTTP协议的主要特点可概括如下:</span><br><span><span style="color: #0000ff;"><strong>1.支持客户/服务器模式</strong></span>。</span><br><span><span style="color: #0000ff;"><strong>2.简单快速</strong></span>:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。</span><br><span><span style="color: #0000ff;"><strong>3.灵活</strong></span>:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。</span><br><span><span style="color: #0000ff;"><strong>4.无连接</strong></span>:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。</span><br><span><span style="color: #0000ff;"><strong>5.无状态</strong></span>:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。</span></p>
<p><span style="font-size: 18pt;"><strong>一、HTTP</strong></span></p>
<p><span style="font-size: 16px;"><strong>1.1 HTTP协议详解之URL篇</strong></span></p>
<p><span>  http(超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式,HTTP1.1版本中给出一种持续连接的机制,绝大多数的Web开发,都是构建在HTTP协议之上的Web应用。</span></p>
<p><span>HTTP URL (URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息)的格式如下:</span></p>
<p><span>http://host[":"port][abs_path</span><span>]<br>  http表示要通过HTTP协议来定位网络资源;host表示合法的Internet主机域名或者IP地址;port指定一个端口号,为空则使用缺省端口80;abs_path指定请求资源的URI;如果URL中没有给出abs_path,那么当它作为请求URI时,必须以“/”的形式给出,通常这个工作浏览器自动帮我们完成。<br>eg:<br>1、输入:</span><span><a href="http://www.guet.edu.cn/">www.guet.edu.cn</a>&nbsp;&nbsp;</span><span>浏览器自动转换成:</span><a href="http://www.guet.edu.cn/"><span>http://www.guet.edu.cn/</span></a><br><span>2、http:192.168.0.116:8080/index.jsp&nbsp;</span></p>
<p><span style="font-size: 16px;"><strong>1.2 HTTP协议详解之请求篇</strong></span></p>
<p><span>  http请求由三部分组成,分别是:<span style="color: #0000ff;"><strong>请求行、消息报头、请求正文</strong></span></span></p>
<p><span>1、请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下:</span></p>
<p><span>Method Request-URI HTTP-Version CRLF&nbsp;&nbsp;<br>其中 Method表示请求方法;Request-URI是一个统一资源标识符;HTTP-Version表示请求的HTTP协议版本;CRLF表示回车和换行(除了作为结尾的CRLF外,不允许出现单独的CR或LF字符)。</span></p>
<p><span>请求方法(所有方法全为大写)有多种,各个方法的解释如下:<br>GET    请求获取Request-URI所标识的<span style="color: #ff6600;"><strong>资源</strong></span><br>POST   &nbsp;在Request-URI所标识的资源后<strong><span style="color: #ff6600;">附加新的数据</span></strong><br>HEAD   &nbsp;请求获取由Request-URI所标识的资源的<strong><span style="color: #ff6600;">响应消息报头</span></strong><br>PUT    &nbsp;请求服务器<span style="color: #ff6600;"><strong>存储一个资源</strong></span>,并用Request-URI作为其标识<br>DELETE  &nbsp;请求服务器<span style="color: #ff6600;"><strong>删除Request-URI所标识的资源</strong></span><br>TRACE   &nbsp;请求服务器回送收到的<span style="color: #ff6600;"><strong>请求信息</strong></span>,主要用于测试或诊断<br>CONNECT &nbsp;保留将来使用<br>OPTIONS  &nbsp;请求查询服务器的性能,或者查询与资源相关的选项和需求<br>应用举例:<br>GET方法:在浏览器的地址栏中输入网址的方式访问网页时,浏览器采用GET方法向服务器获取资源,eg:GET /form.html HTTP/1.1 (CRLF)</span></p>
<p><span>POST方法要求被请求服务器接受附在请求后面的数据,常用于提交表单。<br>eg:POST /reg.jsp HTTP/ (CRLF)<br>Accept:image/gif,image/x-xbit,... (CRLF)<br>...<br>HOST:www.guet.edu.cn (CRLF)<br>Content-Length:22 (CRLF)<br>Connection:Keep-Alive (CRLF)<br>Cache-Control:no-cache (CRLF)<br>(CRLF)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //该CRLF表示消息报头已经结束,在此之前为消息报头<br>user=jeffrey&amp;pwd=1234&nbsp; //此行以下为提交的数据</span></p>
<p><span>HEAD方法与GET方法几乎是一样的,对于HEAD请求的回应部分来说,它的HTTP头部中包含的信息与通过GET请求所得到的信息是相同的。利用这个方法,不必传输整个资源内容,就可以得到Request-URI所标识的资源的信息。该方法常用于测试超链接的有效性,是否可以访问,以及最近是否更新。<br>2、请求报头后述<br>3、请求正文(略)&nbsp;</span></p>
<p><span style="font-size: 16px;"><strong>1.3&nbsp;HTTP协议详解之响应篇</strong></span></p>
<p><span>  在接收和解释请求消息后,服务器返回一个HTTP响应消息。</span></p>
<p><span>HTTP响应也是由三个部分组成,分别是:<span style="color: #0000ff;"><strong>状态行、消息报头、响应正文</strong></span><br>1、状态行格式如下:<br>HTTP-Version Status-Code Reason-Phrase CRLF<br>其中,HTTP-Version表示服务器HTTP协议的版本;Status-Code表示服务器发回的响应状态代码;Reason-Phrase表示状态代码的文本描述。<br>状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:<br>1xx:指示信息--表示请求已接收,继续处理<br>2xx:成功--表示请求已被成功接收、理解、接受<br>3xx:重定向--要完成请求必须进行更进一步的操作<br>4xx:客户端错误--请求有语法错误或请求无法实现<br>5xx:服务器端错误--服务器未能实现合法的请求<br>常见状态代码、状态描述、说明:<br>200 OK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //客户端请求成功<br>400 Bad Request&nbsp; //客户端请求有语法错误,不能被服务器所理解<br>401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用&nbsp;<br>403 Forbidden&nbsp; //服务器收到请求,但是拒绝提供服务<br>404 Not Found&nbsp; //请求资源不存在,eg:输入了错误的URL<br>500 Internal Server Error //服务器发生不可预期的错误<br>503 Server Unavailable&nbsp; //服务器当前不能处理客户端的请求,一段时间后可能恢复正常<br>eg:HTTP/1.1 200 OK (CRLF)</span></p>
<p><span>2、响应报头后述</span></p>
<p><span>3、响应正文就是服务器返回的资源的内容&nbsp;</span></p>
<p><span style="font-size: 16px;"><strong>1.4 HTTP协议详解之消息报头篇</strong></span></p>
<p><span>  HTTP消息由客户端到服务器的请求和服务器到客户端的响应组成。请求消息和响应消息都是由开始行(对于请求消息,开始行就是请求行,对于响应消息,开始行就是状态行),消息报头(可选),空行(只有CRLF的行),消息正文(可选)组成。</span></p>
<p><span>HTTP消息报头包括普通报头、<span style="color: #0000ff;"><strong>请求报头、响应报头、实体报头</strong></span>。<br>每一个报头域都是由<span style="color: #ff0000;"><strong>名字+“:”+空格+值</strong></span> 组成,消息报头域的名字是大小写无关的。</span></p>
<p><span><span style="font-size: 15px;"><strong>1、普通报头</strong></span><br>  在普通报头中,有少数报头域用于所有的请求和响应消息,但并不用于被传输的实体,<span style="color: #ff0000;"><strong>只用于传输的消息</strong></span>。<br>eg:<br>Cache-Control&nbsp;&nbsp; 用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制),HTTP1.0使用的类似的报头域为Pragma。<br>请求时的缓存指令包括:no-cache(用于指示请求或响应消息不能缓存)、no-store、max-age、max-stale、min-fresh、only-if-cached;<br>响应时的缓存指令包括:public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age、s-maxage.<br>eg:为了指示IE浏览器(客户端)不要缓存页面,服务器端的JSP程序可以编写如下:response.sehHeader("Cache-Control","no-cache");<br>//response.setHeader("Pragma","no-cache");作用相当于上述代码,通常两者//合用<br>这句代码将在发送的响应消息中设置普通报头域:Cache-Control:no-cache</span></p>
<p><span>Date普通报头域表示消息产生的日期和时间</span></p>
<p><span>Connection普通报头域允许发送指定连接的选项。例如指定连接是连续,或者指定“close”选项,通知服务器,在响应完成后,关闭连接</span></p>
<p><span><strong><span style="font-size: 15px;">2、请求报头</span></strong><br>  请求报头允许客户端向服务器端传递请求的<span style="color: #ff0000;"><strong>附加信息以及客户端自身的信息</strong></span>。<br>常用的请求报头<br><span style="color: #ff0000;"><strong>Accept</strong></span>请求报头域用于指定客户端接受哪些类型的信息。eg:Accept:image/gif,表明客户端希望接受GIF图象格式的资源;Accept:text/html,表明客户端希望接受html文本。<br><span style="color: #ff0000;"><strong>Accept-Charset</strong></span>请求报头域用于指定客户端接受的字符集。eg:Accept-Charset:iso-8859-1,gb2312.如果在请求消息中没有设置这个域,缺省是任何字符集都可以接受。、<br><span style="color: #ff0000;"><strong>Accept-Encoding</strong></span>请求报头域类似于Accept,但是它是用于指定可接受的内容编码。eg:Accept-Encoding:gzip.deflate.如果请求消息中没有设置这个域服务器假定客户端对各种内容编码都可以接受。<br><span style="color: #ff0000;"><strong>Accept-Language</strong></span>请求报头域类似于Accept,但是它是用于指定一种自然语言。eg:Accept-Language:zh-cn.如果请求消息中没有设置这个报头域,服务器假定客户端对各种语言都可以接受。<br><span style="color: #ff0000;"><strong>Authorization</strong></span>请求报头域主要用于证明客户端有权查看某个资源。当浏览器访问一个页面时,如果收到服务器的响应代码为401(未授权),可以发送一个包含Authorization请求报头域的请求,要求服务器对其进行验证。<br><span style="color: #ff0000;"><strong>Host</strong></span>请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的,</span>发送请求时,该报头域是必需的,eg:我们在浏览器中输入:<a href="http://www.guet.edu.cn/index.html">http://www.guet.edu.cn/index.html</a></p>
<p><span>浏览器发送的请求消息中,就会包含Host请求报头域,如下:Host:</span><a href="http://www.guet.edu.cn/"><span>www.guet.edu.cn</span></a><br><span>此处使用缺省端口号80,若指定了端口号,则变成:Host:</span><a href="http://www.guet.edu.cn/"><span>www.guet.edu.cn</span></a><span>:指定端口号<br><span style="color: #ff0000;"><strong>User-Agent</strong></span>我们上网登陆论坛的时候,往往会看到一些欢迎信息,其中列出了你的操作系统的名称和版本,你所使用的浏览器的名称和版本,这往往让很多人感到很神奇,实际上,服务器应用程序就是从User-Agent这个请求报头域中获取到这些信息。User-Agent请求报头域允许客户端将它的操作系统、浏览器和其它属性告诉服务器。不过,这个报头域不是必需的,如果我们自己编写一个浏览器,不使用User-Agent请求报头域,那么服务器端就无法得知我们的信息了。<br><span style="font-size: 15px;"><strong>请求报头举例:</strong></span><br>GET /form.html HTTP/1.1 (CRLF)<br>Accept:image/gif,image/x-xbitmap,image/jpeg,application/x-shockwave-flash,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,*/* (CRLF)<br>Accept-Language:zh-cn (CRLF)<br>Accept-Encoding:gzip,deflate (CRLF)<br>If-Modified-Since:Wed,05 Jan 2007 11:21:25 GMT (CRLF)<br>If-None-Match:W/"80b1a4c018f3c41:8317" (CRLF)<br>User-Agent:Mozilla/4.0(compatible;MSIE6.0;Windows NT 5.0) (CRLF)<br>Host:www.guet.edu.cn (CRLF)<br>Connection:Keep-Alive (CRLF)<br>(CRLF)</span></p>
<p><span><span style="font-size: 15px;"><strong>3、响应报头</strong></span><br>  响应报头允许服务器传递不能放在状态行中的<span style="color: #ff0000;"><strong>附加响应信息</strong></span>,以及关于服务器的信息和对Request-URI所标识的资源进行<strong><span style="color: #ff0000;">下一步访问的信息</span></strong>。<br>常用的响应报头<br><span style="color: #ff0000;"><strong>Location</strong></span>响应报头域用于重定向接受者到一个新的位置。Location响应报头域常用在更换域名的时候。<br><span style="color: #ff0000;"><strong>Server</strong></span>响应报头域包含了服务器用来处理请求的软件信息。与User-Agent请求报头域是相对应的。下面是Server响应报头域的一个例子:Server:Apache-Coyote/1.1<br><span style="color: #ff0000;"><strong>WWW-Authenticate</strong></span>响应报头域必须被包含在401(未授权的)响应消息中,客户端收到401响应消息时候,并发送Authorization报头域请求服务器对其进行验证时,服务端响应报头就包含该报头域。<br>eg:WWW-Authenticate:Basic realm="Basic Auth Test!"&nbsp; //可以看出服务器对请求资源采用的是基本验证机制。</span></p>
<p><span><span style="font-size: 15px;"><strong>4、实体报头</strong></span><br>  请求和响应消息都可以<span style="color: #ff0000;"><strong>传送一个实体</strong></span>。一个实体由实体报头域和实体正文组成,但并不是说实体报头域和实体正文要在一起发送,可以只发送实体报头域。实体报头定义了关于实体正文(eg:有无实体正文)和请求所标识的资源的元信息。<br>常用的实体报头<br><span style="color: #ff0000;"><strong>Content-Encoding</strong></span>实体报头域被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码,因而要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。Content-Encoding这样用于记录文档的压缩方法,eg:Content-Encoding:gzip<br><span style="color: #ff0000;"><strong>Content-Language</strong></span>实体报头域描述了资源所用的自然语言。没有设置该域则认为实体内容将提供给所有的语言阅读<br>者。eg:Content-Language:da<br><span style="color: #ff0000;"><strong>Content-Length</strong></span>实体报头域用于指明实体正文的长度,以字节方式存储的十进制数字来表示。<br><span style="color: #ff0000;"><strong>Content-Type</strong></span>实体报头域用语指明发送给接收者的实体正文的媒体类型。eg:<br>Content-Type:text/html;charset=ISO-8859-1<br>Content-Type:text/html;charset=GB2312<br><span style="color: #ff0000;"><strong>Last-Modified</strong></span>实体报头域用于指示资源的最后修改日期和时间。<br><span style="color: #ff0000;"><strong>Expires</strong></span>实体报头域给出响应过期的日期和时间。为了让代理服务器或浏览器在一段时间以后更新缓存中(再次访问曾访问过的页面时,直接从缓存中加载,缩短响应时间和降低服务器负载)的页面,我们可以使用Expires实体报头域指定页面过期的时间。eg:Expires:Thu,15 Sep 2006 16:23:12 GMT<br>HTTP1.1的客户端和缓存必须将其他非法的日期格式(包括0)看作已经过期。eg:为了让浏览器不要缓存页面,我们也可以利用Expires实体报头域,设置为0,jsp中程序如下:response.setDateHeader("Expires","0");</span></p>
<p><span>作者:<span>Jeffrey&nbsp;&nbsp;</span>转自:<a href="http://blog.csdn.net/gueter/article/details/1524447">http://blog.csdn.net/gueter/article/details/1524447</a></span></p>
<p><span style="color: #0000ff;"><strong>工具类为HttpUtil.java</strong></span></p>
<div class="cnblogs_code" οnclick="cnblogs_code_show('4a5e2294-34c1-40d1-93aa-6e63853b08c2')"><img id="code_img_closed_4a5e2294-34c1-40d1-93aa-6e63853b08c2" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_4a5e2294-34c1-40d1-93aa-6e63853b08c2" class="code_img_opened" style="display: none;" οnclick="cnblogs_code_hide('4a5e2294-34c1-40d1-93aa-6e63853b08c2',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt=""><span class="cnblogs_code_collapse">View Code </span>
<div id="cnblogs_code_open_4a5e2294-34c1-40d1-93aa-6e63853b08c2" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> HttpUtil {
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> String httpGet(String httpUrl) {
        String result </span>= ""<span style="color: #000000;">;
        DefaultHttpClient httpclient </span>= <span style="color: #0000ff;">new</span> DefaultHttpClient();<span style="color: #008000;">//</span><span style="color: #008000;"> 创建http客户端</span>
        HttpGet httpget = <span style="color: #0000ff;">new</span><span style="color: #000000;"> HttpGet(httpUrl);
        HttpResponse response </span>= <span style="color: #0000ff;">null</span><span style="color: #000000;">;
        HttpParams params </span>= httpclient.getParams(); <span style="color: #008000;">//</span><span style="color: #008000;"> 计算网络超时用</span>
        HttpConnectionParams.setConnectionTimeout(params, 15 * 1000<span style="color: #000000;">);
        HttpConnectionParams.setSoTimeout(params, </span>20 * 1000<span style="color: #000000;">);
        
        </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
            response </span>=<span style="color: #000000;"> httpclient.execute(httpget);
            HttpEntity entity </span>= response.getEntity();<span style="color: #008000;">//</span><span style="color: #008000;"> 得到http的内容</span>
            response.getStatusLine().getStatusCode();<span style="color: #008000;">//</span><span style="color: #008000;"> 得到http的状态返回值</span>
            result = EntityUtils.toString(response.getEntity());<span style="color: #008000;">//</span><span style="color: #008000;"> 得到具体的返回值,一般是xml文件</span>
            entity.consumeContent();<span style="color: #008000;">//</span><span style="color: #008000;"> 如果entity不为空,则释放内存空间</span>
            httpclient.getCookieStore();<span style="color: #008000;">//</span><span style="color: #008000;"> 得到cookis</span>
            httpclient.getConnectionManager().shutdown();<span style="color: #008000;">//</span><span style="color: #008000;"> 关闭http客户端</span>
        } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (ClientProtocolException e) {
            e.printStackTrace();
        } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (IOException e) {
            e.printStackTrace();
        }
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> result;
    }

    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> String httpPost(String httpUrl, String data) {
        String result </span>= ""<span style="color: #000000;">;
        DefaultHttpClient httpclient </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> DefaultHttpClient();
        HttpPost httpPost </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> HttpPost(httpUrl);
        </span><span style="color: #008000;">//</span><span style="color: #008000;"> httpclient.setCookieStore(DataDefine.mCookieStore);</span>
<span style="color: #000000;">        
        HttpParams params </span>= httpclient.getParams(); <span style="color: #008000;">//</span><span style="color: #008000;"> 计算网络超时用</span>
        HttpConnectionParams.setConnectionTimeout(params, 15 * 1000<span style="color: #000000;">);
        HttpConnectionParams.setSoTimeout(params, </span>20 * 1000<span style="color: #000000;">);
        httpPost.setHeader(</span>"Content-Type", "text/xml"<span style="color: #000000;">);
        StringEntity httpPostEntity;
        
        </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
            httpPostEntity </span>= <span style="color: #0000ff;">new</span> StringEntity(data, "UTF-8"<span style="color: #000000;">);
            httpPost.setEntity(httpPostEntity);
            HttpResponse response </span>=<span style="color: #000000;"> httpclient.execute(httpPost);
            HttpEntity entity </span>= response.getEntity();<span style="color: #008000;">//</span><span style="color: #008000;"> 得到http的内容</span>
            response.getStatusLine().getStatusCode();<span style="color: #008000;">//</span><span style="color: #008000;"> 得到http的状态返回值</span>
            result = EntityUtils.toString(response.getEntity());<span style="color: #008000;">//</span><span style="color: #008000;"> 得到具体的返回值,一般是xml文件</span>
            entity.consumeContent();<span style="color: #008000;">//</span><span style="color: #008000;"> 如果entity不为空,则释放内存空间</span>
            httpclient.getCookieStore();<span style="color: #008000;">//</span><span style="color: #008000;"> 得到cookis</span>
            httpclient.getConnectionManager().shutdown();<span style="color: #008000;">//</span><span style="color: #008000;"> 关闭http客户端</span>
        } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {
            e.printStackTrace();
        }</span><span style="color: #008000;">//</span><span style="color: #008000;"> base64是经过编码的字符串,可以理解为字符串
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> StringEntity httpPostEntity = new StringEntity("UTF-8");</span>
        <span style="color: #0000ff;">return</span><span style="color: #000000;"> result;
    }
}</span></pre>
</div>
</div>
<p><strong style="font-size: 18pt;">二、HTTPS</strong></p>
<p><span>  HTTPS(Hypertext Transfer Protocol over Secure Socket Layer,基于SSL的HTTP协议)使用了HTTP协议,但HTTPS使用不同于HTTP协议的默认端口及一个加密、身份验证层(HTTP与TCP之间)。这个协议的最初研发由网景公司进行,提供了身份验证与加密通信方法,现在它被广泛用于互联网上安全敏感的通信。</span></p>
<p>  客户端在使用HTTPS方式与Web服务器通信时有以下几个<span style="color: #ff0000;"><strong>步骤</strong><span style="color: #000000;">,如图所示</span></span>。</p>
<p>(1)客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。</p>
<p>(2)Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。</p>
<p>(3)客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。</p>
<p>(4)客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。</p>
<p>(5)Web服务器利用自己的私钥解密出会话密钥。</p>
<p>(6)Web服务器利用会话密钥加密与客户端之间的通信。</p>
<p><img src="https://pic002.cnblogs.com/images/2012/339704/2012071410212142.gif" alt="" data-pinit="registered"></p>
<p><span style="color: #0000ff;"><strong>工具类为HttpsUtil.java</strong></span></p>
<div class="cnblogs_code" οnclick="cnblogs_code_show('76a1b822-c586-40d0-be26-102c413c4908')"><img id="code_img_closed_76a1b822-c586-40d0-be26-102c413c4908" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_76a1b822-c586-40d0-be26-102c413c4908" class="code_img_opened" style="display: none;" οnclick="cnblogs_code_hide('76a1b822-c586-40d0-be26-102c413c4908',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt=""><span class="cnblogs_code_collapse">View Code </span>
<div id="cnblogs_code_open_76a1b822-c586-40d0-be26-102c413c4908" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> HttpsUtil {
    </span><span style="color: #0000ff;">static</span> TrustManager[] xtmArray = <span style="color: #0000ff;">new</span> MytmArray[] { <span style="color: #0000ff;">new</span> MytmArray() };<span style="color: #008000;">//</span><span style="color: #008000;"> 创建信任规则列表</span>
    <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">final</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">int</span> CONNENT_TIMEOUT = 15000<span style="color: #000000;">;
    </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">final</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">int</span> READ_TIMEOUT = 15000<span style="color: #000000;">;
    </span><span style="color: #0000ff;">static</span> HostnameVerifier DO_NOT_VERIFY = <span style="color: #0000ff;">new</span><span style="color: #000000;"> HostnameVerifier() {
        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;"> verify(String hostname, SSLSession session) {
            </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;
        }
    };

    </span><span style="color: #008000;">/**</span><span style="color: #008000;">
     * 信任所有主机-对于任何证书都不做检查 Create a trust manager that does not validate
     * certificate chains, Android 采用X509的证书信息机制,Install the all-trusting trust
     * manager
     </span><span style="color: #008000;">*/</span>
    <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> trustAllHosts() {
        </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
            SSLContext sc </span>= SSLContext.getInstance("TLS"<span style="color: #000000;">);
            sc.init(</span><span style="color: #0000ff;">null</span>, xtmArray, <span style="color: #0000ff;">new</span><span style="color: #000000;"> java.security.SecureRandom());
            HttpsURLConnection
                    .setDefaultSSLSocketFactory(sc.getSocketFactory());
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 不进行主机名确认,对所有主机</span>
<span style="color: #000000;">            HttpsURLConnection.setDefaultHostnameVerifier(DO_NOT_VERIFY);
        } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {
            e.printStackTrace();
        }
    }

    </span><span style="color: #008000;">//</span><span style="color: #008000;"> /**
    </span><span style="color: #008000;">//</span><span style="color: #008000;"> * https get方法,返回值是https请求,服务端返回的数据string类型,数据进行xml解析
    </span><span style="color: #008000;">//</span><span style="color: #008000;"> * */
    </span><span style="color: #008000;">//</span><span style="color: #008000;"> public static String HttpsGet(String httpsurl) {
    </span><span style="color: #008000;">//</span><span style="color: #008000;"> return HttpsPost(httpsurl, null);
    </span><span style="color: #008000;">//</span>
    <span style="color: #008000;">//</span><span style="color: #008000;"> }</span>
    <span style="color: #008000;">/**</span><span style="color: #008000;">
     * https post方法,返回值是https请求,服务端返回的数据string类型,数据进行xml解析
     * </span><span style="color: #008000;">*/</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> String HttpsPost(String httpsurl, String data) {
        String result </span>= <span style="color: #0000ff;">null</span><span style="color: #000000;">;
        HttpURLConnection http </span>= <span style="color: #0000ff;">null</span><span style="color: #000000;">;
        URL url;
        </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
            url </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> URL(httpsurl);
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 判断是http请求还是https请求</span>
            <span style="color: #0000ff;">if</span> (url.getProtocol().toLowerCase().equals("https"<span style="color: #000000;">)) {
                trustAllHosts();
                http </span>=<span style="color: #000000;"> (HttpsURLConnection) url.openConnection();
                ((HttpsURLConnection) http).setHostnameVerifier(DO_NOT_VERIFY);</span><span style="color: #008000;">//</span><span style="color: #008000;"> 不进行主机名确认</span>
            } <span style="color: #0000ff;">else</span><span style="color: #000000;"> {
                http </span>=<span style="color: #000000;"> (HttpURLConnection) url.openConnection();
            }

            http.setConnectTimeout(CONNENT_TIMEOUT);</span><span style="color: #008000;">//</span><span style="color: #008000;"> 设置超时时间</span>
<span style="color: #000000;">            http.setReadTimeout(READ_TIMEOUT);
            </span><span style="color: #0000ff;">if</span> (data == <span style="color: #0000ff;">null</span><span style="color: #000000;">) {
                http.setRequestMethod(</span>"GET");<span style="color: #008000;">//</span><span style="color: #008000;"> 设置请求类型</span>
                http.setDoInput(<span style="color: #0000ff;">true</span><span style="color: #000000;">);
                </span><span style="color: #008000;">//</span><span style="color: #008000;"> http.setRequestProperty("Content-Type", "text/xml");</span>
                <span style="color: #0000ff;">if</span> (AppSession.mCookieStore != <span style="color: #0000ff;">null</span><span style="color: #000000;">)
                    http.setRequestProperty(</span>"Cookie"<span style="color: #000000;">, AppSession.mCookieStore);
            } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
                http.setRequestMethod(</span>"POST");<span style="color: #008000;">//</span><span style="color: #008000;"> 设置请求类型为post</span>
                http.setDoInput(<span style="color: #0000ff;">true</span><span style="color: #000000;">);
                http.setDoOutput(</span><span style="color: #0000ff;">true</span><span style="color: #000000;">);
                </span><span style="color: #008000;">//</span><span style="color: #008000;"> http.setRequestProperty("Content-Type", "text/xml");</span>
                <span style="color: #0000ff;">if</span> (AppSession.mCookieStore != <span style="color: #0000ff;">null</span>
                        &amp;&amp; AppSession.mCookieStore.trim().length() &gt; 0<span style="color: #000000;">)
                    http.setRequestProperty(</span>"Cookie"<span style="color: #000000;">, AppSession.mCookieStore);

                DataOutputStream out </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> DataOutputStream(
                        http.getOutputStream());
                out.writeBytes(data);
                out.flush();
                out.close();
            }

            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 设置http返回状态200(ok)还是403</span>
            AppSession.httpsResponseCode =<span style="color: #000000;"> http.getResponseCode();
            BufferedReader in </span>= <span style="color: #0000ff;">null</span><span style="color: #000000;">;
            </span><span style="color: #0000ff;">if</span> (AppSession.httpsResponseCode == 200<span style="color: #000000;">) {
                getCookie(http);
                in </span>= <span style="color: #0000ff;">new</span> BufferedReader(<span style="color: #0000ff;">new</span><span style="color: #000000;"> InputStreamReader(
                        http.getInputStream()));
            } </span><span style="color: #0000ff;">else</span><span style="color: #000000;">
                in </span>= <span style="color: #0000ff;">new</span> BufferedReader(<span style="color: #0000ff;">new</span><span style="color: #000000;"> InputStreamReader(
                        http.getErrorStream()));
            String temp </span>=<span style="color: #000000;"> in.readLine();
            </span><span style="color: #0000ff;">while</span> (temp != <span style="color: #0000ff;">null</span><span style="color: #000000;">) {
                </span><span style="color: #0000ff;">if</span> (result != <span style="color: #0000ff;">null</span><span style="color: #000000;">)
                    result </span>+=<span style="color: #000000;"> temp;
                </span><span style="color: #0000ff;">else</span><span style="color: #000000;">
                    result </span>=<span style="color: #000000;"> temp;
                temp </span>=<span style="color: #000000;"> in.readLine();
            }
            in.close();
            http.disconnect();
        } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {
            e.printStackTrace();
        }
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> result;
    }

    </span><span style="color: #008000;">/**</span><span style="color: #008000;">
     * 得到cookie
     * 
     </span><span style="color: #008000;">*/</span>
    <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> getCookie(HttpURLConnection http) {
        String cookieVal </span>= <span style="color: #0000ff;">null</span><span style="color: #000000;">;
        String key </span>= <span style="color: #0000ff;">null</span><span style="color: #000000;">;
        AppSession.mCookieStore </span>= ""<span style="color: #000000;">;
        </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 1; (key = http.getHeaderFieldKey(i)) != <span style="color: #0000ff;">null</span>; i++<span style="color: #000000;">) {
            </span><span style="color: #0000ff;">if</span> (key.equalsIgnoreCase("set-cookie"<span style="color: #000000;">)) {
                cookieVal </span>=<span style="color: #000000;"> http.getHeaderField(i);
                cookieVal </span>= cookieVal.substring(0, cookieVal.indexOf(";"<span style="color: #000000;">));
                AppSession.mCookieStore </span>= AppSession.mCookieStore +<span style="color: #000000;"> cookieVal
                        </span>+ ";"<span style="color: #000000;">;
            }
        }
    }
}</span></pre>
</div>
</div>
<p><strong style="font-size: 18pt;">三、WebService</strong></p>
<p><span style="color: #000000;">  在<a href="http://wenku.baidu.com/view/6f28a71ea76e58fafab003d5.html###">《Web Service开发详解》</a>资料中详细介绍了WebService,故本文只贴出Android的代码。</span></p>
<p>&nbsp;</p>
<div class="cnblogs_code" οnclick="cnblogs_code_show('690aa01c-e68b-4c09-aa74-2501657d44bf')"><img id="code_img_closed_690aa01c-e68b-4c09-aa74-2501657d44bf" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_690aa01c-e68b-4c09-aa74-2501657d44bf" class="code_img_opened" style="display: none;" οnclick="cnblogs_code_hide('690aa01c-e68b-4c09-aa74-2501657d44bf',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt=""><span class="cnblogs_code_collapse">View Code </span>
<div id="cnblogs_code_open_690aa01c-e68b-4c09-aa74-2501657d44bf" class="cnblogs_code_hide">
<pre><span style="color: #008000;">/**</span><span style="color: #008000;">
 * WebService调用返回值
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> String invoke(String nameSpace, String methodName,
        String httpUrl, Map</span>&lt;String, Object&gt;<span style="color: #000000;"> map) {
    </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
        </span><span style="color: #008000;">//</span><span style="color: #008000;"> 实例化SoapObject,invokerWS为服务端调用WebService的方法名</span>
        SoapObject request = <span style="color: #0000ff;">new</span><span style="color: #000000;"> SoapObject(nameSpace, methodName);
        
        </span><span style="color: #008000;">//</span><span style="color: #008000;"> 设置调用方法的参数,参数是服务端所要求的</span>
        <span style="color: #0000ff;">if</span> (map != <span style="color: #0000ff;">null</span><span style="color: #000000;">) {
            Set</span>&lt;String&gt; keySet = map.keySet();<span style="color: #008000;">//</span><span style="color: #008000;"> 返回键的集合</span>
            Iterator&lt;String&gt; it =<span style="color: #000000;"> keySet.iterator();
            </span><span style="color: #0000ff;">while</span> (it.hasNext()) {<span style="color: #008000;">//</span><span style="color: #008000;"> 第一种迭代方式取键值</span>
                Object key =<span style="color: #000000;"> it.next();
                request.addProperty(key.toString(), map.get(key).toString());
                Log.i(key.toString(), map.get(key).toString());
            }
        }

        Element username </span>= <span style="color: #0000ff;">new</span> Element().createElement(nameSpace, "UserName"<span style="color: #000000;">);
        username.addChild(Node.TEXT, </span>"mobile"<span style="color: #000000;">);

        Element pass </span>= <span style="color: #0000ff;">new</span> Element().createElement(nameSpace, "Password"<span style="color: #000000;">);
        pass.addChild(Node.TEXT, </span>"111111"<span style="color: #000000;">);

        Element[] header </span>= <span style="color: #0000ff;">new</span> Element[1<span style="color: #000000;">];
        header[</span>0] = <span style="color: #0000ff;">new</span> Element().createElement(nameSpace, "CredentialSoapHeader"<span style="color: #000000;">);
        header[</span>0<span style="color: #000000;">].addChild(Node.ELEMENT, username);
        header[</span>0<span style="color: #000000;">].addChild(Node.ELEMENT, pass);

        </span><span style="color: #008000;">//</span><span style="color: #008000;"> 设置SOAP请求信息,获得序列化的Envelope</span>
        SoapSerializationEnvelope envelope = <span style="color: #0000ff;">new</span><span style="color: #000000;"> SoapSerializationEnvelope(
                SoapEnvelope.VER11);
        envelope.headerOut </span>=<span style="color: #000000;"> header;
        envelope.bodyOut </span>=<span style="color: #000000;"> request;
        envelope.dotNet </span>= <span style="color: #0000ff;">true</span><span style="color: #000000;">;
        envelope.setOutputSoapObject(request);

        </span><span style="color: #008000;">//</span><span style="color: #008000;"> 构建传输对象,指明URL</span>
        HttpTransportSE httpTransport = <span style="color: #0000ff;">new</span> HttpTransportSE(httpUrl, 10000<span style="color: #000000;">);
        httpTransport.debug </span>= <span style="color: #0000ff;">true</span><span style="color: #000000;">;

        </span><span style="color: #008000;">//</span><span style="color: #008000;"> 调用WebService,methodName是调用服务端的方法名</span>
        httpTransport.call(nameSpace +<span style="color: #000000;"> methodName, envelope);

        </span><span style="color: #008000;">//</span><span style="color: #008000;"> 获得服务端的返回结果</span>
        <span style="color: #0000ff;">return</span><span style="color: #000000;"> envelope.getResponse().toString();
    } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {
        Log.e(</span>"WebServieInvoker.invoke"<span style="color: #000000;">, e.getMessage());
    }
    </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">null</span><span style="color: #000000;">;
}</span></pre>
</div>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="color: #000000;">&nbsp;</span></p></div><div id="MySignature"></div>
<div class="clear"></div>
<div id="blog_post_info_block">
<div id="BlogPostCategory">分类: <a href="https://www.cnblogs.com/ok-lanyan/category/386499.html" target="_blank">Android技术</a></div>
<div id="EntryTag">标签: <a href="https://www.cnblogs.com/ok-lanyan/tag/http/">http</a>, <a href="https://www.cnblogs.com/ok-lanyan/tag/https/">https</a>, <a href="https://www.cnblogs.com/ok-lanyan/tag/webservice/">webservice</a></div>
<div id="blog_post_info"><div id="green_channel">
        <a href="javascript:void(0);" id="green_channel_digg" οnclick="DiggIt(2591204,cb_blogId,1);green_channel_success(this,'谢谢推荐!');">好文要顶</a>
            <a id="green_channel_follow" οnclick="follow('d940f719-c8f3-e011-8ee0-842b2b196315');" href="javascript:void(0);">关注我</a>
    <a id="green_channel_favorite" οnclick="AddToWz(cb_entryId);return false;" href="javascript:void(0);">收藏该文</a>
    <a id="green_channel_weibo" href="javascript:void(0);" title="分享至新浪微博" οnclick="ShareToTsina()"><img src="//common.cnblogs.com/images/icon_weibo_24.png" alt=""></a>
    <a id="green_channel_wechat" href="javascript:void(0);" title="分享至微信" οnclick="shareOnWechat()"><img src="//common.cnblogs.com/images/wechat.png" alt=""></a>
</div>
<div id="author_profile">
    <div id="author_profile_info" class="author_profile_info">
            <a href="https://home.cnblogs.com/u/ok-lanyan/" target="_blank"><img src="//pic.cnblogs.com/face/u339704.jpg?id=06151510" class="author_avatar" alt=""></a>
        <div id="author_profile_detail" class="author_profile_info">
            <a href="https://home.cnblogs.com/u/ok-lanyan/">ok_lanyan</a><br>
            <a href="https://home.cnblogs.com/u/ok-lanyan/followees">关注 - 2</a><br>
            <a href="https://home.cnblogs.com/u/ok-lanyan/followers">粉丝 - 51</a>
        </div>
    </div>
    <div class="clear"></div>
    <div id="author_profile_honor"></div>
    <div id="author_profile_follow">
                <a href="javascript:void(0);" οnclick="follow('d940f719-c8f3-e011-8ee0-842b2b196315');return false;">+加关注</a>
    </div>
</div>
<div id="div_digg">
    <div class="diggit" οnclick="votePost(2591204,'Digg')">
        <span class="diggnum" id="digg_count">3</span>
    </div>
    <div class="buryit" οnclick="votePost(2591204,'Bury')">
        <span class="burynum" id="bury_count">0</span>
    </div>
    <div class="clear"></div>
    <div class="diggword" id="digg_tips">
    </div>
</div>
<script type="text/javascript">
    currentDiggType = 0;
</script></div>
<div class="clear"></div>
<div id="post_next_prev"><a href="https://www.cnblogs.com/ok-lanyan/archive/2012/07/13/2590288.html" class="p_n_p_prefix">« </a> 上一篇:<a href="https://www.cnblogs.com/ok-lanyan/archive/2012/07/13/2590288.html" title="发布于2012-07-13 15:15">百度地图 根据经纬度获取地址</a><br><a href="https://www.cnblogs.com/ok-lanyan/archive/2012/07/15/2592070.html" class="p_n_p_prefix">» </a> 下一篇:<a href="https://www.cnblogs.com/ok-lanyan/archive/2012/07/15/2592070.html" title="发布于2012-07-15 09:41">新浪微博授权发布 WebView Android</a><br></div>
</div>


        </div>
        <div class="postDesc">posted @ <span id="post-date">2012-07-14 10:35</span> <a href="https://www.cnblogs.com/ok-lanyan/">ok_lanyan</a> 阅读(<span id="post_view_count">22016</span>) 评论(<span id="post_comment_count">4</span>)  <a href="https://i.cnblogs.com/EditPosts.aspx?postid=2591204" rel="nofollow">编辑</a> <a href="#" οnclick="AddToWz(2591204);return false;">收藏</a></div>
    </div>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值