HttpURLConnection 以及其父类URLConnection 中的方法及静态常量

本文将介绍HttpURLConnection 以及其父类URLConnection中的常用方法以及成员变量,并且会通过例子来看看这些方法的用处。

一、HttpURLConnection.java

1. HttpURLConnection.java常用的方法:

(1) void setRequestMethod(String method)   //设置请求方法

  /**
   * The HTTP method (GET,POST,PUT,etc.).
   */
  protected String method = "GET"; //在HttpURLConnection中将会默认请求方法为"GET",开发者可通过下面方法进行重新设置


public void setRequestMethod(String method) throws ProtocolException {
        if (connected) {           //如果当前已经连接,将抛出protocolException  提示已连接
            throw new ProtocolException("Can't reset method: already connected");
        }
        // This restriction will prevent people from using this class to
        // experiment w/ new HTTP methods using java.  But it should
        // be placed for security - the request String could be
        // arbitrarily long.

        for (int i = 0; i < methods.length; i++) {
            if (methods[i].equals(method)) {
                if (method.equals("TRACE")) { //如果是trace,则会判断权限,因为这将暴露出一些私人信息
                    SecurityManager s = System.getSecurityManager();
                    if (s != null) {
                        s.checkPermission(new NetPermission("allowHttpTrace"));
                    }
                }
                this.method = method;       //将值赋给method 
                return;
            }
        }
        throw new ProtocolException("Invalid HTTP method: " + method);
    }


(2)String   getRequestMethod()                //获取请求方法

     直接return method;


(3)int   getResponseCode()                 //获得响应状态码

public int getResponseCode() throws IOException {
        /*
         * We're got the response code already
         */
        if (responseCode != -1) {     //responseCode不为-1时,说明已经存在
            return responseCode;
        }

        /*
         * Ensure that we have connected to the server. Record
         * exception as we need to re-throw it if there isn't
         * a status line.
         */
        Exception exc = null;
        try {
            getInputStream();          //此时还没有状态行,所以通过getInputStream() 进行connect
        } catch (Exception e) {
            exc = e;
        }

        /*
         * If we can't a status-line then re-throw any exception
         * that getInputStream threw.
         */
        String statusLine = getHeaderField(0);           //一般在连接失败时出现
        if (statusLine == null) {
            if (exc != null) {
                if (exc instanceof RuntimeException)
                    throw (RuntimeException)exc;
                else
                    throw (IOException)exc;
            }
            return -1;
        }

        /*
         * Examine the status-line - should be formatted as per
         * section 6.1 of RFC 2616 :-
         *
         * Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase    //上篇文章讲过状态行的组成 HTTP版本号, 响应状态码 , 状态码文本描述
         *
         * If status line can't be parsed return -1.
         */
        if (statusLine.startsWith("HTTP/1.")) {       //比如  HTTP/1.1 200 OK
            int codePos = statusLine.indexOf(' ');    //状态行以空格隔开   8
            if (codePos > 0) {

                int phrasePos = statusLine.indexOf(' ', codePos+1);   //  12
                if (phrasePos > 0 && phrasePos < statusLine.length()) {
                    responseMessage = statusLine.substring(phrasePos+1);  //此时获得状态码文本描述 OK   13位置往后就是OK了
                }

                // deviation from RFC 2616 - don't reject status line
                // if SP Reason-Phrase is not included.
                if (phrasePos < 0)
                    phrasePos = statusLine.length();

                try {
                    responseCode = Integer.parseInt
                            (statusLine.substring(codePos+1, phrasePos));    //获得状态码  9~12 为200
                    return responseCode;
                } catch (NumberFormatException e) { }
            }
        }
        return -1;
    }

(3)String  getResponseMessage()              //获取响应状态码的描述

    直接return responseMessage;  在上面方法中已经获得

(4)long    getHeaderFieldDate(String name, long Default)    //响应日期

public long getHeaderFieldDate(String name, long Default) {
        String dateString = getHeaderField(name);   //父类中的方法,获得响应头中的键值对
        try {
            if (dateString.indexOf("GMT") == -1) {    //一般为Date Wed, 12 Jul 2017 10:59:31 GMT
                dateString = dateString+" GMT";   
            }
            return Date.parse(dateString);
        } catch (Exception e) {
        }
        return Default;
    }

(5)void    disconnect()                  //取消连接

抽象方法,指在一段时间内不太可能进行连接

(6)boolean      usingProxy()                  //连接是否通过代理

抽象方法

(7)Permission   getPermission()                 //获得权限

public Permission getPermission() throws IOException {
        int port = url.getPort();
        port = port < 0 ? 80 : port;
        String host = url.getHost() + ":" + port;
        Permission permission = new SocketPermission(host, "connect");  //建立此HttpURLConnection所需要的权限
        return permission;
    }

(8)InputStream  getErrorStream()              //获得错误信息

连接失败,但服务器还是返回数据,此时走错误流


2. HttpURLConnection.java常用的成员变量或静态常量:

下面主要是与状态码相关的静态常量

    /**
     * HTTP Status-Code 200: OK.
     */
    public static final int HTTP_OK = 200;

    /**
     * HTTP Status-Code 201: Created.
     */
    public static final int HTTP_CREATED = 201;

    /**
     * HTTP Status-Code 202: Accepted.
     */
    public static final int HTTP_ACCEPTED = 202;

    /**
     * HTTP Status-Code 203: Non-Authoritative Information.
     */
    public static final int HTTP_NOT_AUTHORITATIVE = 203;

    /**
     * HTTP Status-Code 204: No Content.
     */
    public static final int HTTP_NO_CONTENT = 204;

    /**
     * HTTP Status-Code 205: Reset Content.
     */
    public static final int HTTP_RESET = 205;

    /**
     * HTTP Status-Code 206: Partial Content.
     */
    public static final int HTTP_PARTIAL = 206;

    /* 3XX: relocation/redirect */

    /**
     * HTTP Status-Code 300: Multiple Choices.
     */
    public static final int HTTP_MULT_CHOICE = 300;

    /**
     * HTTP Status-Code 301: Moved Permanently.
     */
    public static final int HTTP_MOVED_PERM = 301;

    /**
     * HTTP Status-Code 302: Temporary Redirect.
     */
    public static final int HTTP_MOVED_TEMP = 302;

    /**
     * HTTP Status-Code 303: See Other.
     */
    public static final int HTTP_SEE_OTHER = 303;

    /**
     * HTTP Status-Code 304: Not Modified.
     */
    public static final int HTTP_NOT_MODIFIED = 304;

    /**
     * HTTP Status-Code 305: Use Proxy.
     */
    public static final int HTTP_USE_PROXY = 305;

    /* 4XX: client error */

    /**
     * HTTP Status-Code 400: Bad Request.
     */
    public static final int HTTP_BAD_REQUEST = 400;

    /**
     * HTTP Status-Code 401: Unauthorized.
     */
    public static final int HTTP_UNAUTHORIZED = 401;

    /**
     * HTTP Status-Code 402: Payment Required.
     */
    public static final int HTTP_PAYMENT_REQUIRED = 402;

    /**
     * HTTP Status-Code 403: Forbidden.
     */
    public static final int HTTP_FORBIDDEN = 403;

    /**
     * HTTP Status-Code 404: Not Found.
     */
    public static final int HTTP_NOT_FOUND = 404;

    /**
     * HTTP Status-Code 405: Method Not Allowed.
     */
    public static final int HTTP_BAD_METHOD = 405;

    /**
     * HTTP Status-Code 406: Not Acceptable.
     */
    public static final int HTTP_NOT_ACCEPTABLE = 406;

    /**
     * HTTP Status-Code 407: Proxy Authentication Required.
     */
    public static final int HTTP_PROXY_AUTH = 407;

    /**
     * HTTP Status-Code 408: Request Time-Out.
     */
    public static final int HTTP_CLIENT_TIMEOUT = 408;

    /**
     * HTTP Status-Code 409: Conflict.
     */
    public static final int HTTP_CONFLICT = 409;

    /**
     * HTTP Status-Code 410: Gone.
     */
    public static final int HTTP_GONE = 410;

    /**
     * HTTP Status-Code 411: Length Required.
     */
    public static final int HTTP_LENGTH_REQUIRED = 411;

    /**
     * HTTP Status-Code 412: Precondition Failed.
     */
    public static final int HTTP_PRECON_FAILED = 412;

    /**
     * HTTP Status-Code 413: Request Entity Too Large.
     */
    public static final int HTTP_ENTITY_TOO_LARGE = 413;

    /**
     * HTTP Status-Code 414: Request-URI Too Large.
     */
    public static final int HTTP_REQ_TOO_LONG = 414;

    /**
     * HTTP Status-Code 415: Unsupported Media Type.
     */
    public static final int HTTP_UNSUPPORTED_TYPE = 415;

    /* 5XX: server error */

    /**
     * HTTP Status-Code 500: Internal Server Error.
     * @deprecated   it is misplaced and shouldn't have existed.
     */
    @Deprecated
    public static final int HTTP_SERVER_ERROR = 500;

    /**
     * HTTP Status-Code 500: Internal Server Error.
     */
    public static final int HTTP_INTERNAL_ERROR = 500;

    /**
     * HTTP Status-Code 501: Not Implemented.
     */
    public static final int HTTP_NOT_IMPLEMENTED = 501;

    /**
     * HTTP Status-Code 502: Bad Gateway.
     */
    public static final int HTTP_BAD_GATEWAY = 502;

    /**
     * HTTP Status-Code 503: Service Unavailable.
     */
    public static final int HTTP_UNAVAILABLE = 503;

    /**
     * HTTP Status-Code 504: Gateway Timeout.
     */
    public static final int HTTP_GATEWAY_TIMEOUT = 504;

    /**
     * HTTP Status-Code 505: HTTP Version Not Supported.
     */
    public static final int HTTP_VERSION = 505;


二、父类URLConnection.java
(1)void setConnectTimeout(int timeout)         //设置连接超时时间
将值赋给 connectTimeout = timeout;

(2)int getConnectTimeout()                     //返回连接超时时间
直接return connectTimeout ;

(3)void setReadTimeout(int timeout)                //设置读超时时间
将值赋给readTimeout = timeout;

(4)int getReadTimeout()                           //返回读超时时间
直接return readTimeout ;

(5)URL getURL()                                   //返回URL

(6)int getContentLength()                         //返回content-length 头字段的值

在HTTP协议中,Content-Length用于描述HTTP消息实体的传输长度the transfer-length of the message-body。在HTTP协议中,消息实体长度和消息实体的传输长度是有区别,比如说gzip压缩下,消息实体长度是压缩前的长度,消息实体的传输长度是gzip压缩后的长度。

(7)String getContentType()                        //返回content-type头字段的值

服务器发送内容的类型和编码类型
(8)String getContentEncoding()                    //返回content-encoding头字段的值

服务器发送的压缩编码方式
(9)long  getExpiration()                       //返回 expires 头字段的值

用来控制网页缓存的失效日期

(10)long getDate()                                   //返回date头字段的值

获得HTTP响应消息头中的Date字段的值,返回的是服务器响应的时间

(11)long getLastModified()                            //返回last-modified头字段的值   

HTTP响应消息头有一个Last-Modified字段,这个字段表示服务器内容最新修改时间。如果请求消息头中包含If-Modificed-Since字段,并且该字段的时间比Last-Modified字段的时间早。或是请求消息头中没有If-Modificed-Since字段。service方法就会调用doGet方法来重新获得服务端内容。但这有一个前提,就是getLastModified方法必须返回一个正数。但在默认情况下,getLastModified方法返回-1.因此,service方法调用用doGet方法的规则如下:  当getLastModified返回-1时,service方法总会调用doGet方法。

6~11这几个方法,是通过字段key content-length   content-type   content-encoding    expires    date    last-modified 在方法getHeaderField中获得值

public String getHeaderField(String name) {  
        return null;         //源码中看到的是null, 实际应该响应消息头的一个解析。
}


(12)InputStream getInputStream()                    //获得输入流

从此打开的连接读入的输入流。           内部包含connect的操作
抛出: 
IOException - 如果在创建输入流时发生 I/O 错误。 
UnknownServiceException - 如果协议不支持输入。

(13)OutputStream getOutputStream()                 //获得输出流
写入到此连接的输出流。 
抛出: 
IOException - 如果在创建输出流时发生 I/O 错误。 
UnknownServiceException - 如果协议不支持输出。


三、常见的请求头与响应头(后面括号内有解释错误的可以留言更改- -。)

请求头: 
Accept: text/html,image/*(浏览器可以接收的类型) 
Accept-Charset: ISO-8859-1(浏览器可以接收的编码类型) 
Accept-Encoding: gzip,compress(浏览器可以接收压缩编码类型) 
Accept-Language: en-us,zh-cn(浏览器可以接收的语言和国家类型) 
Host: www.it315.org:80(浏览器请求的主机和端口) 
If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT(某个页面缓存时间) 
Referer: http://www.it315.org/index.jsp(请求来自于哪个页面) 
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)(浏览器相关信息) 
Cookie:(浏览器暂存服务器发送的信息) 
Connection: close(1.0)/Keep-Alive(1.1)(HTTP请求的版本的特点) 
Date: Tue, 11 Jul 2000 18:23:51 GMT(请求网站的时间) 
 
响应头: 
Location: http://www.it315.org/index.jsp(控制浏览器显示哪个页面) 
Server:apache tomcat(服务器的类型) 
Content-Encoding: gzip(服务器发送的压缩编码方式) 
Content-Length: 80(服务器发送显示的字节码长度) 
Content-Language: zh-cn(服务器发送内容的语言和国家名) 
Content-Type: image/jpeg; charset=UTF-8(服务器发送内容的类型和编码类型) 
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT(服务器最后一次修改的时间) 
Refresh: 1;url=http://www.it315.org(控制浏览器1秒钟后转发URL所指向的页面) 
Content-Disposition: attachment; filename=aaa.jpg(服务器控制浏览器发下载方式打开文件) 
Transfer-Encoding: chunked(服务器分块传递数据到客户端)  
Set-Cookie:SS=Q0=5Lb_nQ; path=/search(服务器发送Cookie相关的信息) 
Expires: -1(服务器控制浏览器不要缓存网页,默认是缓存) 
Cache-Control: no-cache(服务器控制浏览器不要缓存网页) 
Pragma: no-cache(服务器控制浏览器不要缓存网页)   
Connection: close/Keep-Alive(HTTP请求的版本的特点)   
Date: Tue, 11 Jul 2000 18:23:51 GMT(响应网站的时间) 


四、简单举例一下部分方法

                url = new URL(strings[0]);
                httpURLConnection = (HttpURLConnection) url.openConnection();

                httpURLConnection.setRequestMethod("GET");
                httpURLConnection.setReadTimeout(5000);
                httpURLConnection.setDoOutput(false);
                httpURLConnection.setDoInput(false);
                httpURLConnection.connect();
                int responseCode = httpURLConnection.getResponseCode();
                int readTimeout = httpURLConnection.getReadTimeout();
                String responseMessage = httpURLConnection.getResponseMessage();
                long date = httpURLConnection.getDate();
                String contentEncoding = httpURLConnection.getContentEncoding();
                arrayList = new ArrayList<String>();
                arrayList.add("responseCode = " + responseCode);
                arrayList.add("readTimeout = " + readTimeout);
                arrayList.add("responseMessage = " + responseMessage);
                arrayList.add("date = " + date);
                arrayList.add("contentEncoding = " + contentEncoding);
//                01-05 21:48:26.248 12592 12592 D result  : responseCode = 200
//                01-05 21:48:26.248 12592 12592 D result  : readTimeout = 5000
//                01-05 21:48:26.248 12592 12592 D result  : responseMessage = OK
//                01-05 21:48:26.249 12592 12592 D result  : date = 1500376608000
//                01-05 21:48:26.249 12592 12592 D result  : contentEncoding = null
if (code == 200) {
                    InputStream is = huc.getInputStream();
                    ByteArrayOutputStream output = new ByteArrayOutputStream();
                    byte[] buffer = new byte[1024];
                    int len = -1;
                    while ((len = is.read(buffer)) != -1) {
                        output.write(buffer, 0, len);
                    }
                    is.close();
                    output.close();
                    text = new String(output.toByteArray(), "utf-8");  //此时可获得百度首页源码信息
                }
01-05 21:56:19.913 13180 13199 D result  : <html><!--STATUS OK--><head><script>var actionSta = 1;if (actionSta === 1) {var startTime = Date.now();} else {var endTime = Date.now();}if (actionSta === 1 || (endTime && (endTime - startTime) > 3000)) {actionSta = actionSta == 1 ? 'start' : 'end';new Image().src = '//hpd.baidu.com/v.gif?tid=365&funcSta=whiteScreenEx&sourceSta=wiseindex&actionSta='+ actionSta + '&logid=1482073863&ssid=0'+ '&ct=1&cst=9&logFrom=mid_news&logInfo=stability';}</script><meta name="referrer" content="always" /><meta charset='utf-8' /><meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/><meta http-equiv="x-dns-prefetch-control" content="on"><link rel="dns-prefetch" href="//m.baidu.com"/><link rel="shortcut icon" href="https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/wiseindex/img/favicon.ico" type="image/x-icon"><link rel="apple-touch-icon-precomposed" href="https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/wiseindex/img/screen_icon.png"/><meta name="format-detection" content="telephone=no"/><noscript><style type="text/css">#page{display:none;}</style><meta http-equiv="refresh" content="0; URL=http://m.baidu.com/index/index.php?from=844b&amp;vit=fps&amp;pu=sz%401321_480&amp;t_noscript=jump" /></noscript><title>百度一下</title><script type="text/javascript">window.οnerrοr=function(m,b,n,l,k){var f="//hpd.baidu.com/v.gif";var c={tid:"259",ct:"1",cst:"9",logFrom:"mid_news",logInfo:"jsException",r:"l"+(Date.now()),logExtra:{rta:"wise"}};var d={};d.message=m||"";d.url=b||"";d.line=n||"";c.logExtra["excep"]=d;try{c.logExtra=JSON.stringify(c.logExtra)}catch(j){}var g="";for(var h in c){if(c.hasOwnProperty(h)){g+="&"+h+"="+encodeURIComponent(c[h])}}var a=f+"?"+g.slice(1);new Image().src=a};;</script><style type="text/css" id='spa-base-style'>#search-card {display: none;}</style><style type="text/css">@font-face {font-family: 'icons';src: url(https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/wiseindex/iconfont/iconfont_9c0cdb21.eot);src: url(https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/wiseindex/iconfont/iconfont_9c0cdb21.eot#iefix) format('embedded-opentype'),url(https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/wiseindex/iconfont/iconfont_11a872b9.woff) format('woff'),url(https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/wiseindex/iconfont/iconfont_0b0a971d.ttf) format('truetype'),url(https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/wiseindex/iconfont/iconfont_b8b3267e.svg#iconfont) format('svg');font-weight: normal;font-style: normal;}i.ns-focus,i.ns-news,i.ns-novel,i.ns-video,i.ns-life,i.ns-map,i.ns-tieba,i.ns-app,i.ns-image,i.ns-website,i.ns-extend,i.ns-music,i.ns-listen {background: url(https://gss0.bdstatic.com/5bd1bjqh_Q23odCf/static/wiseindex/img/ns_diff_color_v2_3d39b4dd.png) no-repeat;background-size: 22px auto;}</style><style type="text/css" class="spa-index-style" data-lsid="plus_css_head">body,h1,h2,h3,p,div,ol,ul,input,button{margin:0;padding:0}body{font-family:Arial, Helvetica, sans-serif;text-align:center;-webkit-text-size-adjust:none;background:#f1f1f1;max-width:100%;overflow-x:hidden}ol,ul{list-style:none}a{text-decoration:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}input,button,textarea{border:0;border-radius:0;background:transparent;-webkit-appearance:none;-webkit-box-sizing:border-box;box-sizing:border-box}button{outline:none}#index-card [class^="icon-"],#index-card [class*=" icon-"],#__SF___mine [class^="icon-"],#__SF___mine [class*=" icon-"],#index-view [class^="icon-"],#index-view [class*=" icon-"]{font-family:icons;font-style:normal;-webkit-font-smoothing:antialiased;-webkit-text-stroke-width:.2px}#__SF___mine .normal-title > i{position:absolute;top:11px;left:-2px;display:none}#__SF___mine .icon-add,#index-view .icon-add{//font-size:24px;color:#B6B7BA;display:inherit;margin:auto}#__SF___mine .icon-add:before{content:'\e888';font:16px/16px icons;color:#999}#__SF___mine .plus-empty .icon-add-empty:before{content:'';position:absolute;top:50%;left:50%;height:1px;width:16px;margin-top:-1px;margin-left:-8px;border-ra


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值