Servlet--Servlet转发和重定向
一、Servlet请求转发三种方式
servlet中的请求转发主要有三种方式
forward转发原理:
1、浏览器向第一个servlet(FirstServlet)发送请求,tomcat接到请求后调用FirstServlet类的doxx方法。
2、FirstServlet将用户请求的信息放到request中,执行RequestDispatcher.forward(“/ToServlet”)转发请求到tomcat
3、tomcat接收到转发的请求后,创建一个新的request和response对象,将FirstServlet中的信息复制到这个新的对象中。
4、由tomcat请求ToServlet类的doxx方法,将新对象传递过去。
5、ToServlet接收到请求后,执行doxx方法,获取FirstServlet中的信息。返回到浏览器。
forward转发结果
1、转发是在tomcat中完成的
2、转发浏览器只会发送一次请求
3、转发请求浏览器的地址不会改变。
4、转发只能讲请求转发给同一个web项目。
5、转发共享request中的数据,返回的信息只会显示转发目标的文件返回的信息。
include包含转发原理:
1、浏览器向FirstServlet发送请求
2、tomcat接受到请求后,创建request和response两个对象,向FirstServlet类的doxx方法发送请求并传递这两个对象
3、FirstServlet接收到请求后,执行doxx方法,执行request.getRequestDispatcher.include()包含转发语句,发送到转发请求到
tomcat。
4、tomcat接收到转发请求,将ToServlet作为FiestServlet一部分进行转发,请求ToServlet类的doxx方法
5、ToServlet类的doxx方法获取请求数据,返回信息到tomcat
6、tomcat接受到ToServlet返回的信息,发送给FirstServlet。
7、FirstServlet将两个类的信息返回给浏览器。
include包含转发结果:
1、包含转发结果和上面forward转发结果一样,只有最后一条结果不一样。
2、包含返回的数据是转发类和被转发类两个类的返回的信息。
sendRedirect重定向原理:
1、浏览器向FirstServlet类发送请求
2、Tomcat接收到请求后向FirstServlet类的doxx方法传递request和response两个对象。
3、FirstServlet执行doxx方法,执行response.sendRedirect("ToServlet")重定向语句,向浏览器发送302状态码
4、浏览器收到重定向302状态码后,重新发送请求到ToServlet类
5、tomcat就收到新的请求后,创建request和response两个对象,向ToServlet类的doxx方法传递这两个对象。
6、ToServlet执行doxx方法,获取数据,返回信息到浏览器。
sendRedirect重定向结果
1、重定向是客户端发送第二次请求,不是tomcat服务完成的
2、重定向浏览器地址会改变
3、重定向不会共享request的数据,转发后的servlet不能获取前一个servlet中的数据。
4、重定向可以指向任何资源。
二、Servlet三种转发方式实例
1、FirsetServlet类实现三种转发方式
package zhuanfa;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
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 FirstServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
System.out.println("这是第一个servlet"+request);
//获取随机值
Random rand = new Random();
int a = rand.nextInt(50);
request.setAttribute("rand", a);
//获取转发的类的对象
RequestDispatcher zhuanfa = request.getRequestDispatcher("/ToServlet");
//调用forward执行转发功能
//zhuanfa.forward(request, response);
//包含转发
zhuanfa.include(request, response);
out.println("包含转发前返回的信息FirstServlet"+request.getAttribute("rand"));
//重定向
//response.sendRedirect("ToServlet");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
}
}
2、ToServlet类实现接受FirstServlet类跳转的信息。
package zhuanfa;
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 ToServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//First转发到ToServlet
/*out.print("这个是First转发到ToServlet"+"<br/>");
Object ob = request.getAttribute("rand");
out.println("转发:这个值是FirstServlet传递到ToServlet的值:"+ob+"<br/>");*/
//First包含转发到ToServlet
out.print("这个是First转发到ToServlet"+"<br/>");
Object bob = request.getAttribute("rand");
out.println("包含转发:这个值是FirstServlet传递到ToServlet的值:"+bob+"<br/>");
//First重定向到ToServlet
/*out.print("这个是First转发到ToServlet"+"<br/>");
Object cob = request.getAttribute("rand");
out.println("包含转发:这个值是FirstServlet传递到ToServlet的值:"+cob+"<br/>");*/
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
}
}
3、Web配置信息
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>zhuanfa.FirstServlet</servlet-class>
</servlet>
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>ToServlet</servlet-name>
<servlet-class>zhuanfa.ToServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/FirstServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ToServlet</servlet-name>
<url-pattern>/ToServlet</url-pattern>
</servlet-mapping>
</web-app>
4、测试
①、如果测试三种转发方式,需要将FirstServlet中的其他的两个转发方式注释掉,每次只能测试其中的一种转发方式。
②、在ToServlet中同样的将没有测试的两种方式进行注释。
③、上面的两个Servlet类中已经注释了其中的两个转发方式,只有包含转发没有注释。下面值包含转发测试结果
④、在浏览器中输入测试地址:http://127.0.0.1:8080/test07_7/FirstServlet 发送请求
⑤、测试结果返回两个类的数据。