Servlet与HTTP请求协议

Posted 超霸霸

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Servlet与HTTP请求协议相关的知识,希望对你有一定的参考价值。

Servlet与HTTP请求协议

一、相关概念

  • Servlet的体系结构:

    • Servlet(接口)–> GenericServlet(抽象类)–> HttpServlet(抽象类)

    • GenericServlet:将Servlet接口其他的方法做了默认空实现,只将service()方法作为抽象,将来定义Servlet类时,可以继承GenericServlet,实现service()方法即可

    • HttpServlet:对http协议的一种封装,简化操作

      • 定义类继承HttpServlet
      • 复写doGet/doPost方法
  • Servlet相关配置:

    • urlpatternServlet访问路径

    • 一个Servlet可以定义多个访问路径:@webServlet({"/d4","/dd4","/ddd4"})

    • 路径定义规则:

      1. /xxx :路径匹配
      2. /xxx/xxx :多层路径,目录结构
      3. *.do:扩展名匹配
  • HTTP

    • 概念:Hyper Text Transfer Protocol 超文本传输协议
    • 传输协议:定义客户端和服务器端通信时发送数据的格式
    • 特点:
      • 基于TCP/IP的高级协议
      • 默认端口号:80
      • 基于请求/响应模型:一次请求对应一次响应
      • 无状态:每次请求之间互相独立,不能交互数据
    • 历史版本:
      • 1.0:每次请求响应都会建立新的连接
      • 1.1:复用连接,一次连接可进行多次请求响应
  • 请求消息数据格式:

    • 请求行

      GET /login.html HTTP/1.1
      请求方式  请求url  请求协议/版本
      
      • 请求方式:HTTP中有7种请求方式,常用的有2种
        • GET
          1. 请求参数在请求行中,url后
          2. 请求的url长度有限制
          3. 不太安全
        • POST
          1. 请求参数在请求体中
          2. 请求的url长度没有限制
          3. 相对安全
    • 请求头

      • 客户端浏览器告诉服务器一些信息
      • 请求头名称:请求头值
      • 常见的请求头:
        • User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息,可以在服务器端获取该头的信息,解决浏览器的兼容性问题
        • Referer:告诉服务器当前请求从哪里来,作用:防盗链和统计
      HOST: localhost
      User-Agent: Mozilla/5.0 (Windows NT 6.1;Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
      Accept: text/html,appliaction/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
      Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
      Accept-Encoding: gzip, deflate
      Connection: keep-alive
      Upgrade-Insecure-Requests: 1
      
    • 请求空行

      • 空行,用于分割POST请求的请求头和请求体
    • 请求体(正文)

      • 存放参数,封装POST请求消息的请求参数,GET方式没有请求体
      username="zhangsan"
      password=123456
      

二、Request

  • request对象和response对象的原理:

    • requestresponse对象是由服务器创建的,我们来使用它们
    • request对象是用来获取请求消息,response对象是用来设置相应消息
  • request对象继承体系结构:

    • ServletRequest(接口)–> HttpServletRequest(接口)–> Tomcat(实现)
  • request功能:

    • 获取请求消息数据

      • 获取请求行数据

        1. 获取请求方式:GET
          String getMethod()
        2. 获取虚拟目录:/day14
          String getContextPath()
        3. 获取Servlet路径:/demo01
          String getServletPath()
        4. 获取GET方式请求参数:name=zhangsan
          String getQueryString()
      1. 获取请求URI:/day14/demo01
        String getRequestURI()/day14/demo01(URI,统一资源定位符)
        StringBuffer getRequestURL():http://localhost/day14/demo01(URL,统一资源标识符)
      2. 获取协议及版本:HTTP/1.1
        String getProtocol()
      3. 获取客户机的IP地址:10.159.00.8
        String getRemoteAddr()
    package cn.chao.web.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebServlet("/demo5")
    public class ServletDemo5 extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        }
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1.获取请求方法
            String method = request.getMethod();
            System.out.println(method);
            //2.获取虚拟目录
            String contextPath = request.getContextPath();
            System.out.println(contextPath);
            //3.获取Servlet路径
            String servletPath = request.getServletPath();
            System.out.println(servletPath);
            //4.获取请求参数
            String queryString = request.getQueryString();
            System.out.println(queryString);
            //5.获取URI和URL
            String requestURI = request.getRequestURI();
            StringBuffer requestURL = request.getRequestURL();
            System.out.println(requestURI);
            System.out.println(requestURL);
            //6.获取协议及版本
            String protocol = request.getProtocol();
            System.out.println(protocol);
            //7.获取客户端IP地址
            String remoteAddr = request.getRemoteAddr();
            System.out.println(remoteAddr);
        }
    }
    

    在网址中输入:

    http://localhost:8080/demo5?username=zhangsan
    

    输出:

    GET
    
    /demo5
    username=zhangsan
    /demo5
    http://localhost:8080/demo5
    HTTP/1.1
    0:0:0:0:0:0:0:1
    
    • 获取请求头数据
      • String getHeader(String name):通过请求头的名称获取请求头的值
      • Enumeration<String> getHeaderNames:获取所有的请求头名称
    package cn.chao.web.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.Enumeration;
    
    @WebServlet("/demo5")
    public class ServletDemo5 extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        }
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String agent = request.getHeader("user-agent");
    
            if (agent.contains("Chrome")) {
                System.out.println("谷歌来了");
            } else if (agent.contains("Firefox")) {
                System.out.println("火狐来了");
            } else if (agent.contains("Edge")) {
                System.out.println("Edge来了");
            } else {
                System.out.println("其他浏览器来了");
            }
        }
    }
    

    使用谷歌浏览器,在网址中输入:

    http://localhost:8080/demo5
    

    输出:

    谷歌来了
    
    package cn.chao.web.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.Enumeration;
    
    @WebServlet("/demo5")
    public class ServletDemo5 extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        }
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //演示获取请求头数据
            
            //1.获取所有请求头名称
            Enumeration<String> headerNames = request.getHeaderNames();
            //2.遍历
            while (headerNames.hasMoreElements()) 
                String name = headerNames.nextElement();
            	//根据名称获取请求头的值
                String value = request.getHeader(name);
                System.out.println(name + "---" + value);
            }
        }
    }
    

    在网址中输入:

    http://localhost:8080/TomcatStudy02_war_exploded/demo5
    

    输出:

    host---localhost:8080
    connection---keep-alive
    upgrade-insecure-requests---1
    user-agent---Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.8031 SLBChan/25
    accept---text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    sec-fetch-site---none
    sec-fetch-mode---navigate
    sec-fetch-user---?1
    sec-fetch-dest---document
    accept-encoding---gzip, deflate, br
    accept-language---zh-CN,zh;q=0.9
    cookie---JSESSIONID=4124D21F1230D29F5A04EA5E86994D93
    
    package cn.chao.web.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.Enumeration;
    
    @WebServlet("/demo5")
    public class ServletDemo5 extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        }
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //演示获取请求头数据:referer
            String referer = request.getHeader("referer");
            System.out.println(referer);
            
            //防盗链
            if (referer != null) {
                if (referer.contains("TomcatStudy02_war_exploded")) {
                    //正常访问
                    System.out.println("播放电影");
                } else {
                    //盗链
                    System.out.println("想看电影吗,来b站!");
                }
            }
        }
    }
    

    login.html中写一个超链接:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <a href="/TomcatStudy02_war_exploded/demo5">demo5</a>
    </body>
    </html>
    

    在网址中输入:

    http://localhost:8080/TomcatStudy02_war_exploded/login.html
    

    点击网页的超链接,输出:

    http://localhost:8080/TomcatStudy02_war_exploded/login.html
    
    • 获取请求体数据(只有POST请求方法才有请求体)

      • 步骤:
        1. 获取流对象
          • BufferedReader getReader():获取字符输入流,只能操作字符数据
          • ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
        2. 从流对象中拿数据
    package cn.chao.web.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.util.Enumeration;
    
    @WebServlet("/demo5")
    public class ServletDemo5 extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            BufferedReader br = request.getReader();
    
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        }
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        }
    }
    

    写一个登录界面(regist.html) :

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="/demo5" method="post">
        <input type="text" placeholder="请输入用户名" name="username"><br>
        <input type="text" placeholder="请输入密码" name="password"><br>
        <input type="submit" value="注册">
    </form>
    </body>
    </html>
    

    在网址中输入:

    http://localhost:8080/regist.html
    

    填入信息,输出:

    username=zhangsan&password=123
    
    • 其他功能:

      • 获取请求参数通用方式:不论是get还是post请求方法都可以使用下列方法来获取请求参数

        • String getParameter(String name):根据参数名名称获取参数值
        • String[] getParameterValues(String name):根据参数名称 获取参数值的数组
        • Enumeration<String> getParameterNames():获取所有请求的参数名称
        • Map<String,String[]> getParameterMap():获取所有参数的map集合
        package cn.chao.web.servlet;
        
        import javax.servlet.ServletException;
        import javax.servlet.annotation.WebServlet;
        import javax.servlet.http.HttpServlet;
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        import java.io.IOException;
        import java.util.Enumeration;
        import java.util.Map;
        import java.util.Set;
        
        @WebServlet("/demo5")
        public class ServletDemo5 extends HttpServlet {
            @Override
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                //post获取请求参数
        
                //根据参数名称获取参数值
                String username = request.getParameter("username");
                System.out.println("post");
                System.out.println(username);
                System.out.println();
        
                //根据参数名称获取参数值的数组
                String[] hobbies = request.getParameterValues("hobby");
                for (String hobby : hobbies) {
                    System.out.println(hobby);
                }
                Servlet与HTTP请求协议

        Servlet与HTTP请求协议

        servlet和filter的区别

        servlet,过滤器,监听器,拦截器的区别

        Servlet --- [HTTP协议,HTTP请求]

        servlet,filter,listener,intercepter区别