请求转发的问题

来源:互联网 发布:手机淘宝申诉进度查询 编辑:程序博客网 时间:2024/06/16 08:21

请求转发又被称为内部跳转,可以通过以下两个对象获取RequestDispacher对象:

1.调用ServletContext的getRequestDispacher(String path)方法,path参数为目标组件的路径。这里必须为绝对路径。所谓绝对路径就是以“/”开头,“/”表示当前Web应用的URL入口。例如请求转发到另一个Servlet,这里的参数就必须是web.xml文件中的目标Servlet的servlet-mapping中配置的url-pattern的值/ServletName。

2.调用ServletRequest的getRequestDispacher(String path)方法,path参数为目标组件的路径。这里可以为绝对路径也可以为相对路径。所谓相对路径就是不以“/”开头。例如请求转发到另一个Servlet,web.xml文件中的目标Servlet的servlet-mapping中配置的url-pattern的值是/ServletName。这里还可以写为相对路径ServletName即去掉前面的“/”。

请求转发的大致特点:

1.由于RequestDispacher对象在调用forward(request,response)方法会先清空用于存放响应正文的缓冲区,因此(下文实例代码CheckServlet类中注释掉注释A、B两行代码)Servlet源组件生成的响应结果不会被发送到客户端(也就是不会呈现在浏览器中)。只有目标组件生成的响应结果会被发送到客户端。

2.如果目标组件为Servlet或JSP,就会调用它们的service()方法,把该方法所产生的响应结果发送到客户端(呈现在浏览器中)。如果目标组件为静态HTML文档,就读取文档中的数据并把它发送到客户端(呈现在浏览器中)。

3.如果在源组件进行请求转发之间,已经提交了响应结果,有两种情况:

a.ServletResponse调用了flushBuffer()方法

b.ServletResponse调用了关联的输出流的close()方法。例如PrintWriter的close()方法。

以上两种情况会导致不好的后果。因此不应该在源组件中提交相应结果。

实例代码如下:CheckServlet类处理请求后将请求转发给目标组件OutputServlet类:

CheckServlet类:

public class CheckServlet extends HttpServlet {

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

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");

        String name = request.getParameter("userName");

        String message = null;

        if (message == null) {
            message = "Please input name!";
        } else {
            message = "Hello:" + name;
        }

        request.setAttribute("Message", message);
        RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/OutputServlet");
       
        PrintWriter out = response.getWriter();

        out.println("Output from CheckServlet before forwording request!");//(1)
        System.out.println("Output from CheckServlet before forwording request!");
        response.flushBuffer();//(A)会在浏览器输出注释(1)的语句,而且不会执行注释(2)和OutputServlet的输出
        out.close();//(B)会在浏览器输出注释(1)的语句,而且不会执行注释(2)OutputServlet的输出
        dispatcher.forward(request, response);

        out.println("Output from CheckServlet after forwording request!");//(2)
        System.out.println("Output from CheckServlet after forwording request!");
    }
}

OutputServlet类:

public class OutputServlet extends HttpServlet {

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

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
       response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        String message = (String) request.getAttribute("Message");

        out.println(message);
        out.close();
    }
}

web.xml文件配置:

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.5" 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_2_5.xsd">
    <servlet>
        <servlet-name>CheckServlet</servlet-name>
        <servlet-class>servlet002.web.servlet.CheckServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>OutputServlet</servlet-name>
        <servlet-class>servlet002.web.servlet.OutputServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CheckServlet</servlet-name>
        <url-pattern>/CheckServlet</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>OutputServlet</servlet-name>
        <url-pattern>/OutputServlet</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
</web-app>

0 0