JavaWEB的请求转发的原理(Servlet的详解)

257 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

请求转发

客户端(浏览器)通过工程进行访问服务器Tomcat,先访问Servlet1程序,进行Servlet1的事件处理,Servlet1处理完后,由Servlet1指向Servlet2程序,执行Servlet2的事件,

从Servlet1到Servlet2就是请求转发 请求转发特点

  • 浏览器地址栏没有发生变化
  • 是一次请求
  • 可以共享Request域中的数据
  • 可以转发到WEB-INF目录下(WEB-INF是禁止浏览器访问的 、但请求转发可以)

下面需要在web.xml配置好路径

public class ServletTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //获取请求的参数
        req.setCharacterEncoding("UTF-8");
        System.out.println("在Servlet1中查看参数");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println("用户名 :" + username);
        System.out.println("密码 :" + password);
        req.setAttribute("key1","Servlet一结束");
        //开始请求转发
        /*请求转发必须要以斜杠打头  ,斜杠表示地址为:http://ip:port/工程名, 映射到IDEA代码的web目录
        * */
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
        //走向servlet2
        requestDispatcher.forward(req,resp);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}
@WebServlet(name = "ServletTest2")
public class ServletTest2 extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求的参数
        req.setCharacterEncoding("UTF-8");
        System.out.println("在Servlet2中查看参数");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println("用户名 :" + username);
        System.out.println("密码 :" + password);
        //查看Servlet1是否有盖章
        Object key1 = req.getAttribute("key1");
        System.out.println("Servlet1 是否有值"+ key1);
        //处理自己的事件
        System.out.println("Servlet2 处理自己的事件");
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }
}

图片.png

Base标签的作用

base标签可以设置当前页面中所有相对路径工作时,参照那个路径来进行跳转

下面是一个实例 当我们点击a标签进行跳转的时候,浏览器的地址栏中的地址是http://localhost:8080/day2/test/Dome/t1.html

跳转回去的a标签的路径是: ../../index.jsp 所有相对路径在工作时候都会参照当前游览器地址栏中的地址来进行跳转 那么参照后得到的地址是http://localhost:8080/day2/index.jsp 正确的跳转地址

到我们用请求转发;来进行跳转的时候,浏览器地址栏中的地址是http://localhost:8080/day2/forward 跳转回去的a标签路径是: ../../index.jsp 所有相对路径在工作时候都会参照当前浏览器地址栏中的地址来跳转 那这参照来得到的地址是http://localhost:8080/index.jsp 错误的路径

<%--
  Created by IntelliJ IDEA.
  User: 程序员小徐同学
  Date: 2022-04-7
  Time: 10:20
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>首页</title>
  </head>
  <body>
  <h3>开始了新的测试</h3>
<a href="test/d/t1.html">这是test下Dome下t1.html页面</a>
<a href="http://localhost:8888/day2/context">这是请求转发t1.html页面</a>
  </body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>t1.html</title>
    <!--base标签设置页面相对路径工作时参照的地址-->
    <base href="http://localhost:8888/day2/test/d/t1.html">
</head>
<body>
<h3>这是web下test下Dome下的t1.html页面</h3>
<a href="../../index.jsp">跳回首页</a>
</body>
</html>
public class ContextServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("经过请求转发Forward程序");
        request.getRequestDispatcher("/test/d/t1.html").forward(request,response);
    }
}

三者的路径关系 在javaweb中,路径分为相对路径和绝对路径两种: 相对路径

.点表示当前路径
. .表示上一级路径
绝对路径为http://ip:port/工程路径/资源路径

图片.png

HttpServletResponse类

httpServletResponse类和HttpServletRequest类一样,每次请求进来,Tomcat服务器都会创建一个Response对象传递给Servlet程序去使用。HttpServletRequest表示请求过来的信息,HttpServletResponse表示所有响应的信息, 我们如果需要设置返回给客户端的消息,都可以通过HttpServletResponse对象来进行设置 1.两个输出流的说明 两个流同时只能使用一个,使用字节流就不能再使用字符流,反之亦然,否则就会报错

字节流getOutputStream() --- 常用于下载(传递二进制数据)
字符流getWriter(); -- 常用于回传字符串(常用)

要求:往客户端回传一个字符串

响应在浏览器出现乱码,我们需要先设置编码方式一般将服务器和客户端都使用UTF-8编码此方法一定要在获取流对象之前调用才有效response.setContentType("text/html;character=UTF-8");

public class ContextServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       // System.out.println(response.getCharacterEncoding());//默认是ISO-8859-1编码格式
        //设置服务器字符为UTF-8
     // response.setCharacterEncoding("UTF-8");
      //通过响应头设置浏览器也使用UTF-8字符集
 //       response.setHeader("Content-Type","text/html;character=UTF-8");

        //下面我们使用一种方便的改字符的方式、它会使服务器和客户端都使用UTF-8字符集,还设置了响应头
        // 此方法一定要在获取流对象之前调用才有效
        response.setContentType("text/html;character=UTF-8");
       //要求:往客户端回传一个字符串
        PrintWriter writer = response.getWriter();
        writer.write("response 的中文响应");
    }
}

请求重定向

指的是客户端给服务器发请求,然后服务器告诉客户端说,我给你一些地址,你去新地址访问,叫请求重定向(前地址可能被废弃) 请求重定向特点

  • 浏览器地址栏会改变

  • 两次请求

  • 不共享Req域的数据

  • 不能访问WEB-INF下的资源

  • 可以访问工程外的资源

图片.png

下面为第一种简单的

 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Response1 现在状态");
        //设置响应状态码302,表示重定向
        resp.setStatus(302);
        //设置响应头,说明新的地址
        resp.setHeader("Location","http://localhost:8888/day2/servlet2");
    }

第二种更简单的

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Response1 现在状态");
        //设置响应状态码302,表示重定向
        //resp.setStatus(302);
        //设置响应头,说明新的地址
       // resp.setHeader("Location","http://localhost:8888/day2/servlet2");
        resp.sendRedirect("http://localhost:8888/day2/servlet2");
    }

还有什么问题可以留言给我,会尽心解答的,觉得文章不错的话点个赞把