区别

序号 问题 重定向 请求转发
1 第二次请求谁请求的? 浏览器 服务器
2 浏览器发送了几次请求? 2次以上 1次
3 servlet可以共享request吗? 不可以 可以
4 地址栏是否发生改变? 不是
5 浏览器地址栏显示的哪一次访问地址? 最后一次 第一次
6 可以跳转到什么资源? 任意资源 项目内部
7 第二次的请求路径是? 绝对路径 内部路径

举个栗子

  1. 重定向

    ①:A对B说,帮忙拿下快递

    ②:B对A说,没有空,你找下C吧

    ③:A对C说,帮忙拿下快递

    ④:C然后拿了快递给A

  2. 请求转发

    ①:A对B说,帮忙拿下快递

    ②:第二步,B没有空,直接找让C帮A拿下快递

    ③:C拿到了快递并返回给A

重定向-流程图、代码

流程图

代码BoyServlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class BoyServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
// 获取请求携带的id
String id = request.getParameter("id");
System.out.println("A对B说:帮我拿下快递,id号是:" + id);
System.out.println("B对A说:我没有空,你找下C");
System.out.println("----分割线----");
// 重定向方式1:
response.setStatus(302);
response.setHeader("location", "/redirect/girl");
// 重定向方式2:(正常用此方法)
// response.sendRedirect("/redirect/girl");
}
protected void doPost(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
doGet(request, response);
}
}

代码GirlServlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GirlServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
//设置浏览器解析的格式,否则浏览器会出现乱码
response.setContentType("text/html;charset=utf-8");
//获取请求携带的id
String id = request.getParameter("id");
System.out.println("A对C说,帮我拿下快递,id号是:"+id);
System.out.println("拿到快递了");
//获取输出流
PrintWriter writer = response.getWriter();
//将信息返回给浏览器
writer.println("拿到快递了");
}
2.3web.xml文件
请求转发-流程图、代码
1.流程图
protected void doPost(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
doGet(request, response);
}
}

web.xml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>redirect</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>BoyServlet</display-name>
<servlet-name>BoyServlet</servlet-name>
<servlet-class>com.redirect.BoyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BoyServlet</servlet-name>
<url-pattern>/boy</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>GirlServlet</display-name>
<servlet-name>GirlServlet</servlet-name>
<servlet-class>com.redirect.GirlServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GirlServlet</servlet-name>
<url-pattern>/girl</url-pattern>
</servlet-mapping>
</web-app>

请求转发-流程图、代码

流程图

代码BoyServlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class BoyServlet extends HttpServlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
// 获取请求携带的id
String id = request.getParameter("id");
System.out.println("A对B说:帮我拿下快递,id号是:" + id);
System.out.println("B对A说:好的");
System.out.println("----分割线----");
//---后面B直接在服务器将请求转发给C---
//获取转发对象,后面括号指定了转发的路径
RequestDispatcher dispatcher = request.getRequestDispatcher("/girl");
//执行转发功能,并将请求和响应一并转发过去
dispatcher.forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
doGet(request, response);
}
}

代码GirlServlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GirlServlet extends HttpServlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
// 设置浏览器解析的格式,否则浏览器会出现乱码
response.setContentType("text/html;charset=utf-8");
// 获取请求携带的id
String id = request.getParameter("id");
System.out.println("B对C说:帮A拿下快递,id号是:" + id);
System.out.println("拿到快递了");
// 获取输出流
PrintWriter writer = response.getWriter();
// 将信息返回给浏览器
writer.println("拿到快递了");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
doGet(request, response);
}
}

web.xml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>dispatcher</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>BoyServlet</display-name>
<servlet-name>BoyServlet</servlet-name>
<servlet-class>com.dispatcher.BoyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BoyServlet</servlet-name>
<url-pattern>/boy</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>GirlServlet</display-name>
<servlet-name>GirlServlet</servlet-name>
<servlet-class>com.dispatcher.GirlServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GirlServlet</servlet-name>
<url-pattern>/girl</url-pattern>
</servlet-mapping>
</web-app>

请求转发和重定向时的路径问题

转发或重定向时路径上带"/“和不带”/"的区别

  1. 对于重定向

    如果资源的路径前面有"/“,此时”/“参照 web 服务器的根路径,会丢失 web 应用的根路径,解决方案: 在”/"前面加上

    1
    2
    request.getContextPath()
    response.sendRedirect(request.getContextPath()+"/show.jsp")

    如果路径前没有"/",那么路径相对于当前的 servlet 或 jsp 的路径的,是一个相对路径。

  2. 对于请求转发

    如果资源的路径前没有"/“,那么路径相对于当前的 servlet 或 jsp 的路径;如果路径前带了”/“,此时”/"参照 web 应用的根路径。

    总结:如果请求是客户端的请求(发生在客户端的跳转),那么路径前不要带"/“, 因为带了”/"会丢失 web 应用的根路径。