初识Servlet(六)🚌

217 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第27天,点击查看活动详情

写在前面👀

今天主要讲讲Request请求转发Response请求重定向

一、Request请求转发

请求转发(forward):一种在服务器内部的资源跳转方式

1️⃣请求转发流程简介

  1. 浏览器发送请求给服务器,服务器中对应的Servlet A接收到请求
  2. Servlet A处理完请求后将请求发给Servlet B
  3. 资源B处理完后将结果响应给浏览器
  4. 请求从Servlet AServlet B的过程就叫请求转发

2️⃣请求转发的实现方式

  • 调用 ServletRequest 的 getRequestDispatcher(String path) 方法,可以获得RequestDispatcher 对象。参数 path 指定目标资源的路径,可以为绝对路径,也可以为相对路径
  • RequestDispatcher 接口中的forward(ServletRequest request,ServletResponse response) 方法,用于将请求转发给另一个 Web 资源(该方法必须在响应提交给客户端之前被调用,否则将抛出 IllegalStateException 异常)。
request.getRequestDispatcher("Servlet B路径").forward(request,response);

3️⃣Request域对象

request 是 Servlet 的三大域对象之一,它与请求转发一起使用,可以实现资源间共享数据

  • 下表是 ServletRequest 接口中操作数据的方法
返回值类型方法描述
voidsetAttribute(String name, Object o)将数据存放到 request 对象中。参数 name 为属性名,参数 object 为属性值。
ObjectgetAttribute(String name)根据属性名 name,返回 request 对象中对应的属性值。
voidremoveAttribute(String name)用于移除 request 对象中指定的属性。
EnumerationgetAttributeNames()用于返回 request 对象中的所有属性名的枚举集合。

4️⃣举个例子

实现注册后的欢迎页面

  1. webapp目录下添加一个html文件,名称为:register.html。添加一个表单类型标签,设置请求方式为POST,请求路径为/tomcat/register
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="/tomcat/register" method="post">
            账号:<input type="text" name="username">
            <br>
            密码:<input type="password" name="password">
            <br>
            <input type="submit" value="注册">
        </form>
    </body>
</html>
  1. 创建一个HttpServlet的子类:DispatcherServlet1,Servlet映射路径:/disp1
/**
 * 请求转发
 */
@WebServlet("/disp1")
public class DispatcherServlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.获取姓名参数
        String username = request.getParameter("username");
        // 2.将姓名参数存入request作用域中
        request.setAttribute("username", username);
        // 3.请求转发资源到disp2路径下
        request.getRequestDispatcher("disp2").forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
  1. 创建一个HttpServlet的子类:DispatcherServlet2,Servlet映射路径:/disp2

/**
 * 接受共享数据
 */
@WebServlet("/disp2")
public class DispatcherServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.获取request作用域中的参数
        String username = (String) request.getAttribute("username");
        // 2.解决中文乱码问题
        String name = URLEncoder.encode(username, StandardCharsets.ISO_8859_1);
        String name1 = URLDecoder.decode(name, StandardCharsets.UTF_8);
        // 3.返回注册结果
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("<h1>注册成功!</h1>"+"<h2>欢迎你,"+name1+"</h2>");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
  1. 启动Tomcat服务器

  2. 在浏览器地址栏输入,敲回车

localhost:8080/tomcat/register.html
  1. 演示结果

二、Response请求重定向

Response重定向(redirect):一种资源跳转方式(服务器内外部资源均可)。

1️⃣重定向流程简介

  1. 用户访问浏览器,提高浏览器发送请求给服务器,服务器中的ServletA接收到请求
  2. 但是ServletA现在无法处理该请求,它就会给浏览器响应一个302的状态码和一个访问ServletBlocation
  3. 浏览器接收到302响应状态码就会重新发送请求到location对应的访问地址去访问ServletB
  4. ServletB接收到请求后进行处理并最终给浏览器响应结果,这整个过程就叫重定向

2️⃣重定向的实现方式

// 1.设置响应状态码为302
response.setStatus(302);
// 2.设置重定向的资源访问路径
response.setHeader("location","重定向资源的访问路径");
  • 当然response对象给我们提供了简化的编写方式,省去了设置302状态码的步骤
resposne.sendRedirect("重定向资源的访问路径")

3️⃣举个例子

用重定向实现帮懒人必应一下。

  1. webapp目录下添加一个html文件,名称为:search.html。添加一个表单类型标签,设置请求方式为GET,请求路径为/tomcat/resp1
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="/tomcat/resp1" method="get">
            请输入你的问题:<input type="text" name="question">
            <input type="submit" value="查询">
        </form>
    </body>
</html>
  1. 创建一个HttpServlet的子类:ResponseDemo1,Servlet映射路径:/resp1
/**
 * 重定向:让我帮你必应一下吧!
 */
@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.获取question参数
        String question = request.getParameter("question");
        // 2.以UTF-8编码
        String q = URLEncoder.encode(question, StandardCharsets.UTF_8);
        // 3.重定向,跳转到服务器外部资源
        response.sendRedirect("https://cn.bing.com/search?q=" + q);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
  1. 启动tomcat服务器

  2. 在浏览器地址栏输入,敲回车

localhost:8080/tomcat/search.html
  1. 演示结果

三、转发和重定向的区别

  • 相同点:都能实现页面的跳转
区别转发重定向
浏览器地址栏 URL 是否发生改变
是否支持跨域跳转
请求与响应的次数一次请求和一次响应两次请求和两次响应
是否共享 request 对象和 response 对象
是否能通过 request 域对象传递数据
速度相对要快相对要慢
行为类型服务器行为客户端行为

写在后面🍻

感谢观看啦✨
有什么不足,欢迎指出哦💖
掘金的运营同学审核辛苦了💗