杰瑞科技汇

Java JSP页面跳转如何实现?

概览

特性 客户端跳转 服务器端跳转
核心原理 服务器向浏览器返回一个 302 状态码和新的 Location,浏览器收到后重新发起一个新请求访问新页面。 服务器在内部直接将请求转发给另一个资源,浏览器对此毫不知情。
实现方式 response.sendRedirect() <jsp:forward>RequestDispatcher.forward()
URL 地址栏 会改变为新的 URL 地址。 不会改变,始终显示原始请求的 URL。
请求与响应 两个独立的请求和响应,第一个请求结束,第二个请求开始。 同一个请求和响应在服务器内部传递。
数据共享 不能直接共享 request 中的数据,因为第二次请求是全新的,数据需要通过 URL 参数 (?key=value) 或 session 传递。 可以共享 request 中的数据,因为是在同一个请求内处理。
性能 相对较慢,因为浏览器需要重新发起网络请求。 相对较快,因为不涉及网络往返。
适用场景 登录成功后跳转到主页、跨域跳转、需要改变 URL 的情况(如搜索页)。 页面布局(如头部、主体、底部)、条件判断后跳转、MVC 模式中跳转到视图。

客户端跳转

这种方式通过 HTTP 重定向实现,最常见的方式是使用 response.sendRedirect()

Java JSP页面跳转如何实现?-图1
(图片来源网络,侵删)

核心方法

response.sendRedirect(String location)

示例代码

假设我们有两个 JSP 文件:

  • login.jsp: 登录页面
  • welcome.jsp: 登录成功后的欢迎页面

a) login.jsp (登录表单)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">登录页面</title>
</head>
<body>
    <h2>用户登录</h2>
    <form action="login_process.jsp" method="post">
        用户名: <input type="text" name="username"><br>
        密码: <input type="password" name="password"><br>
        <input type="submit" value="登录">
    </form>
</body>
</html>

b) login_process.jsp (处理登录逻辑并跳转)

Java JSP页面跳转如何实现?-图2
(图片来源网络,侵删)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.net.URLEncoder" %>
<%
    // 1. 获取表单提交的数据
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    // 2. 模拟简单的验证逻辑
    if ("admin".equals(username) && "password".equals(password)) {
        // 登录成功,使用 sendRedirect 进行客户端跳转
        // 可以在 URL 后面通过 ?key=value 的方式传递数据
        String redirectUrl = "welcome.jsp?user=" + URLEncoder.encode(username, "UTF-8");
        response.sendRedirect(redirectUrl);
    } else {
        // 登录失败,可以跳转到错误页面或返回登录页
        out.println("<script>alert('用户名或密码错误!'); window.location.href='login.jsp';</script>");
    }
%>

注意: 如果要通过 URL 传递中文等特殊字符,最好使用 URLEncoder.encode() 进行编码,防止乱码。

c) welcome.jsp (欢迎页面)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">欢迎页面</title>
</head>
<body>
    <h1>欢迎您!</h1>
    <!-- 
      由于是客户端跳转,数据通过 request 参数传递。
      注意:request 对象在这里是新的请求,所以需要从参数中获取。
    -->
    <p>欢迎您, <%= request.getParameter("user") %>!</p>
    <p>您可以通过查看浏览器地址栏发现,URL 已经从 login_process.jsp 变成了 welcome.jsp。</p>
</body>
</html>

服务器端跳转

这种方式也称为“请求转发”,服务器将当前请求的处理权交给另一个资源处理,客户端浏览器完全不知道这个过程。

核心方法

  1. JSP 动作标签: <jsp:forward>
  2. Servlet API: request.getRequestDispatcher("url").forward(request, response)

示例代码

我们使用同样的场景,但这次使用服务器端跳转。

Java JSP页面跳转如何实现?-图3
(图片来源网络,侵删)

a) login_forward.jsp (处理登录逻辑并转发)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
    // 1. 获取表单提交的数据
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    // 2. 模拟简单的验证逻辑
    if ("admin".equals(username) && "password".equals(password)) {
        // 登录成功,使用 requestDispatcher 进行服务器端跳转(转发)
        // 数据可以直接存入 request 属性中,在新页面直接获取
        request.setAttribute("loggedInUser", username);
        // 获取转发器,并执行转发
        // 路径是相对于当前 webapp 根目录的
        request.getRequestDispatcher("welcome_forward.jsp").forward(request, response);
        // forward() 方法执行后,当前页面的代码就停止执行了,下面的代码不会被执行
        // out.println("这一行不会被执行到");
    } else {
        // 登录失败,可以转发到一个错误页面
        request.setAttribute("errorMessage", "用户名或密码错误!");
        request.getRequestDispatcher("error.jsp").forward(request, response);
    }
%>

注意: forward() 方法执行后,JSP 容器会立即停止当前页面的执行,并将控制权交给目标页面。forward() 之后的代码(out.println())不会被执行。

b) welcome_forward.jsp (欢迎页面)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">欢迎页面 (服务器端跳转)</title>
</head>
<body>
    <h1>欢迎您!</h1>
    <!-- 
      由于是服务器端跳转(转发),数据通过 request 属性传递。
      这里的 request 对象和 login_forward.jsp 是同一个。
    -->
    <p>欢迎您, <%= request.getAttribute("loggedInUser") %>!</p>
    <p>请查看浏览器地址栏,URL 仍然是 login_forward.jsp,并没有改变。</p>
</body>
</html>

c) error.jsp (错误页面)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">登录错误</title>
</head>
<body>
    <h1>登录失败</h1>
    <p style="color: red;"><%= request.getAttribute("errorMessage") %></p>
    <p><a href="login.jsp">返回登录页</a></p>
</body>
</html>

总结与最佳实践

  1. 何时使用 sendRedirect (客户端跳转)?

    • 需要改变 URL 时:登录成功后跳转到主页,URL 从 /login 变成 /home
    • 跨域或跨应用跳转:当需要跳转到另一个完全不同的网站或 Web 应用时。
    • 防止表单重复提交:在提交表单后进行重定向,如果用户刷新页面,浏览器会提示“重新提交表单数据吗?”,此时重新提交的是 GET 请求,不会重复执行业务逻辑。
    • 退出登录:通常需要清除 session 并跳转到登录页。
  2. 何时使用 forward (服务器端跳转)?

    • 需要共享 request 数据时:这是最核心的原因,在 MVC 架构中,控制器处理完业务逻辑后,将数据存入 request,然后转发到 JSP 视图进行展示。
    • 不希望改变 URL 时:一个网站的所有页面都通过一个主入口(如 index.jsp)来控制,根据参数转发到不同的子页面,但用户看到的始终是 index.jsp
    • 提高性能:避免了一次不必要的网络往返。

在现代的 Web 开发中(尤其是基于 MVC 框架如 Spring MVC),服务器端跳转是构建视图层的标准做法,因为它能很好地在控制器和视图之间传递数据,而客户端跳转则更多地用于流程控制,如登录、注册、退出等场景。

分享:
扫描分享到社交APP
上一篇
下一篇