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都是随时间的变化而变化的,而点击 看不清换一张 则仅仅只是刷新了一次该页面。

参考文献

posted @   LeeHua  阅读(234)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示

目录导航