Introduction to This Section:

In the previous section, we learned about network programming in Android and also studied the basic concepts of HTTP. In this section, we will learn about HTTP request headers and response headers. Of course, you can also treat this section as a document and look it up when needed.


1. HTTP Request Message Headers:

Here is the figure from the previous section. Based on the table given below, you can get a feel for the functions of the relevant request headers. PS: The first line is the request line: request method + resource name + HTTP protocol version number. In addition, the request headers only provide information to the server, and it is up to the server to decide how to handle it.


HTTP Request Header Reference Table:

Header Explanation Example
Accept Specifies the content types the client can accept Accept: text/plain, text/html
Accept-Charset The character encoding sets the browser can accept. Accept-Charset: iso-8859-5
Accept-Encoding Specifies the compression encoding types for web server returned content that the browser can support. Accept-Encoding: compress, gzip
Accept-Language Languages the browser can accept Accept-Language: en,zh
Accept-Ranges Can request one or more sub-ranges of a web page entity Accept-Ranges: bytes
Authorization Authorization certificate for HTTP authorization Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Cache-Control Specifies the caching mechanism that requests and responses follow Cache-Control: no-cache
Connection Indicates whether a persistent connection is required. (HTTP 1.1 uses persistent connections by default) Connection: close
Cookie When an HTTP request is sent, all cookie values stored under the requested domain name are sent to the web server along with the request. Cookie: $Version=1; Skin=new;
Content-Length Length of the request content Content-Length: 348
Content-Type MIME information corresponding to the request entity Content-Type: application/x-www-form-urlencoded
Date Date and time the request was sent Date: Tue, 15 Nov 2010 08:12:31 GMT
Expect Specific server behavior requested Expect: 100-continue
From Email of the user making the request From: user@email.com
Host Specifies the domain name and port number of the requested server Host: www.zcmhi.com
If-Match Only valid if the request content matches the entity If-Match: "737060cd8c284d8af7ad3082f209582d"
If-Modified-Since The request succeeds only if the requested part has been modified after the specified time; if not modified, a 304 code is returned If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT
If-None-Match Returns a 304 code if the content has not changed. The parameter is the Etag previously sent by the server, compared with the server's returned Etag to determine whether it has changed If-None-Match: "737060cd8c284d8af7ad3082f209582d"
If-Range If the entity has not changed, the server sends the part the client lost; otherwise, it sends the entire entity. The parameter is also Etag If-Range: "737060cd8c284d8af7ad3082f209582d"
If-Unmodified-Since The request succeeds only if the entity has not been modified after the specified time If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT
Max-Forwards Limits the time information is transmitted through proxies and gateways Max-Forwards: 10
Pragma Used to include implementation-specific directives Pragma: no-cache
Proxy-Authorization Authorization certificate for connecting to a proxy Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Range Request only a part of the entity, specifying the range Range: bytes=500-999
Referer The address of the previous webpage, which the current request follows; that is, the referrer Referer: http://blog.csdn.net/coder_pig
TE The transfer encodings the client is willing to accept, and notifies the server to accept trailing header information TE: trailers,deflate;q=0.5
Upgrade Specifies a certain transfer protocol to the server so that the server can convert (if supported) Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
User-Agent The content of User-Agent contains user information about the requester User-Agent: Mozilla/5.0 (Linux; X11)
Via Notifies the intermediate gateway or proxy server of the address and communication protocol Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
Warning Warning information about the message entity Warn: 199 Miscellaneous warning

2. HTTP Response Headers:

Here is the figure from the previous section. PS: The first line is, in order: protocol version, status code. 302 means it is not here, but it is in another place, and the page is redirected via the Location header.

HTTP Response Header Reference Table:

Header Explanation Example
Accept-Ranges Indicates whether the server supports the specified range request and which type of partial request Accept-Ranges: bytes
Age Estimated time from the origin server to the proxy cache (in seconds, non-negative) Age: 12
Allow Valid request behavior for a certain network resource; if not allowed, returns 405 Allow: GET, HEAD
Cache-Control Tells all caching mechanisms whether caching is allowed and which type Cache-Control: no-cache
Content-Encoding Compression encoding types supported by the web server for returned content Content-Encoding: gzip
Content-Language Language of the response body Content-Language: en,zh
Content-Length Length of the response body Content-Length: 348
Content-Location Alternative address for the requested resource Content-Location: /index.htm
Content-MD5 MD5 checksum of the returned resource Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==
Content-Range Byte position of this part within the entire response body Content-Range: bytes 21010-47021/47022
Content-Type MIME type of the returned content Content-Type: text/html; charset=utf-8
Date Time the origin server sent the message Date: Tue, 15 Nov 2010 08:12:31 GMT
ETag Current value of the entity tag for the request variable ETag: "737060cd8c284d8af7ad3082f209582d"
Expires Date and time the response expires Expires: Thu, 01 Dec 2010 16:00:00 GMT
Last-Modified Last modification time of the requested resource Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT
Location Used to redirect the recipient to a non-requested URL to complete the request or identify a new resource Location: http://blog.csdn.net/coder_pig
Pragma Contains implementation-specific directives that may apply to any recipient in the response chain Pragma: no-cache
Proxy-Authenticate It indicates the authentication scheme and parameters applicable to the proxy for this URL Proxy-Authenticate: Basic

3. Verifying the Role of Response Headers with Code:

Okay, after reading so many conceptual things, how can we not get our hands dirty? Right? So let's write some simple code to verify the functions of some common response headers, so as to deepen our understanding. Here, the server side will be implemented with the simplest Servlet. If you don't know Java Web, just copy the code, configure web.xml, and fill in the Servlet class name, for example:

<servlet>
    <servlet-name>FirstServlet</servlet-name>
    <servlet-class>com.jay.server.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>FirstServlet</servlet-name>
    <url-pattern>/FirstServlet</url-pattern>
</servlet-mapping>

Just change it to the corresponding class name!


1) Implement page redirection via Location

Implementation code:

package com.jay.http.test;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletOne extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        //告诉浏览器响应码,以及重定向页面
        resp.setStatus(302);
        resp.setHeader("Location", "http://www.baidu.com");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

Running result:

When we visit http://localhost:8080/HttpTest/ServletOne, we will find that the page redirects to Baidu. Then, using FireFox's developer tools, we can see the HTTP content we sent:


2) Tell the browser the data compression format via Content-Encoding

Implementation code:

package com.jay.http.test;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletTwo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        String data = "Fresh air and sunshine can have an amazing effect on our feelings. "
                + "Sometimes when we are feeling down, all that we need to do is simply to go "
                + "outside and breathe. Movement and exercise is also a fantastic way to feel better. "
                + "Positive emotions can be generated by motion. So if we start to feel down,"
                + " take some deep breathes, go outside, feel the fresh air, "
                + "let the sun hit our face, go for a hike, a walk, a bike ride, "
                + "a swim, a run, whatever. We will feel better if we do this.";
        System.out.println("原始数据长度:" + data.getBytes().length);
        // 对数据进行压缩:
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        GZIPOutputStream gout = new GZIPOutputStream(bout);
        gout.write(data.getBytes());
        gout.close();
        // 得到压缩后的数据
        byte gdata[] = bout.toByteArray();
        resp.setHeader("Content-Encoding", "gzip");
        resp.setHeader("Content-Length", gdata.length + "");
        resp.getOutputStream().write(gdata);

    }
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        doGet(req, resp);
    };
}

Running result:

Console output:

Browser output:

Let's take a look at our HTTP content:

ThisgzipCompressing strings is not efficient for simple strings. For example, the author originally wrote a string of a "Quiet Night Thought" poem, but later found that the compressed size was actually larger than the original = - =...


3) Set the returned data type via content-type

The server may sometimes return text/html, sometimes image/jpeg, or a video like video/avi. The browser can display the data in different ways according to the corresponding data type! Okay, here we will make one that reads a PDF.

Implementation code:

package com.jay.http.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletThree extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setHeader("content-type", "application/pdf");
        InputStream in = this.getServletContext().getResourceAsStream("/file/android编码规范.pdf");
        byte buffer[] = new byte[1024];
        int len = 0;
        OutputStream out = resp.getOutputStream();
        while((len = in.read(buffer)) > 0)
        {
            out.write(buffer,0,len);
        }
    }
    
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws
       ServletException ,IOException 
    {
        doGet(req, resp);
    };
}

Running result:

Enter http://localhost:8080/HttpTest/ServletThree in the browser

Great, we can indeed read the PDF. By the way, I have placed this PDF in the file directory under webroot, otherwise it will throw a null pointer exception~:

Of course, you can also try playing a piece of music or video; you just need to modify the content-type parameter.

Here is also a quick reference table for HTTP Content-type:HTTP Content-type Reference Table


4) Use the refresh response header to make the browser jump to another page after a few seconds

Yes, we may often have such requirements, such as refreshing a page every few seconds, or jumping to another page a few seconds after loading a page. Then refresh can meet your needs~

Implementation code:

package com.jay.http.test;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletFour extends HttpServlet {
    public int second = 0;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        //1.浏览器每隔2秒定时刷新页面
//        resp.setHeader("refresh", "2");
//        resp.getWriter().write(++second + "");
//        System.out.println("doGet方法被调用~");
        
        //2.进入页面5s后,然页跳到百度~
        resp.setHeader("refresh", "5;url='http://www.baidu.com'");
        resp.getWriter().write("HE HE DA~");
    }
    
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException ,IOException 
    {
        doGet(req, resp);
    };
}

Running result:

  • 1) The page refreshes every 2 seconds. We can see that the displayed number is incrementing, and the doGet method is also being called continuously, which shows that the page is indeed refreshing!
  • 2) After entering the page, after 5 seconds, it automatically jumps to Baidu~

5) Use the content-disposition response header to make the browser download a file

This is very simple. We just need to remove the line that sets Content-type in ③ and add: resp.setHeader("content-disposition", "attachment;filename=Android.pdf");

Implementation code:

package com.jay.http.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletFive extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setHeader("content-disposition", "attachment;filename=Android.pdf");
        InputStream in = this.getServletContext().getResourceAsStream("/file/android编码规范.pdf");
        byte buffer[] = new byte[1024];
        int len = 0;
        OutputStream out = resp.getOutputStream();
        while((len = in.read(buffer)) > 0)
        {
            out.write(buffer,0,len);
        }
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        doGet(req, resp);
    }
}

Running result:


Summary of This Section:

This section introduced the request headers and response headers in HTTP, and also provided a few examples of using response headers to adjust the browser. After this chapter, I believe you have a better understanding of the HTTP protocol. In the next section, we will learn the HTTP request method provided by Android: HttpURLConnection! Alright, that's all for this section, thanks~ Oh, by the way, download the demo for this section:Download HttpTest.zip