一、知识点
1、req.getRequestDispatch与resp.sendRedirect跳转方式的比较
一、实现原理
1、req.getRequestDispatcher:
属于服务器端跳转,在服务器内部将请求转发给另一个资源(如另一个 Servlet 或 JSP 页面)。调用 getRequestDispatcher
方法获取 RequestDispatcher
对象,然后使用 forward
方法实现转发。
例如:
RequestDispatcher dispatcher = request.getRequestDispatcher("/targetPage.jsp"); dispatcher.forward(request, response);
。
整个过程对客户端是透明的,客户端并不知道请求在服务器内部被转发,请求和响应对象保持不变。
2、resp.sendRedirect:
是客户端跳转,服务器向客户端发送一个重定向响应(通常是 302 或 307 状态码),并在响应头中添加 Location
信息,指示客户端重定向到新的 URL。
例如:
response.sendRedirect("http://example.com/newPage.jsp");
。
客户端收到响应后,会根据 Location
信息向新的 URL 发送新的请求。
二、URL 显示
1、req.getRequestDispatcher:
浏览器地址栏的 URL 不会改变,始终显示最初请求的 URL,因为请求是在服务器内部转发,客户端无感知。
2、resp.sendRedirect:
浏览器地址栏会更新为新的重定向 URL,因为客户端发起了新的请求。
三、请求次数
1、req.getRequestDispatcher:
仅一次请求,服务器将请求从一个资源转发到另一个资源,服务器内部完成跳转。
2、resp.sendRedirect:
会产生两次请求,第一次是向原服务器请求,原服务器返回重定向响应,客户端收到响应后发起第二次请求到新的 URL。
四、数据传递
1、req.getRequestDispatcher:
可以使用 request
对象传递数据,因为是在同一个请求范围内,所以在转发前设置的 request
属性在转发后的资源中可以获取。 转发是request!!
例如:
request.setAttribute("data", "value");
在转发后的页面可以使用request.getAttribute("data");
来获取数据。
2、resp.sendRedirect:
不能使用 request
对象传递数据,因为是两次不同的请求。若要传递数据,可使用 session
存储或通过 URL 传递参数。 重定向是sendRendirect!!
例如:
response.sendRedirect("http://example.com/newPage.jsp?data=value");
,新页面可以通过解析 URL 参数获取数据,或者使用
session.setAttribute("data", "value");
存储数据在session
中,在新页面通过session.getAttribute("data");
获取。
五、使用场景
1、req.getRequestDispatcher:
适合在服务器内部的资源之间跳转,尤其是在 MVC 架构中,控制器将请求转发给视图层,实现页面的显示。例如,在 Servlet 处理完业务逻辑后,将请求转发给 JSP 页面显示结果,并且希望将处理结果作为请求属性传递给 JSP 页面。
2、resp.sendRedirect:
适用于需要将客户端引导到另一个不同的应用程序、域名或不同上下文的资源时。例如,在用户登录成功后,重定向到另一个系统或网站的页面;或者在完成表单提交后,重定向到一个结果页面,以防止用户刷新页面时重复提交表单。
综上所述,根据具体的开发需求和场景,选择合适的跳转方式可以优化应用程序的性能和用户体验。
如果需要在服务器内部进行资源跳转,且需要传递数据,可使用 req.getRequestDispatcher
;如果需要引导用户到不同的 URL 或不同的上下文,可使用 resp.sendRedirect
。
六、 Java Servlet 示例
java">import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class JumpServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 使用 req.getRequestDispatcher 进行转发if (request.getParameter("forward")!= null) {request.setAttribute("message", "This is a message from forward.");RequestDispatcher dispatcher = request.getRequestDispatcher("/forwardPage.jsp");dispatcher.forward(request, response);} // 使用 resp.sendRedirect 进行重定向else if (request.getParameter("redirect")!= null) {response.sendRedirect("/redirectPage.jsp");}}
}
当请求参数包含 forward
时,使用 getRequestDispatcher
进行转发,并设置 request
属性 message
,将请求转发到 /forwardPage.jsp
。当请求参数包含 redirect
时,使用 sendRedirect
重定向到 /redirectPage.jsp
。
forwardPage.jsp
页面代码展示
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Forward Page</title>
</head>
<body><h1>Forward Page</h1><p>${message}</p>
</body>
</html>
在 forwardPage.jsp
中,可以使用 EL 表达式 ${message}
获取通过 request
对象传递的属性。
redirectPage.jsp
页面代码展示:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Redirect Page</title>
</head>
<body><h1>Redirect Page</h1>
</body>
</html>
注意,使用 sendRedirect
时,如果是相对 URL,它是相对于当前 Servlet 上下文的;如果需要重定向到其他域名或绝对 URL,需要提供完整的 URL 地址。而 getRequestDispatcher
的路径通常是相对于当前 Web 应用程序的路径。
参考链接:
参考链接:creq.getRequestDispatch与resp.sendRedirect跳转方式_req.getrequestdispatcher-CSDN博客
2、BootStrap官方文档
Dropdowns · Bootstrap v5 中文文档 v5.3 | Bootstrap 中文网
对应class属性的一些值,大家忘记了可以参考这一篇博客
Bootstrap的class属性_bootstrap class-CSDN博客
这篇对于表格写的还比较详细:
Bootstrap系列之表格(Tables)_bootstrap table-CSDN博客
其实这种东西,多用几次自然就记得了,记得一个大概,把知识点过一遍,等要用的时候也可以去查,原来觉得一定要全部记住,就像考试一样,后来发现其实人生是开卷考试
3、查询角色列表到页面中——转发模式
1、设计思路
第一点:页面的设计
如图,只是简单的做了一个大致能表示意思的网页,大部分是在bootstrap里边扒拉出来的,五个button,左右两个表格。
第二点:controller的设计
第三点:数据库的连接处理查询
第四点:如何遍历查询到的数据并展示到页面上
2、controller代码展示
java">package com.illley.controller;import com.illley.bean.Role;
import com.illley.service.ManagerService;
import com.illley.service.impl.ManagerServiceImpl;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.util.List;/** 对应角色的所有操作
* /role 返回基本页面
* /role?act=add 新增角色
* /role?act=delete 删除角色
* /role?act=update 修改角色
* /role?act=xxxx .......
*
* */@WebServlet(urlPatterns = {"/role"})
public class RoleController extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String act =req.getParameter("act");if(act==null){//返回基本页面 往哪放呢? 可以req.getRequestDispatcher("/admin/role.jsp").forward(req,resp);//转发//待解决问题 如果不登 能看到这个页面吗?}else if(act.equals("rolelist")){rolelist(req,resp);}}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req, resp);}void rolelist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//查询所有角色信息//最标准的 还是 得有 roleService 等 一个表对一个javabean controller dao serviceManagerService ms =new ManagerServiceImpl();List<Role> roleList =ms.roleList();req.setAttribute("roleList",roleList);req.getRequestDispatcher("/admin/role.jsp").forward(req,resp);}void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//新增的操作}
}
3、数据库的连接查询
分dao层 和service层 三层架构规范
java">//dao层
package com.illley.dao;import com.illley.bean.Role;import java.util.List;public interface RoleDao extends BaseDao{List<Role> roleList();
}//daoImpl层
package com.illley.dao.impl;import com.illley.bean.Role;
import com.illley.dao.RoleDao;
import org.springframework.jdbc.core.BeanPropertyRowMapper;import java.util.List;public class RoleDaoUmpl implements RoleDao {@Overridepublic List<Role> roleList() {String sql ="select * from role";return t.query(sql,new BeanPropertyRowMapper<>(Role.class));}
}
java">//service层
package com.illley.service;import com.illley.bean.Manager;
import com.illley.bean.Role;import java.util.List;public interface ManagerService {Manager login(String username, String password);List<Role> roleList();
}//serviceimpl层部分代码@Overridepublic List<Role> roleList() {return rd.roleList();}
4、如何遍历查询到的数据并展示到页面上
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Role</title><link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet"/><!-- bt的样式 --></head><body>
<div class="container-fluid"><div class="row"><button type="button" class="btn btn-secondary disabled" >角色和管理员</button></div><div class="row g-2 mt-2"> <div class="col-6 border-end border-dark-subtle border-2 shadow-lg "><a type="button" class="btn btn-info" href="${pageContext.request.contextPath}/role?act=rolelist">角色列表</a><button type="button" class="btn btn-primary">新增角色</button><table class="table table-hover table-bordered border-primary mt-2"><thead><tr><th scope="col"><div class="form-check form-check-inline"><input class="form-check-input border-primary" type="checkbox" id="chk1" value="1"><label class="form-check-label" for="chk1">全选</label></div></th><th scope="col">ID</th><th scope="col">角色名称</th><th scope="col">创建时间</th><th scope="col">简单描述</th><th scope="col">操作</th></tr></thead><tbody><c:forEach items="${requestScope.roleList}" var="r"><tr><th scope="row"><div class="form-check form-check-inline"><input class="form-check-input border-primary" type="checkbox" id="role${r.id}" value="option1"></div></th><td>${r.id}</td><td>${r.rolename}</td><td>${r.createtime}</td><td>${r.display}</td><td><c:if test="${r.id!=1}"><button type="button" class="btn btn-outline-primary btn-sm">查看资源</button><button type="button" class="btn btn-outline-danger btn-sm" >删除</button></c:if></td></tr></c:forEach></tbody></table></div><div class="col-6"><button type="button" class="btn btn-primary">管理员列表</button><button type="button" class="btn btn-info">新增管理员</button><table class="table table-hover table-bordered border-primary mt-2"><thead><tr><th scope="col"><div class="form-check form-check-inline"><input class="form-check-input border-primary" type="checkbox" id="chk2" value="1"><label class="form-check-label" for="chk2">全选</label></div></th><th scope="col">ID</th><th scope="col">用户名</th><th scope="col">密码</th><th scope="col">角色名称</th><th scope="col">创建时间</th></tr></thead><tbody><%--<tr><th scope="row"><div class="form-check form-check-inline"><input class="form-check-input border-primary" type="checkbox" id="i1" value="option1"></div></th><td>Mark</td><td>Otto</td><td>@mdo</td><td>Mark</td><td>Mark</td></tr>--%></tbody></table></div></div>
</div><script src="${pageContext.request.contextPath}/js/bootstrap.bundle.min.js"></script> <!-- bt的脚本 -->
<script src="${pageContext.request.contextPath}/js/jquery-3.7.1.min.js"></script><!-- jq的脚本[bt不需要,我们自己需要] -->
</body>
</html>
讲一下,就是通过jstl里边的c:foreach 把转发中的rolelist属性中的存放着role对象的list拿出来,然后遍历每一个role的数据,展示在屏幕上。