Servlet(二)【HTTP协议、Request对象介绍、请求乱码处理】

前 言

人总是要有梦想的,也许哪天就实现了呢!

如果有不正确之处,还望赐教,毕竟我只是初学者!


一、Servelt 其他实现方式

前面我们是通过实现Servlet接口来创建Servlet的,现在我们通过继承Servlet的实现类HttpPServlet来创建我们的Servlet。

@WebServlet(value = "/show")
public class ServletDemo2 extends HttpServlet {

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println("post" + username + "," + password);
    }
}

二、HTTP 协议

1、概 述

HTTP协议(Hyper Text Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。HTTP是一个基于TCP/IP通信协议来传递数据的应用层协议。


2、HTTP 特点

  1. HTTP是无状态的:每次请求之间相互独立,不能进行数据交互
  2. HTTP协议默认端口号为80
  3. HTTP是无连接的:每次连接只处理一个请求,服务器处理完客户的请求,并收到客户的应答后,即断开连接

3、HTTP 版本介绍

  1. 1.0版本:在该版本中,每完成一次请求/响应就断开连接。其特点是简单、易于管理。
  2. 1.1版本:由于1.0版本每次连接只能完成一次请求/响应,这样会导致效率低下。在该版本中,允许一个连接可以进行多次请求/响应。
  3. 2.0版本:在该版本中,效率更快。

4、HTTP 请求消息结构

  1. 请求行:请求行中包括URL、请求协议、协议版本号、请求方式
    在这里插入图片描述

  2. 请求头:请求头中包括浏览器告诉服务器的一些信息

    请求头中通常包含User-Agent和Referer
    在这里插入图片描述
    User-Agent:告诉服务器,访问网页时浏览器的版本信息

    扫描二维码关注公众号,回复: 9975113 查看本文章

    Referer:告诉服务器,当前请求是从哪里发送来的


  3. 请求空行:用于分割POST请求的请求头和请求体的

  4. 请求体:封装POST请求信息的请求参数的
    在这里插入图片描述

5、请求方式

请求方式有七种,常用的就只有GET和POST两种请求方式

  1. GET:GET方式发出的请求,请求参数在请求行中,在URL后面,GET方式请求的URL长度有限,并且数据不安全,通常用来获取数据。
  2. POST:POST方式发出的请求,请求参数在请求体中,请求的URL也没有长度限制,相对于GET来说,数据安全,一般用来提交表单数据。

三、Request 对象

1、概 述

Request对象是请求对象,通过该对象可以获取请求信息。Request对象是由Tomcat创建的,我们直接使用就行。


2、获取请求行数据

  1. 方法介绍:

    1. String getMethod() - 获取请求方式   
    2. String getContextPath() - 获取虚拟目录(☆)
    3. String getServletPath() - 获取Servlet路径
    4. String getQueryString() - 获取get方式请求参数
    5. String getRequestURI() - 获取请求URI(☆)
    6. StringBuffer getRequestURL() - 获取请求URL
    7. String getProtocol() - 获取协议及版本
    8. String getRemoteAddr() - 获取客户机的IP地址 
    

  2. 代码示例:

    @WebServlet(value = "/method.test")
    public class ServletDemo5 extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            System.out.println("请求方法:" + req.getMethod());
            System.out.println("虚拟目录:" + req.getContextPath());
            System.out.println("Servlet路径:" + req.getServletPath());
            System.out.println("get方式请求参数:" + req.getQueryString());
            System.out.println("URI:" + req.getRequestURI());
            System.out.println("URL:" + req.getRequestURL());
            System.out.println("协议版本:" + req.getProtocol());
            System.out.println("IP地址:" + req.getRemoteAddr());
        }
    }
    

2、获取请求头数据

  1. 方法介绍:

    1. String getHeader(String name) - 通过请求头的名称获取请求头的值
    2. Enumeration<String> getHeaderNames() - 获取所有的请求头名称
    
  2. 代码示例:

    @WebServlet(value = "/head.test")
    public class ServletDemo6 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            System.out.println("User-Agent:" + req.getHeader("user-agent"));
            System.out.println("Referer:" + req.getHeader("referer"));
            System.out.println("Host:" + req.getHeader("host"));
            Enumeration<String> headerNames = req.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                System.out.println(headerNames.nextElement());
            }
        }
    }
    

3、获取请求体数据

请求体只存在于通过POST请求方法,请求体中封装了POST请求的请求参数,获取其中的数据,需要先获取流对象,然后通过流对象去读取封装的数据。

  1. 方法介绍:

    1. BufferedReader getReader() - 获取字符输入流,只能操作字符数据
    2. ServletInputStream getInputStream() - 获取字节输入流,可以操作所有类型数据
    

  2. 代码示例及运行结果:
    在这里插入图片描述

4、其他功能

  1. 获取请求参数的通用方式:不管是get请求还是post请求都适用

    1. 方法介绍:

      1. String getParameter(String name) - 根据参数名称获取参数值
      2. String[] getParameterValues(String name) - 根据参数名称获取参数值的数组,用于获取复选框的值
      3. Map<String,String[]> getParameterMap() - 获取所有参数的map集合
      
    2. 代码示例:

      @WebServlet(value = "/show.do")
      public class ServletDemo8 extends HttpServlet {
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                  throws ServletException, IOException {
              String username = req.getParameter("username");
              String[] hobbies = req.getParameterValues("hobby");
              Map<String, String[]> parms = req.getParameterMap();
              System.out.println(username);
              for (String hobby : hobbies) {
                  System.out.println(hobby);
              }
              Set<Map.Entry<String, String[]>> entries = parms.entrySet();
              for(Map.Entry<String, String[]> entry : entries) {
                  System.out.println(entry);
              }
          }
      }
      
      show.html
      <form action="/servlet/show.do" method="post">
          <input type="text" name="username"><br>
          <input type="text" name="password"><br>
          <input type="checkbox" name="hobby">看书
          <input type="checkbox" name="hobby">敲代码
          <input type="submit" value="提交">
      </form>    
      

  2. 请求转发:请求转发是一种在服务器内部发生的资源跳转,但这仍是一次请求。举例:你现在去办事窗口盖章,你去了1号窗口,但是1号窗口不能给你办理,需要去3号窗口办理,此时1号业务员就去了3号窗口替你办好了,然后将文件给你,在这过程中,你只在1号窗口发起了请求,但是却转发到了3号窗口,但是你并不知道内部有什么操作,这就是请求转发。

    1. 特点:

      1. 请求转发是一次请求;
      2. 浏览器地址栏不发生改变;
      3. 只能转发到服务器内部资源中,不能指定网络资源;
    2. 方法:

      1. RequestDispatcher getRequestDispatcher(String path) - 通过request对象获取请求转发器对象
      2. forward(ServletRequest request, ServletResponse response) - 使用RequestDispatcher对象来进行转发
      
    3. 使用场景:用户注册完成后,完成自动登录。用户登录成功后跳转至主页面。

    4. 代码示例:

      /*
      * 将请求转发给ServletDemo8
      */
      @WebServlet(value = "/forward.do")
      public class ServletDemo9 extends HttpServlet {
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                  throws ServletException, IOException {
              req.getRequestDispatcher("/show.do").forward(req, resp);
          }
      }
      

  3. 共享数据:

    1. 概述:共享数据指的是在同一个作用范围内可以数据共享。即在一次请求的范围内,可以在请求转发的多个资源之间共享数据,我们称之为Request域。注意,数据共享只能存在于一次请求中,多个请求之间不能使用共享数据。

    2. 方法介绍:

      1. void setAttribute(String name,Object obj) - 存储数据
      2. Object getAttitude(String name) - 通过键获取值
      3. void removeAttribute(String name) - 通过键移除键值对
      
    3. 代码示例:

      @WebServlet(value = "/forward.do")
      public class ServletDemo9 extends HttpServlet {
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                  throws ServletException, IOException {
              req.setAttribute("name", "张三");
              req.getRequestDispatcher("/request.do").forward(req, resp);
          }
      }
      
      @WebServlet(value = "/request.do")
      public class ServletDemo10 extends HttpServlet {
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                  throws ServletException, IOException {
              String name = (String) req.getAttribute("name");
              System.out.println("name:" + name);
          }
      }
      

5、乱码处理

  1. 为什么出现乱码问题:当浏览器和服务器的字符编码不同时,就会出现乱码问题。

  2. 注意:在Tomcat 8及以上,get方式的乱码问题已经被解决了,post方式的请求乱码需要我们自己解决。也就是说,我们解决的是post的请求乱码问题。

  3. 方法介绍:setCharacterEncoding("字符编码集") - 在获取参数前设置request的编码

  4. 代码示例:

    @WebServlet(value = "/request.do")
    public class ServletDemo10 extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            req.setCharacterEncoding("UTF-8"); // 在获取参数之前设置请求编码
            String username = req.getParameter("username");
            System.out.println(username);
            String name = (String) req.getAttribute("name");
            System.out.println("name:" + name);
        }
    }
    
发布了22 篇原创文章 · 获赞 0 · 访问量 344

猜你喜欢

转载自blog.csdn.net/Yi__Ying/article/details/104522875