request.getRequestDispatcher()的两个方法forward()/include()

本文详细对比了Java Web开发中request.getRequestDispatcher(String arg0).forward(req, resp)与response.sendRedirect(String arg0)的区别,前者实现页面转向但URL不变,后者实现重定向且URL变化。同时深入解析了forward()与include()两种请求包含方式的不同之处,包括它们如何处理request与response对象,以及执行过程中对后续代码的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先,解释一下request.getRequestDispatcher(String arg0)是"转向"的意思,跟response.sendRedirect(String arg0)重定向是不一样的;

1..request.getRequestDispatcher(String arg0)---转向的特点:
1.1.地址栏的URl是不变,如:servlet --A转向到servlet--- B的时候,地址栏还是 A它本身,但是内容其实上已经是B的内容了.
2..response.sendRedirect(String arg0)---重定向的特点:
2.1.地址栏的URL是会改变的.如:servlet --A转向到servlet--- B的时候,地址栏就变成B了
2.2.重定向"  sendRedirect(String arg0)  "跟转向的"  forward()"方法有点类似之处:就是在放在它们后面的语句都不会被执行.还有response不能被传递.
---------------------------------------------------------------------------------------------------------------
解释forward()跟include()两个方法
共同点:
(1) forward() 跟include() 在执行的时候,URl也就是浏览器地址栏那的地址是不会改变.从哪里转向的,就是哪的地址
如下面的例子:(创建两个servlet A跟B)
差异点:
(1)调用forward() 的话,有关response对象的一切方法或者属性都会失去作用..只有request能被转向到下一个页面.
    调用include()的话,response跟request都能被传递到转向的下一个页面..
Servlet A:
public A extends HttpServlet{
....省略其它
doGet(HttpServletRequest req,HttpServletResponse resp){
PrintWriter pw=response.getWriter(); pw.write("A");//在页面上打出"A"
 
request.getRequestDispatcher("B").forward(req,resp);//请看结果1
//使用include()的话,结果会怎样呢?请看结果2
//request.getRequestDispatcher("B").include(req,resp);
}
....省略其它
}
Servlet B:
public B extends HttpServlet{
....省略其它
doGet(HttpServletRequest req,HttpServletResponse resp){
PrintWriter pw=response.getWriter();
pw.write("B");//在页面上打出"B"    
}
....省略其它
}
当我直接在地址栏输入:  localhost:8080/Demo02/A  -->回车得到结果如下图
结果1:----forward()
技术分享
结果是:  页面中只有一个字符:   B  
但是地址栏上的Url还是    localhost:8080/Demo02/A 
结果2:(猜猜看..)---include()
技术分享
结果是:  页面中有两个字符:   AB  
但是地址栏上的Url还是    localhost:8080/Demo02/A 
说明问题: 
Ⅰ.  正如共同点(1)说的那样,不管是forward()还是include(),地址栏的url是不变得,因为它们都是转向的方法.
Ⅱ.  从第一个结果可以看出,调用forward()方法,会失去response对象的传递,(如果用request设置的话,是可以传递到 下一个页面的,下面会讲到)用include()的话,就不会出现这个问题.//////(include()方法可以将原来的数据和后来的数据合并在一起)
------------------------啊,我是一条华丽的分割线-------------------
那么下面进行下一个论证:调用forward()方法,request对象能传递到下一个页面么?还有定义在forward()下面的语句能被执行么?
Servlet A:
public A extends HttpServlet{
....省略其它
doGet(HttpServletRequest req,HttpServletResponse resp){
PrintWriter pw=response.getWriter(); pw.write("A");//在页面上打出"A"
//使用forward()...
request.setAttribute("name", "zhangsan");
request.getRequestDispatcher("B").forward(req, resp);//请看结果3
request.setAttribute("age", 13);
 
//使用include()的话,结果会怎样呢?请看结果4
//request.setAttribute("name", "zhangsan");
//request.getRequestDispatcher("B").include(req,resp);
//request.setAttribute("age", 13);
 
}
....省略其它
}
Servlet B:
public B extends HttpServlet{
....省略其它
doGet(HttpServletRequest req,HttpServletResponse resp){
PrintWriter pw=response.getWriter();
pw.write("B"+"\r\n");//在页面上打出"B"    
pw.write(request.getAttribute("name")+"\r\n");   //测试request对象是否可以通过forward()传递
pw.write(request.getAttribute("age")+"");  //测试写在forward()后面的语句是否可以被执行
}
....省略其它
}
结果3:---使用forward()

结果是:页面中显示出了  在request设置的name属性:zhangsan   然而在forward()方法下设置的request属性age却是为null  说明了,执行forward()方法是可以传递request对象设置的属性或者方法的,但是写在forward()方法后面的代码,将不会被执行..
 
结果4:---使用include();
 
结果是:页面中显示的内容跟结果3是一样..!但是,include()跟forward()引起的原因是不一样,只是结果一样而已!
那么include()导致age丢失的原因是什么呢?
要知道这个原因,首先要理解include()的执行过程是怎么样的?
(---include就是包含的意思---)
现在来讲讲include()执行的过程:   (如图)
技术分享

 过程1-3都是正常的程序执行...到了第4步,程序执行到include()方法的时候,把servlet B的代码直接包含进了servlet A中,

也就是把servlet B合并到A去了,合并完的代码如下图:
技术分享
 由上图可知,include()方法之所以也会丢失age属性值,是由于,age属性调用比age属性设置早了一步,也就是说,age还没赋值呢,程序就调用,等程序调用完后,age才被赋值..
所以,得出结论,include()跟forward()方法导致age为空值得原因是不一样的..
----->来自呆呆的坐的网易博客
5 应用系统的设计与实现 5.1 开发环境简介 本应用系统采用Java语言进行开发,基于B/S架构,使用JDBC作为数据访问接口,集成开发环境为Eclipse。前端采用HTML、CSS和JavaScript技术进行页面设计,后端使用Servlet和JSP技术实现业务逻辑和页面交互。 5.1 系统总体功能模块 系统主要有图书类别管理、出版社管理、图书管理、仓库信息管理、进货管理、入库管理、销售管理、出库管理等几个功能模块。功能模块图如图5-1所示。 图5-1 系统功能模块图 5.2 用户登录模块的设计实现 用户登录模块用于验证用户的身份,只有合法的用户才能进入系统。系统界面截图如图5-2所示。 图5-2 用户登录界面 关键代码如下: java @WebServlet("/login") public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); if ("admin".equals(username) && "123456".equals(password)) { HttpSession session = request.getSession(); session.setAttribute("user", username); response.sendRedirect("index.jsp"); } else { request.setAttribute("error", "用户名或密码错误"); request.getRequestDispatcher("login.jsp").forward(request, response); } } } 5.3 图书管理模块的设计与实现 图书管理模块用于对图书的基本信息进行管理,包括查询、录入、删除、修改等操作。系统界面截图如图5-3所示。 图5-3 图书管理界面 关键代码如下: java // BookServlet.java @WebServlet("/book") public class BookServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String action = request.getParameter("action"); if ("list".equals(action)) { List<Book> books = BookDAO.getAllBooks(); request.setAttribute("books", books); request.getRequestDispatcher("book_list.jsp").forward(request, response); } else if ("add".equals(action)) { request.getRequestDispatcher("book_add.jsp").forward(request, response); } else if ("save".equals(action)) { String bookName = request.getParameter("bookName"); String author = request.getParameter("author"); String isbn = request.getParameter("isbn"); double price = Double.parseDouble(request.getParameter("price")); int categoryId = Integer.parseInt(request.getParameter("categoryId")); int publisherId = Integer.parseInt(request.getParameter("publisherId")); Book book = new Book(); book.setBookName(bookName); book.setAuthor(author); book.setIsbn(isbn); book.setPrice(price); book.setCategoryId(categoryId); book.setPublisherId(publisherId); BookDAO.addBook(book); response.sendRedirect("book?action=list"); } } } 使用C语言和mysql
最新发布
06-24
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <jsp:include page="check_logstate.jsp"></jsp:include> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!doctype html> <html lang="zh_CN"> <head> <base href="<%=basePath%>" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>欢迎使用后台管理系统</title> <link rel="stylesheet" href="asset/page/css/style.default.css" type="text/css" /> <link rel="stylesheet" href="asset/page/css/responsive-tables.css"> <script type="text/javascript" src="asset/page/js/jquery-1.9.1.min.js"></script> <script type="text/javascript" src="asset/page/js/bootstrap.min.js"></script> </head> <body> <div class="mainwrapper"> <div class="maincontent"> <div class="maincontentinner"> <h4 class="widgettitle">学生请假列表</h4> <table id="dyntable" class="table table-bordered responsive"> <thead> <tr> <th style="text-align: center;"> </th> <th style="text-align: center;">学生用户</th> <th style="text-align: center;">宿舍</th> <th style="text-align: center;">开始时间</th> <th style="text-align: center;">结束时间</th> <th style="text-align: center;">原因</th> <th style="text-align: center;">状态</th> <th style="text-align: center;">操作</th> </tr> </thead> <c:forEach items="${outList}" var="out"> <tr style="text-align: center;"> <td style="text-align: center;"> </td> <td style="text-align: center;">${out.realname}</td> <td style="text-align: center;">${out.roomsname}</td> <td style="text-align: center;">${out.starttime}</td> <td style="text-align: center;">${out.endtime}</td> <td style="text-align: center;">${out.reason}</td> <td style="text-align: center;">${out.stats}</td> <td style="text-align: center;"> <c:if test="${out.stats eq '待审批' }"> <a href="out/stats.action?id=${out.outid}">处理</a>  </c:if><a href="out/deleteOut.action?id=${out.outid}" onclick="{if(confirm('确定要删除吗?')){return true;}return false;}">删除</a></td> </tr> </c:forEach> </tbody> </table> <div class="dataTables_info" id="dyntable_info" style="text-align: right;">${html }</div> </div> </div> </div> </body> </html> 学生用户不显示姓名
06-09
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值