在 JSP/Servlet 学习中,response 是一个非常重要的内置对象。
如果说 request 负责“接收浏览器发来的请求”,那么 response 就负责“把服务器处理后的结果返回给浏览器”。

在实际开发和考试中,response.sendRedirect() 是最常考的内容之一,尤其经常和 <jsp:forward> 放在一起比较。


一、response 是什么?

response 是 JSP 的九大内置对象之一,完整类型是:

javax.servlet.http.HttpServletResponse

它的作用是:服务器用来给客户端浏览器做响应

浏览器访问 JSP 页面时,本质上是发送了一个 HTTP 请求。服务器处理请求后,需要把处理结果返回给浏览器,这个返回过程就依靠 response 对象完成。

常见作用包括:

1. 设置响应编码
2. 设置响应头信息
3. 实现页面跳转
4. 向客户端写出内容
5. 向客户端保存 Cookie

例如:

<%
    response.setContentType("text/html;charset=UTF-8");
%>

这表示告诉浏览器:服务器返回的是 HTML 页面,并且使用 UTF-8 编码。


二、response 常用方法

1. response.setHeader()

setHeader() 用于设置响应头信息。

格式:

response.setHeader("头信息名称", "头信息内容");

例如让页面每 1 秒刷新一次:

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<body>

<%
    response.setHeader("refresh", "1");
%>

<h1>页面每 1 秒刷新一次</h1>

</body>
</html>

如果配合全局变量,可以看到数字不断变化:

<%@ page contentType="text/html;charset=UTF-8" %>

<%!
    int count = 0;
%>

<html>
<body>

<%
    response.setHeader("refresh", "1");
%>

<h1>当前刷新次数:<%= count++ %></h1>

</body>
</html>

这里的:

response.setHeader("refresh", "1");

表示浏览器每隔 1 秒自动刷新当前页面。


2. 使用 response.setHeader() 实现延时跳转

除了刷新页面,setHeader() 还可以实现延时跳转。

例如:3 秒后跳转到 login.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<body>

<%
    response.setHeader("refresh", "3;URL=login.jsp");
%>

<h1>登录失败,页面将在 3 秒后返回登录页</h1>

</body>
</html>

解释:

response.setHeader("refresh", "3;URL=login.jsp");

含义是:

3 秒后跳转到 login.jsp

这种方式适合做提示页面,例如:

登录失败,3秒后返回登录页
注册成功,3秒后跳转到登录页
操作完成,2秒后返回首页

三、redirect 是什么?

redirect 的中文意思是:重定向

在 JSP/Servlet 中,最常用的重定向方法是:

response.sendRedirect("目标地址");

例如:

<%
    response.sendRedirect("login.jsp");
%>

它的意思是:服务器告诉浏览器:

你重新访问 login.jsp 这个地址。

所以,重定向本质上不是服务器内部直接跳过去,而是浏览器重新发起了一次新的请求


四、response.sendRedirect() 基本用法

例子:登录成功跳转到 welcome.jsp

login.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<body>

<form action="check.jsp" method="post">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit" value="登录">
</form>

</body>
</html>

check.jsp

<%@ page contentType="text/html;charset=UTF-8" %>

<%
    request.setCharacterEncoding("UTF-8");

    String username = request.getParameter("username");
    String password = request.getParameter("password");

    if("admin".equals(username) && "123456".equals(password)){
        response.sendRedirect("welcome.jsp");
    }else{
        response.sendRedirect("login.jsp");
    }
%>

welcome.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<body>

<h1>登录成功,欢迎你!</h1>

</body>
</html>

运行效果:

用户名:admin
密码:123456

点击登录后跳转到:

welcome.jsp

如果输入错误,则重新跳回:

login.jsp

五、sendRedirect 的特点

response.sendRedirect() 有几个非常重要的特点。

1. 地址栏会改变

例如在 check.jsp 中写:

response.sendRedirect("welcome.jsp");

浏览器最终地址会从:

http://localhost:8080/demo/check.jsp

变成:

http://localhost:8080/demo/welcome.jsp

所以它属于 客户端跳转


2. 会产生两次请求

用户先请求:

check.jsp

服务器返回一个重定向响应,告诉浏览器再请求:

welcome.jsp

于是浏览器又发送第二次请求。

流程如下:

浏览器  --请求1-->  check.jsp
服务器  --响应重定向-->  浏览器
浏览器  --请求2-->  welcome.jsp
服务器  --返回页面-->  浏览器

所以 sendRedirect() 本质上会产生两次请求。


3. request 作用域中的数据会丢失

因为重定向是一次新的请求,所以原来的 request 数据不能保留。

例如:

<%
    request.setAttribute("msg", "登录成功");
    response.sendRedirect("welcome.jsp");
%>

然后在 welcome.jsp 中取:

<%
    String msg = (String)request.getAttribute("msg");
%>
<h1><%= msg %></h1>

结果通常是:

null

原因是:

sendRedirect 会让浏览器重新发送一次请求,原来的 request 已经结束。

六、重定向时如何传递数据?

因为 sendRedirect() 不能保存 request 属性,所以如果想传递简单数据,可以通过 URL 地址重写。

例如:

<%
    response.sendRedirect("welcome.jsp?username=admin");
%>

welcome.jsp 中接收:

<%
    String username = request.getParameter("username");
%>

<h1>欢迎你:<%= username %></h1>

如果要传递多个参数,可以这样:

<%
    response.sendRedirect("welcome.jsp?username=admin&age=20");
%>

接收:

<%
    String username = request.getParameter("username");
    String age = request.getParameter("age");
%>

<h1>用户名:<%= username %></h1>
<h1>年龄:<%= age %></h1>

但是这种方式有缺点:

1. 参数会暴露在地址栏中
2. 不适合传递敏感信息,比如密码
3. 不适合传递大量数据

所以登录状态一般不要通过 URL 传递,而是用 session


七、登录状态为什么要用 session?

假设登录成功后这样写:

<%
    if("admin".equals(username) && "123456".equals(password)){
        session.setAttribute("loginUser", username);
        response.sendRedirect("welcome.jsp");
    }
%>

然后在 welcome.jsp 里取:

<%
    String user = (String)session.getAttribute("loginUser");
%>

<h1>欢迎你:<%= user %></h1>

这里用的是 session,不是 request

原因是:

request:一次请求有效
session:一次会话有效

即使 sendRedirect() 产生了新的请求,只要浏览器和服务器还保持同一个会话,session 里的数据仍然可以取到。

所以登录功能一般写成这样:

<%@ page contentType="text/html;charset=UTF-8" %>

<%
    request.setCharacterEncoding("UTF-8");

    String username = request.getParameter("username");
    String password = request.getParameter("password");

    if("admin".equals(username) && "123456".equals(password)){
        session.setAttribute("loginUser", username);
        response.sendRedirect("welcome.jsp");
    }else{
        response.sendRedirect("login.jsp");
    }
%>

welcome.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<body>

<%
    String user = (String)session.getAttribute("loginUser");

    if(user == null){
        response.sendRedirect("login.jsp");
        return;
    }
%>

<h1>欢迎你:<%= user %></h1>

</body>
</html>

这里的:

return;

很重要。
它表示跳转之后,下面的代码不再继续执行。


八、sendRedirect 和 forward 的区别

这是期末考试最容易考的点。

JSP 中常见的服务器端跳转是:

<jsp:forward page="目标页面"/>

Servlet 中常见的服务器端跳转是:

request.getRequestDispatcher("目标页面").forward(request, response);

而客户端跳转是:

response.sendRedirect("目标页面");

它们的区别如下:

对比项 forward sendRedirect
跳转类型 服务器端跳转 客户端跳转
地址栏 不改变 改变
请求次数 一次请求 两次请求
request 数据 可以保留 不能保留
跳转范围 通常限于当前项目内部 可以跳转到外部网站
速度 较快 相对较慢
常见用途 携带 request 数据到 JSP 显示 登录后跳转、避免重复提交

九、forward 示例

forwardDemo.jsp

<%@ page contentType="text/html;charset=UTF-8" %>

<%
    request.setAttribute("msg", "这是通过 request 保存的数据");
%>

<jsp:forward page="result.jsp"/>

result.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<body>

<%
    String msg = (String)request.getAttribute("msg");
%>

<h1><%= msg %></h1>

</body>
</html>

运行结果:

这是通过 request 保存的数据

因为 forward 是服务器端跳转,没有产生新的请求,所以 request 数据可以保留。


十、sendRedirect 示例

redirectDemo.jsp

<%@ page contentType="text/html;charset=UTF-8" %>

<%
    request.setAttribute("msg", "这是通过 request 保存的数据");
    response.sendRedirect("result.jsp");
%>

result.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<body>

<%
    String msg = (String)request.getAttribute("msg");
%>

<h1><%= msg %></h1>

</body>
</html>

运行结果:

null

因为 sendRedirect 是客户端跳转,会产生新的请求,原来的 request 数据已经不存在。


十一、什么时候用 forward?什么时候用 redirect?

适合使用 forward 的情况

如果只是服务器内部页面之间传递数据,尤其是需要保留 request 数据,推荐使用 forward

例如:

Servlet 处理业务后,把结果交给 JSP 显示

常见写法:

request.setAttribute("list", list);
request.getRequestDispatcher("list.jsp").forward(request, response);

这种方式适合 MVC 模式。


适合使用 sendRedirect 的情况

如果希望浏览器地址栏改变,或者希望用户重新访问一个页面,就用 sendRedirect()

例如:

登录成功后跳转首页
退出登录后返回登录页
操作成功后跳转列表页
防止表单重复提交
跳转到外部网站

例如退出登录:

<%@ page contentType="text/html;charset=UTF-8" %>

<%
    session.invalidate();
    response.sendRedirect("login.jsp");
%>

十二、sendRedirect 可以跳转外部网站

forward 一般只能在当前 Web 应用内部跳转。

但是 sendRedirect() 可以跳转到外部地址:

<%
    response.sendRedirect("https://www.baidu.com");
%>

因为它是让浏览器重新访问一个新地址,所以外部网站也可以。


十三、常见错误

1. response.sendRedirect 后继续输出页面

错误写法:

<%
    response.sendRedirect("login.jsp");
%>

<h1>这段内容还可能继续执行</h1>

更规范的写法:

<%
    response.sendRedirect("login.jsp");
    return;
%>

尤其是在登录验证页面中,建议加上 return,防止后面的代码继续执行。


2. sendRedirect 后试图用 request 传值

错误理解:

<%
    request.setAttribute("msg", "成功");
    response.sendRedirect("success.jsp");
%>

然后在 success.jsp 里:

<%= request.getAttribute("msg") %>

这样一般取不到。

正确方式可以改用:

<%
    session.setAttribute("msg", "成功");
    response.sendRedirect("success.jsp");
%>

或者简单参数用 URL:

<%
    response.sendRedirect("success.jsp?msg=success");
%>

3. 中文参数乱码

如果通过表单提交中文,记得写:

<%
    request.setCharacterEncoding("UTF-8");
%>

并且页面开头写:

<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>

HTML 中也建议写:

<meta charset="UTF-8">

十四、期末考试常见写法总结

1. 普通重定向

<%
    response.sendRedirect("index.jsp");
%>

2. 登录成功保存 session 后跳转

<%
    session.setAttribute("loginUser", username);
    response.sendRedirect("welcome.jsp");
%>

3. 退出登录

<%
    session.invalidate();
    response.sendRedirect("login.jsp");
%>

4. 延时跳转

<%
    response.setHeader("refresh", "3;URL=login.jsp");
%>

5. URL 传参跳转

<%
    response.sendRedirect("show.jsp?name=admin&age=20");
%>

6. 服务器端跳转

<jsp:forward page="show.jsp"/>

7. Servlet 中服务器端跳转

request.getRequestDispatcher("show.jsp").forward(request, response);

十五、总结

response 是服务器响应客户端的对象,常用于设置响应信息、页面跳转和 Cookie 操作。

其中,response.sendRedirect() 是最常用的跳转方式之一,它属于客户端跳转,特点是:

1. 地址栏会改变
2. 会产生两次请求
3. request 数据不能保留
4. 可以跳转到当前项目外部的网站
5. 登录成功、退出登录、操作完成跳转时经常使用

<jsp:forward> 属于服务器端跳转,特点是:

1. 地址栏不改变
2. 只有一次请求
3. request 数据可以保留
4. 常用于服务器内部页面转发

一句话记忆:

forward 是服务器内部转发,request 能保留;
redirect 是浏览器重新请求,地址栏会改变。

期末考试中,只要掌握 response.sendRedirect()response.setHeader("refresh", "...")forwardredirect 的区别,基本就能应付大多数 JSP 跳转类程序设计题。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐