Java Web 请求转发与重定向

本文主要介绍 Java 中的请求转发与重定向。

一、请求转发

1. 说明

请求转发可以将一个 Servlet 接收到的 Request 对象和 Response 对象转发给另一个 Servlet 处理。

2. 用法

  • 通过 Request 对象的实例方法 getRequestDispatcher() 获取 RequestDispatcher 对象
  • 通过 RequestDispatcher 对象的实例方法 forward() 方法进行转发
1
Request.getRequestDispatcher(路径).forward(request, respose)

3. 作用

  • 使 Servlet 分工明确,各司其职
  • 可以实现多个 Servlet 联动处理请求,避免代码冗余

4. 特点

  • 浏览器地址栏的路径并不会发生改变
  • 只能转发到当前服务器内部的 Servlet 中
  • 对于客户端而言,只是发起了一次请求
  • 可以使用 request 域共享数据

二、重定向

1. 做法

方法 1:

  • 设置 response 对象的状态码为 302
  • 为 response 对象的响应头添加 location 信息,并设置其值为重定向地址

方法 2:

调用 response 对象的 sendRedirect(重定向路径) 方法

2. 示例

Response1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 重定向至 Response2
*/
@WebServlet("/response1")
public class Response1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Response1 Working");

// 方法1
response.setStatus(302);
response.setHeader("location", "/response2");

// 方法2
// response.sendRedirect("/response2")
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}

Response2:

1
2
3
4
5
6
7
8
9
10
11
12
13
@WebServlet("/response2")
public class Response2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Response2 Working");
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}

运行结果:

3. 特点

重定向

  • 地址栏发生变化
  • 可以访问其它服务器的资源
  • 两次请求
  • 不能使用 request 域共享数据

4. 路径问题

  • 路径既可以是相对路径,也可以是绝对路径

  • 如果使用绝对路径,当此路径需要发回客户端并由客户端获取资源时,需要在路径中加上项目路径

    • 服务器内部获取资源:

      1
      /访问路径
    • 客户端获取资源:

      1
      /项目路径/访问路径
      • 服务器内部获取资源:

        1
        /test.html
      • 客户端获取资源:

        1
        /project1/test.html
  • 如果需要加上项目路径,更好的做法是动态获取项目路径并拼接字符串

    因为项目路径随时可能更换,并且动态获取可以使不同的项目也可以复用相同的代码

    1
    2
    3
    4
    5
    // 动态获取项目路径
    String contextPath = request.getContextPath();

    // 拼接字符串
    contextPath + "/访问路径"

参考