• Response对象学习笔记


    Response 对象功能介绍

    功能:设置响应消息(响应头、响应行、响应体)

    1. 设置响应行:

      1. 格式:HTTP/1.1 200 ok
      2. 设置状态码:setStatus(int sc)
    2. 设置响应头:setHeader(String name, String value)

    3. 设置响应体:

      使用步骤:

      1. 获取输出流

        PrintWriter getWriter()																// 字符输出流
        ServletOutputStream getOutputStream()									// 字节输出流
        
      2. 使用输出流,将数据输出到客户端浏览器


    Response 对象的学习案例

    完成重定向

    1. 要求:用户通过浏览器访问 demo01 资源,重定向到 demo02 资源

    2. 实现:

      1. 创建一个 JavaEE - Tomcat项目(ResponseHttp)

      2. 定义两个类:demo01、demo02

        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("/demo01")
        public class ResponseDemo01 extends HttpServlet {
            @Override
            protected void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                System.out.println("demo01 被访问啦!!!");
                // 要求:用户通过浏览器访问 /demo01 资源,会自动跳转到 /demo02 资源
                // 实现如下:
                // 1. 设置状态码为 302  ———— 重定向状态码
                response.setStatus(302);
                // 2. 设置响应头location,对应 demo02 的资源路径
                response.setHeader("location", "/ResponseHttp_war_exploded/demo02");
                /*
                简单的重定向方法
                response.sendRedirect("/ResponseHttp_war_exploded/demo02");
                这里的虚拟目录/ResponseHttp_war_exploded,推荐动态获取,因为一旦虚拟目录改变,
                如果不是动态获取的虚拟目录,将于全部进行修改。
                response.sendRedirect(request.getContextPath() + "/demo02");
                */
            }
        
            @Override
            protected void doPost(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                this.doGet(request, response);
            }
        }
        
        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("/demo02")
        public class ResponseDemo02 extends HttpServlet {
            @Override
            protected void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                System.out.println("demo02 被访问啦!!!");
            }
        
            @Override
            protected void doPost(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                this.doGet(request, response);
            }
        }
        
    3. 启动服务器,用户访问:http://localhost:8080/ResponseHttp_war_exploded/demo01

      1. 服务器端输出(即编译器控制台输出)

        demo01 被访问啦!!!
        
      2. 用户浏览器页面跳转到:http://localhost:8080/ResponseHttp_war_exploded/demo02

      3. 服务器端输出

        demo02 被访问啦!!!
        
    4. 浏览器中检查Network如下:

      1. demo01

        20200528011649
      2. demo02

        20200528011759

    重定向的特点

    重定向(redirect)特点不同于 Request请求转发(forward)

    1. 地址栏发生变化
    2. 重定向可以访问其他站点(服务器)的资源
    3. 重定向是两次请求。不能使用request对象来共享数据

    服务器输出字符数据到浏览器

    1. 实现代码:

      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.io.PrintWriter;
      
      @WebServlet("/demo03")
      public class ResponseDemo03 extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse response)
                  throws ServletException, IOException {
              // 乱码问题的解决
              // 解决方式1
              // 获取流对象之前,将流对象默认的编码(ISO-8859-1)修改为 GBK
              request.setCharacterEncoding("GBK");
              response.setCharacterEncoding("GBK");
              // 解决方式2
              // 告诉浏览器,服务器发送的消息体数据编码,建议浏览器使用该编码
              // response.setHeader("content-type", "text/html;charset=utf-8");
              // 解决方式3
              // response.setContentType("text/html;charset=utf-8");
              // 获取字符输出流
              PrintWriter responseWriter = response.getWriter();
              // 输出数据
              responseWriter.write("<h1>你好,Response!</h1><br><h2>你好,Response!</h2>");
          }
      
          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse response)
                  throws ServletException, IOException {
              this.doGet(request, response);
          }
      }
      
    2. 浏览器访问:http://localhost:8080/ResponseHttp_war_exploded/demo03

      20200528020921
    3. 乱码问题

      1. 获取的流的默认编码是ISO-8859-1

      2. 设置该流的默认编码

      3. 告诉浏览器响应体使用的编码

        // 简单的形式,设置编码,是在获取流之前设置
        response.setContentType("text/html;charset=utf-8");
        

    服务器输出字节数据到浏览器

    1. 实现代码:

      import javax.servlet.ServletException;
      import javax.servlet.ServletOutputStream;
      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.nio.charset.StandardCharsets;
      
      @WebServlet("/demo04")
      public class ResponseDemo04 extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse response)
                  throws ServletException, IOException {
              // 告诉浏览器,服务器发送的消息体数据编码,建议浏览器使用该编码(设置响应头中的content-type值)
              response.setContentType("text/html;charset=utf-8");
              // 获取字节输出流
              ServletOutputStream responseOutputStream = response.getOutputStream();
              // 输出数据
              responseOutputStream.write("你好,Response!".getBytes(StandardCharsets.UTF_8));
          }
      
          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse response)
                  throws ServletException, IOException {
              this.doGet(request, response);
          }
      }
      
    2. 开启服务器,浏览器访问:http://localhost:8080/ResponseHttp_war_exploded/demo04,浏览器页面输出

      你好,Response!
      

    验证码

    1. Java 代码:

      import javax.imageio.ImageIO;
      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.awt.*;
      import java.awt.image.BufferedImage;
      import java.io.IOException;
      import java.util.Random;
      
      @WebServlet("/checkCodeServlet")
      public class CheckCodeServlet extends HttpServlet {
      
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse response)
                  throws ServletException, IOException {
              // 定义验证码方框长和宽
              int width = 100, height = 50;
              // 创建一个对象,在内存中画图(验证码图片对象)
              BufferedImage bufferedImage =
                      new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
              // 美化图片
              // 创建画笔对象
              Graphics graphics = bufferedImage.getGraphics();
              // 设置画笔的颜色
              graphics.setColor(Color.PINK);
              // 用画笔,将制定的长方形区域,画满(画验证码图片背景 -> 粉红色)
              graphics.fillRect(0, 0, width, height);
              // 画验证码图片边框
              // 设置画笔的颜色
              graphics.setColor(Color.BLACK);
              graphics.drawRect(0, 0, width - 1, height - 1);
              // 定义一个包含所有字幕和数字的字符串(验证码)
              String strings = "QqWwEeRrTtYyUuIiOoPpAaSsDdFfGgHhJjKkLlZzXxCcVvBbNnMm1234567890";
              // 创建随机数对象,用来获取字符串中的一个字符
              Random random = new Random();
              // 写入四个字符在验证码方框中
              int codeNumber = 4;
              for (int i = 1; i <= codeNumber; i++) {
                  // strings 索引
                  int index = random.nextInt(strings.length());
                  // 通过索引获取字符
                  char indexString = strings.charAt(index);
                  // 写入一个验证符
                  graphics.drawString(indexString + "", width / 5 * i, height / 2);
              }
              // 在验证码方框中画干扰线
              graphics.setColor(Color.GREEN);
              int lineNumber = 10;
              for (int i = 0; i < lineNumber; i++) {
                  // 生成随机坐标点
                  int x1 = random.nextInt(width);
                  int x2 = random.nextInt(width);
                  int y1 = random.nextInt(height);
                  int y2 = random.nextInt(height);
                  // 画线
                  graphics.drawLine(x1, y1, x2, y2);
              }
              
              // 将图片输出到页面展示
              ImageIO.write(bufferedImage, "png", response.getOutputStream());
          }
      
          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse response)
                  throws ServletException, IOException {
              this.doGet(request, response);
          }
      }
      
    2. 启动服务器,浏览器中访问:http://localhost:8080/ResponseHttp_war_exploded/checkCodeServlet

      20200528034555

      上面这需要刷新页面,才能更新验证码。

    3. 下面编写html页面,指定对应的CheckCodeServlet.java

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>验证码</title>
          
              <script>
                  /*
                      分析:
                          点击超链接或者图片,需要换一张
                          1.给超链接和图片绑定单击事件
                          2.重新设置图片的src属性值
          
                   */
                  window.onload = function(){
                      // 1.获取图片对象
                      const img = document.getElementById("checkCode");
                      // 2.绑定单击事件
                      img.onclick = function(){
                          // 加时间戳(因为需要每次请求的url都不一样)
                          const date = new Date().getTime();
                          img.src = "/ResponseHttp_war_exploded/checkCodeServlet?"+date;
                      }
                  }
              </script>
          </head>
          <body>
              <div>
                  <img id="checkCode" src="/ResponseHttp_war_exploded/checkCodeServlet" />
                  <a id="change" href=""> 看不清换一张?</a>
              </div>
          </body>
      </html>
      
    4. 启动服务器,浏览器访问:http://localhost:8080/ResponseHttp_war_exploded/CheckCodeHtml.html

      20200528035652

      每次点击图片,都会直接更换验证码,请求的url都是随时间的变化而变化的,而点击 看不清换一张 则仅仅只是刷新了一次该页面。

    参考文献

    Good Good Write Bug, Day Day Up
  • 相关阅读:
    How to access the properties of an object in Javascript
    他们不是机器人
    sql 使用整理
    地图上计算两点间的距离.(参考网络)
    window.location.reload被弃用?
    BitBlt
    BitBlt介绍
    C#大数计算 .Net Framework4.0以下
    C# ToString格式化
    Ubuntu修改时区和更新时间
  • 原文地址:https://www.cnblogs.com/liyihua/p/14477460.html
Copyright © 2020-2023  润新知