• 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>
    " + 
                        "<!-- http://localhost:8080/TestServlet/Test.html -->
    " + 
                        "<html>
    " + 
                        "<head>
    " + 
                        "<meta charset="UTF-8">
    " + 
                        "<title>Insert title here</title>
    " + 
                        "</head>
    " + 
                        "<body>");
            }else {
                out.println("</body>
    " + 
                        "</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(
    " Q1 Q2 Q3 Q4 Total"); out.println("Apple 78 87 99 12 =SUM(B2:D2)"); out.println("orange 8 8 9 2 =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>
    " + 
                            "<!-- http://localhost:8080/TestServlet/Test.html -->
    " + 
                            "<html>
    " + 
                            "<head>
    " + 
                            "<meta charset="UTF-8">
    " + 
                            "<title>Insert title here</title>
    " + 
                            "</head>
    " + 
                            "<body>");
                }else {
                    out.println("</body>
    " + 
                            "</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

  • 相关阅读:
    spring四种依赖注入方式
    java利用反射来调用一个类的私有方法
    IOC和AOP的基本概念
    开业大吉
    1752年9月奇怪的日历
    找到一个软件测试的学习网址,保留一下
    学习任务
    操作系统的第一次作业
    答题
    第四章读后感
  • 原文地址:https://www.cnblogs.com/huang-changfan/p/10293074.html
Copyright © 2020-2023  润新知