1.4(学习笔记)请求头及响应头

一、请求报文 

  客户端在向服务器发送数据时,不仅有一些显式的数据(用户名、密码等),

  还需要传递一些隐式的数据,例如是否缓冲、是否长连接、报文长度等信息。

  请求报文就包含这些隐式和显式的信息。

   

  请求报文结构:

  1.请求行:主要包括请求方式(如POST、GET等),请求对应的URL与请求头字段HOST中的属性组成完整的请求URL。

  2.请求头:是HTTP的报文头,报文头包含若干属性,由键值对组成。

  3.请求体:是报文体,将页面中提交的相关信息以键值对的方式组合成一个字符串。

  (例如username=111&pwd=1234&sex=0&like=1)

  

  请求报文样例:

  

  

  

   

 

  获取请求头信息的方法:

  javax.servlet.http.HttpServletRequest.getHeaderNames()

  获取所有头部字段名。

  javax.servlet.http.HttpServletRequest.getHeader(String name)

  以字符串形式返回指定的请求头字段(name)的值。

  

<!DOCTYPE html>
<!-- http://localhost:8080/TestServlet/Test.html -->
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <!--表单提交调用servlet  -->
    <!-- http://localhost:8080/TestServlet/TestServlet.html -->
    <form name = f1 action = "/TestServlet/TestServlet.html" method = "get">
        username:<input type = "text" name = "username"></input><br>
        pwd:<input type = "password" name = "pwd"></input><br>
        性别:<input type = "radio" name = "sex" value = "0"><input type = "radio" name = "sex" value = "1"><br>
        爱好:<input type = "checkbox" name = "like" value = "1">篮球
            <input type = "checkbox" name = "like" value = "2">足球<br>
        <input type = "submit" value = "提交">
    </form>
    
</body>
</html>
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

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

public class TestServlet extends HttpServlet{
//    private PrintStream out = System.out;
    private String initParam = null;
    private String contextParam = null;
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter out = resp.getWriter();
        //获取所有头部字段名
        Enumeration headNames = req.getHeaderNames();
        //打印html头部代码
        printHtmlPage(out,true);
        //绘制html表格显示获取参数
        out.println("<table border = 2>");
        //遍历包含所有头部字段的枚举对象
        while(headNames.hasMoreElements()) {//判断是否有更多元素
            String headName = (String)headNames.nextElement();//获取当前枚举参数。
            //根据当前头部字段获取对应值
            String values = req.getHeader(headName);
            //输出头部字段
            out.println("<tr>");
            out.print("<td>");
            out.print(headName);
            out.print("</td>");
            
            //输出头部字段所对应的值
            out.print("<td>");
            out.print(values);
            out.print("</td>");
            out.println("</tr>");
        }
        out.println("</table>");
        //打印html尾部代码
        printHtmlPage(out,false);
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
    
    //打印HTML页面,head为True打印HTML头部代码,为false打印尾部HTML代码
    private void printHtmlPage(PrintWriter out, boolean head) {
        if(head) {
            out.println("<!DOCTYPE html>\r\n" + 
                    "<!-- http://localhost:8080/TestServlet/Test.html -->\r\n" + 
                    "<html>\r\n" + 
                    "<head>\r\n" + 
                    "<meta charset=\"UTF-8\">\r\n" + 
                    "<title>Insert title here</title>\r\n" + 
                    "</head>\r\n" + 
                    "<body>");
        }else {
            out.println("</body>\r\n" + 
                    "</html>");
        }
    }
}

host:请求的目标域名和端口号
connection:表示是否需要持久连接。(HTTP 1.1默认进行持久连接)
content-length:报文中实体主体的大小。
cache-control:缓存策略。
Origin:请求的来源域名和端口号 (跨域请求时,浏览器会自动带上这个头信息)。
upgrade-insecure-requests:让浏览器升级请求从http到https。
content-type:互联网媒体类型;也叫做MIME类型,在Http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息。

  常见媒体类型:
  text/html : HTML格式
  text/plain :纯文本格式
  text/xml : XML格式
  image/gif :gif图片格式
  image/jpeg :jpg图片格式
  image/png:png图片格式

  application/xhtml+xml :XHTML格式
  application/xml : XML数据格式
  application/atom+xml :Atom XML聚合格式
  application/json : JSON数据格式
  application/pdf :pdf格式
  application/msword : Word文档格式
  application/octet-stream : 二进制流数据(如常见的文件下载)
  application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)


user-agent:浏览器信息。
accept:代表客户端希望接收的数据类型。
referer:请求资源的完整URL。
accept-encoding:请求的 HTTP 标头通告其内容编码,通常是一个压缩算法。
accept-language:请求头允许客户端声明它可以理解的自然语言,以及语言的权重(q=0.9),权重即高即越希望选择该语言。

关于头字段对应含义可参阅:https://en.wikipedia.org/wiki/List_of_HTTP_header_fields

 

二、响应报文

  响应报文结构:

  响应行:包含报文协议、版本、状态码、状态描述。(HTTP/1.1 200 OK)

  响应头:报文头包含若干属性,由键值对组成(向客户端发送的数据类型、刷新时间等),与请求头类型。

  响应体:响应体主要就是我们需要的正文信息。

   

  

    响应头对应的属性和含义可参阅:https://www.cnblogs.com/wangyang108/p/5755525.html

  

  实际中可以根据需求设置一些响应头信息,已满足某些需求。

  设置响应头信息方法:

  void javax.servlet.http.HttpServletResponse.setHeader(String name, String value)

  //设置对应头部字段名的值

  void javax.servlet.ServletResponse.setContentType(String type)

       //设置发送到客户端的响应的内容类型

  还有其他对应属性的setXXX方法,可参阅API.

 

  下面来看几个小例子。

  2.1设置发送到客户端的内容为Excel表格。

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;

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

public class TestResponseInfomation extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        //设置响应消息为Excel格式
     resp.setContentType("application/vnd.ms-excel"); PrintWriter out = resp.getWriter();
     //设置Excle内容 out.println(
"\tQ1\tQ2\tQ3\tQ4\tTotal"); out.println("Apple\t78\t87\t99\t12\t=SUM(B2:D2)"); out.println("orange\t8\t8\t9\t2\t=SUM(B2:D2)"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doGet(req, resp); } }
 <servlet-mapping>
      <servlet-name>testResponse</servlet-name>
      <url-pattern>/TestResponse.xls</url-pattern>
  </servlet-mapping>

 

使用Chrome浏览器测试时,最好将Servlet-Mapping最后部分为XXX.xls。

IE,Edge则没有此限制,。

 

  

   2.2设置发送到客户端的内容为图片。

  

import java.io.FileInputStream;
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 TestResponseInfomation extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        int len = -1;//设置写入字节数
        resp.setContentType(" image/jpeg");//设置内容为图片jpg格式
        InputStream is = new FileInputStream("F:\\依风\\Pictures\\下载图片\\bg.jpg");
        //获取response的输出流
        OutputStream os = resp.getOutputStream();
        byte[] buff = new byte[1024];
        while((len = is.read(buff)) != -1) {
            os.write(buff,0,len);
        }
        os.flush();
        os.close();
        is.close();
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doGet(req, resp);
    }
}

 

  2.3设置刷新时间。

  例如在响应界面中输出当前时间,每秒刷新一次。(实际中不建议这样每秒刷新一次,比较占用服务器资源)

  这样界面上的时间就不不停增加,呈现出一种动态的效果。

  

import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

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

public class TestResponseInfomation extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        resp.setHeader("Refresh", "1");
        PrintWriter out = resp.getWriter();
        printHtmlPage(out,true);
        DateFormat df = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
        out.print("<h1>" + df.format(new Date(System.currentTimeMillis())) + "</h1>");
        printHtmlPage(out,false);
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doGet(req, resp);
    }
    
    //打印HTML页面,head为True打印HTML头部代码,为false打印尾部HTML代码
        private void printHtmlPage(PrintWriter out, boolean head) {
            if(head) {
                out.println("<!DOCTYPE html>\r\n" + 
                        "<!-- http://localhost:8080/TestServlet/Test.html -->\r\n" + 
                        "<html>\r\n" + 
                        "<head>\r\n" + 
                        "<meta charset=\"UTF-8\">\r\n" + 
                        "<title>Insert title here</title>\r\n" + 
                        "</head>\r\n" + 
                        "<body>");
            }else {
                out.println("</body>\r\n" + 
                        "</html>");
            }
        }
}

浏览器每过一秒会刷新一次,从Servlet获取新的时间输出到界面上,这样比较浪费服务器资源,

平常不建议使用

 

参考资料:https://blog.csdn.net/u010256388/article/details/68491509/

     http://www.runoob.com/http/http-messages.html

     https://www.jb51.net/web/406676.html

posted @ 2019-01-24 14:34  gcmh  阅读(670)  评论(0编辑  收藏  举报