请求转送 Request Dispatching

来源:互联网 发布:小说php源码带采集 编辑:程序博客网 时间:2024/04/30 00:11

 假如Servlet无法回应用户的请求,必要时可以将这个请求转交给其他Servlet处理,这个动作称为“Request Dispatching”(请求转送)。 
   “请求转送”方式:例如ServletRequest.getRequestDispatcher()与ServletContext.getRequestDispatcher(). 

ServletRequest接口所提供的“请求转送”方法 

    ServletRequest.getRequestDispatcher()方法 
在javax.servlet.ServletRequest接口内定义了一个getRequestDispatcher()方法,其方法标记式为: 

public RequestDispatcher getRequestDispatcher(String path) 

getRequestDispatcher()方法需传入一个字符串,表示被转送的 Servlet位置(可以是绝对路径或相对路径)。此方法将回传一个RequestDispatcher对象。接着您可以利用 javax.servlet.RequestDispatcher接口所定义的forward()或include()方法来转送HTTP请求。

笔者以实例来说明“请求转送”的基本步骤。 

(1)当Servlet A收到用户的HTTP请求时,准备将这个HTTP请求转送给Servlet B。 

(2)在Servlet A的doXXX()方法内调用getRequestDispatcher()方法,并指定Servlet B所在位置,例如: 

String path = "/servlet/ServletB";RequestDispatcher rd = request.getRequestDispatcher(path)



(3)取得RequestDispatcher对象后,再利用forward()或include()方法来转送HTTP请求。无论调用哪个方法都必须传入HttpServletRequest与HttpServletResponse对象,例如: 

rd.forward(request, response);rd.include(request, response);



    RequestDispatcher.forward()方法 
RequestDispatcher接口所定义的forward()方法可以将HTTP请求转送给其他Web资源(例如Servlet、JSP或HTML)进行处理,并产生HTTP回应。 

调用forward()方法时必须注意下列两点: 

    在HTTP回应被“确认”(committed)以前才能调用forward()方法(这里的“确认”是指将HTTP回应的内容主体送回用户端),否则将拋出IllegalStateException异常。 

    调用forward()方法后,原先存放在HttpResponse对象中的内容将会自动被清除(本章稍后的实例演练2-3将探讨此议题)。 

RequestDispatcher.include()方法 
    RequestDispatcher接口的include()方法与forward()方法非常类似,惟一的不同在于:利用include()方法将HTTP请求转送给其他Servlet后,被调用的Servlet虽然可以处理这个HTTP请求,但是最后的主导权仍然是在原来的Servlet。换言之,被调用的Servlet如果产生任何HTTP回应,将会并入原来的HttpResponse对象。 

ServletContext接口所提供的“请求转送”方法 

    ServletContext.getRequestDispatcher()方法 
除了ServletRequest接口外,javax.servlet.ServletContext接口也提供一个getRequestDispatcher()方法,其方法标记式为: 

public RequestDispatcher getRequestDispatcher(String path)


    getRequestDispatcher()方法将回传一个RequestDispatcher对象,您可以用这个对象来转送HTTP请求。值得注意的是,传入ServletContext.getRequestDispatcher()方法的路径名称必须以 “/” 开头,这里的 “/” 代表Web应用程序的起始位置(context root)。 

以下是两个合法的ServletContext.getRequestDispatcher()使用范例。 

String path = "/Servlet/ServletB";RequestDispatcher rd = getServletContext().getRequestDispatcher(path);rd.forward(request, response);String path = "/Servlet/ServletB";ServletContext sc = getServletContext();RequestDispatcher rd = sc.getRequestDispatcher(path);rd.forward(request, response);


下面这个范例却是不合法的。 

String path = "../index.html";RequestDispatcher rd = getServletContext().getRequestDispatcher(path);rd.forward(request, response);


在第三个范例中,path变量设定为“../index.html”,因此无法调用ServletContext接口的getRequestDispatcher()方法。在这种情况下,您必须改用ServletRequest接口所提供的getRequestDispatcher()方法,例如: 

String path = "../index.html";RequestDispatcher rd = request.getRequestDispatcher(path);rd.forward(request, response);


getNamedDispatcher()方法 
    ServletContext接口还提供了另一个getNamedDispatcher()方法,其方法标记式为: 

public RequestDispatcher getNamedDispatcher(String name)



    此方法与getRequestDispatcher()方法类似,也会传回一个RequestDispatcher对象,由此可转送HTTP请求。不同之处在于:传入getNamedDispatcher()方法的字符串并非Servlet或JSP的路径,而是其名称。 

以下是getNamedDispatcher()方法的使用范例: 

ServletContext sc = getServletContext();RequestDispatcher rd = sc.getNamedDispatcher("ServletB");rd.forward(request, response);


    上例准备将HTTP请求转送给ServletB,问题是一个Web应用程序说不定包含好几个ServletB(位于不同组件包内),为此,您可以在web.xml内定义ServletB究竟是哪个类或是位于哪个组件包内,例如: 

<servlet><servlet-name>ServletB</servlet-name><servlet-class>scwcd.ch02.ServletB</servlet-class></servlet>


这样一来,getNamedDispatcher()方法才能确定ServletB的真实位置为scwcd.ch02.ServletB,然后传回RequestDispatcher对象。

原创粉丝点击