生活中,110报警中心负责接收群众报警电话,根据接收到的信息(案发地点,紧急程度等),将报警请求交由不同的派出所进行请求,110报警中心充当一个调度员的角色。
该处理方式的好处:
1.提供了统一的报警方式,110
2.报警中心根据实际情况,可以合理调度资源,安排就近单位及时出警
3.报警中心并不处理具体案件,缩短了对报警请求的响应时间
在WEB应用中,该处理模型得到了广泛应用,由Servlet充当调度员的角色,我们也称之为控制器(Controller).在控制器中,可以将请求转发(request dispatcher)给其它Servlet,JSP页面,HTML页面等,由它们处理并产生对请求的响应。
使用javax.servlet.RequestDispatcher接口完成请求转发
RequestDispatcher对象由Servlet容器创建,用于封装一个由路径所标识的服务器资源
该接口定义了两个方法forward()和include()
forward()方法用于将请求从一个Servlet传递到另外的Servlet,JSP页面,HTML页面;需要在响应被提交给客户端之前调用,否则会抛出IllegalStateException.调用方法后,之前在响应缓存中没有提交的内容将被自动清除
include()方法用于在响应中包含其它资源(Servlet,JSP页面,HTML页面),
两个方法的区别:利用include()方法将请求转发给其它Servlet,被调用的Servlet对请求做出的响应会并入原先的响应对象中,原先的Servlet还可以继续输出响应信息,而利用forward()方法将请求转发给其它Servlet,将由被调用Servlet负责对请求做出响应,原先的Servlet的执行将终止。
得到RequestDispatcher对象的三种方法
ServletRequest接口中的getRequestDispatcher(String path)方法
ServletContext接口中的getNamedDispatcher()和geyRequestDispatcher(String path)方法
两个接口中提供了同名的getRequestDispatcher(String path)方法,二者异同:
参数都是资源的路径名,ServletContext接口中的getRequestDispatcher()方法参数必须以‘/’开头,表示相对于当前上下文根(context root)的路径;而ServletRequest接口中的getRequestDispatcher(String path)方法的参数即可以是相对于上下文根的路径,也可以是相对于当前Servlet的路径(依据是否以‘/’开头判断相对路径)
ServletContext接口中的getNamedDispatcher()以部署描述符(web.xml)中给出的Servlet或JSP的名字作为参数。
tips:可以通过ServletContext对象的getContext()获取另一个web应用的上下文对象,利用该上下文对象调用geyRequestDispatcher(String path)方法得到RequestDispatcher对象,可以将请求转发到另一个WEB应用程序中的资源(需要在当前web应用程序中指定
请求转发的实例:
编写一个PortalServlet,首先判断用户登录输入是否正确,为true则调用RequestDispatcher接口的forward()方法,将请求专发 给WelcomeServlet,向用户显示欢迎信息,false,则调用RequestDispatcher接口的include()方法,将请求转发给LoginServlet,LoginServlet在响应中发送登录表单。
Portalservlet.java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class PortalServlet extends HttpServlet
{
public void doGet(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{
resp.setContentType("text/html;charset=gb2312");
PrintWriter out=resp.getWriter();
out.println("");
out.println("登录页面");
out.println(" ");
String name=req.getParameter("username");
String pwd=req.getParameter("password");
if("zhangsan".equals(name)&&"123".equals(pwd)){//登录名,密码正确,则利用上下文对象的getRequestDispatcher()得到请求转发对象
ServletContext context=getServletContext();
RequestDispatcher rd=context.getRequestDispatcher("/welcome");//相对于上下文路径的路径
rd.forward(req,resp);//请求转发给WelcomeServlet处理,14-16行的代码HTNL输出代码被自动清除,执行的控制权移交给welcome,doGet()方法的剩余代码也不再执行。
}else{//登录信息输入错误,则利用请求对象的getRequestDispatcher()得到请求转发对象
RequestDispatcher rd=req.getRequestDispatcher("login");//传入路径以“/”开头表示相对于上下文路径的路径,否则表示相对于当前Servlet的路径
rd.include(req,resp);//将请求转发给loginServlet处理,当login2对请求处理完毕后,执行的控制权回到PortralServlet,将继续执行第27-28行代码
}
out.println("