04.RequestDispatcher

RequestDispatcher

由Servlet容器创建的一个WEB资源的包装器,可以用来把当前的request传递到该资源,或者把新的资源包括到当前响应中。

方法

  • void forward(ServletRequest request, ServletResponse response):将请求从一个servlet转发到另一个资源(servlet,jsp或HTML文件)。此方法允许一个servlet对请求进行初步处理,并使另一个资源生成响应。

    如下图,Servlet1将请求转发给Servlet2,但是可以做相关的初步处理。如果Servlet1做相关的响应,并不会出现在客户端上,将会被丢弃。

  • void include(ServletRequest request, ServletResponse response):包含响应中的某个资源(servlet,jsp或HTML文件)的内容。事实上,此方法支持编程式服务器端的包含。

    如下图,相当于Servlet1包含了Servlet2的服务,两者对服务器的响应都会反馈给客户。
    这里写图片描述

示例代码

HTML文件

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <a href="s1">Dispatcher-forward测试</a><br/>
    <a href="s3">Dispatcher-include测试</a>
</body>
</html>

web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>Dispatcher</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>

  <servlet>
        <servlet-name>s1</servlet-name>
        <servlet-class>com.li.servlet.forward.Servlet1</servlet-class>
  </servlet>
  <servlet-mapping>
        <servlet-name>s1</servlet-name>
        <url-pattern>/s1</url-pattern>
  </servlet-mapping>

  <servlet>
        <servlet-name>s2</servlet-name>
        <servlet-class>com.li.servlet.forward.Servlet2</servlet-class>
  </servlet>
  <servlet-mapping>
        <servlet-name>s2</servlet-name>
        <url-pattern>/s2</url-pattern>
  </servlet-mapping>

  <servlet>
        <servlet-name>s3</servlet-name>
        <servlet-class>com.li.servlet.include.Servlet3</servlet-class>
  </servlet>
  <servlet-mapping>
        <servlet-name>s3</servlet-name>
        <url-pattern>/s3</url-pattern>
  </servlet-mapping>

  <servlet>
        <servlet-name>s4</servlet-name>
        <servlet-class>com.li.servlet.include.Servlet4</servlet-class>
  </servlet>
  <servlet-mapping>
        <servlet-name>s4</servlet-name>
        <url-pattern>/s4</url-pattern>
  </servlet-mapping>

</web-app>

forward示例

Servlet1.java

package com.li.servlet.forward;

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 Servlet1 extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet1 doGet!");
        resp.setContentType("text/html;charset=UTF-8");

        /*此语句并不会被输出,因为请求转发给了s2,此响应将被丢弃
         */
        resp.getWriter().write("Servlet1<br/>");

        /*将请求转发给s2,使用的是相对路径,可以使用斜杠来表示不适用当前的工程目录*/
        RequestDispatcher rd=req.getRequestDispatcher("s2");
        req.setAttribute("test", Math.random());

        /*调用forward方法*/
        rd.forward(req, resp);
    }
}

Servlet2.java

package com.li.servlet.forward;

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 Servlet2 extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet2 doGet!");
        /*
         * 我们并没有在此设置resp的ContentType,但是我们在Servlet1中已经设置过,
         * 在这里输出中文,以此观察响应对象是否被带过来。(实际上会被带过来,我们在此处并不需要再设置)
         */

        double d=(Double)req.getAttribute("test");   //返回类型为Object类型,强制转换

        resp.getWriter().write("test:"+d+"<br/>");
        resp.getWriter().write("Servlet2你好<br/>");

    }
}

include示例

Servlet3.java

package com.li.servlet.include;

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 Servlet3 extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet3 doGet!");
        resp.setContentType("text/html;charset=UTF-8");

        /*此语句会被响应出来,相当于s4被包含进来,应理解包含的意思*/
        resp.getWriter().write("<strong>Servlet3</strong><br/>");

        /*将请求转发给s4,使用的是相对路径,可以使用斜杠来表示不适用当前的工程目录*/
        RequestDispatcher rd=req.getRequestDispatcher("s4");

        /*调用include方法*/
        rd.include(req, resp);

        /*再接收s4设置的数据*/
        double d=(Double)req.getAttribute("test");   //返回类型为Object类型,强制转换
        resp.getWriter().write("test:"+d+"<br/>");
    }
}

Servlet4.java

package com.li.servlet.include;

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 Servlet4 extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet4 doGet!");

        /*设置值,回传给s3*/
        req.setAttribute("test", Math.random());

        resp.getWriter().write("Servlet4你好<br/>");

    }
}

使用请求转发加载不出目的页面CSS文件的解决方法

当我们请求转发的目的页面是HTML文档或者JSP服务页面时,可能会出现一种情况,那就是页面的CSS文件或JS文件没有加载进去,那么这是上面问题呢?实际上这是路径的问题。

例如,假定我们的项目名称为:Store,当我们进入一个Servlet时(此Servlet的url-pattern为:do/servlet),重定向的目的JSP为:index.jsp。

该JSP页面中有以下引用:

<link rel="stylesheet" type="text/css" href="../../css/style.css" />
<link rel="stylesheet" type="text/css" href="../../css/shopping-mall-index.css" />
<script type="text/javascript" src="../../js/jquery.js"></script>
<script type="text/javascript" src="../../js/vin.js"></script>

在Servlet中的请求转发为:

request.getRequestDispatcher("../index.jsp").forward(request, response);

那么这样CSS和JS文件是加载不出来的,我们如果使用浏览器开发者工具查看,能发现这些文件报404错误,熟悉的人都知道这是什么错误,那么是什么文件没找到呢?有以下文件未找到:

http://localhost:8080/css/style.css
http://localhost:8080/css/shopping-mall-index.css
http://localhost:8080/js/jquery.js
http://localhost:8080/js/vin.js

问题分析:上面的URL中没有包含我们项目的名称,我们知道,请求转发地址栏不会改变(地址栏为http://localhost:8080/Store/do/servlet),而 href=”../../css/style.css” 此路径是相对于地址栏的路径,因而,实际上引用到的文件是 http://localhost:8080/css/style.css

问题解决:把引用文件的路径改为两种的一种即可:

href="../css/style.css"

href="/Store/css/style.css"
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值