接着昨天的来复习,昨天复习到了请求转发和请求重定向。

我们先来讲请求转发:

什么叫请求转发呢,你可以这样理解:一个人想去柜台2办事,但是他必须先经过柜台一拿到章才可以(拿柜台2要用的数据),经过柜台1拿到章后再

"问路"到柜台2,拿到想要的东西,再返回。这整个过程就叫做请求转发。

JavaWeb----知识点总结2_html

我们在web.xml配置好路径后在servlet程序中这样配置:

public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求的参数查看
        String username = req.getParameter("username");
        System.out.println("在Servlet1查看参数; " + username);

        //使用域数据,传递到Servlet2
        req.setAttribute("key","柜台1的章");

        //问路 : Servlet2怎么走
        /**
         * 请求转发必须要以/开头  斜杠表示地址  映射到idea代码的web目录  后面就是资源的路径
         */
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/serv2");

        //走向Servlet2
        requestDispatcher.forward(req,resp);

    }
}

其中要注意:

/**
 * 请求转发
 *  setAttribute(key,value)  :  设置域数据
 *  getAttribute(key)  :  获取域数据
 *  getRequestDispatcher()  :  获取请求转发对象
 */

我们在serv2中这样设置:

public class Servlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        System.out.println("在Servlet2中查看参数:" + username);

        //查看柜台1是否盖章
        String key = (String) req.getAttribute("key");
        System.out.println("柜台1是否有章:" + key);

        //处理自己的业务
        System.out.println("Servlet2处理自己的业务");
    }
}

在浏览器中输入如下地址并跳转:

http://localhost:8080/demo/serv1?username=123

控制台会这样输出:

在Servlet1查看参数; 123
在Servlet2中查看参数:123
柜台1是否有章:柜台1的章
Servlet2处理自己的业务

我们可以根据代码观察到我们确实在serv1中设置的域数据被serv2获取到了,并且确实跳转到了serv2。

请求转发的特点:

/**
 * 请求转发
 * 特点:
 * 1、浏览器地址栏没有变化
 * 2、他们是一次请求
 * 3、他们共享Request域中的数据
 * 4、可以转发到 WEB-INF 目录下
 */

但是请求转发可能会遇到问题:
比如我们在web中这样设置网页:

路径是  webapp/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
  这是web下的index.html  <br/>
  <a href="a/b/c.html">a/b/c.html</a>
  <a href="http://localhost:8080/demo/forwardC">请求转发 : a/b/c.html</a>
</body>
</html>

路径是  webapp/a/b/c.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
  这是a下的b下的c.html页面<br/>
  <a href="../../index.html">跳回首页</a>
</body>
</html>

web.xml配置好路径/forwardC后这样配置servlet程序:

 @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("经过了ForwardC程序");
        req.getRequestDispatcher("/a/b/c.html").forward(req,resp);
    }
}

JavaWeb----知识点总结2_数据_02

我们点击第一个a标签后出现这样的页面:

JavaWeb----知识点总结2_ide_03

 点击跳回首页确实可以跳转到刚刚那个页面,但是如果我们点击请求转发:a/b/c.html再点击跳回首页却出现了网页404。

这是为什么呢?

这是因为我们使用请求转发的时候页面地址是

http://localhost:8080/demo/forwardC

如果这个时候我们再点击页面内的a链接它是这样跳转的:

<a href="../../index.html">跳回首页</a>

就跳转到了:

http://localhost:8080/index.html

这显然是一个错误的资源路径,所以才会出现404问题。

那我们该如何解决这样的问题呢,很简单,只要在webapp/a/b/c.html页面内加一行这样的代码:

 <base href="http://localhost:8080/demo/a/b/">

这样你页面的任何跳转都是参照这个地址来进行跳转,这样就可以实现请求转发的顺利跳转了。

 

请求重定向:

/**
 * 请求重定向
 * 请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说,我给你一些地址,你去新地址访问,就是请求重定向
 * (因为之前的地址可能已经废弃了)
 *
 * 特点:
 * 1、浏览器地址栏会发生变化
 * 2、两次请求
 * 3、不共享request域中的数据
 * 4、不能访问WEB-INF下的资源
 * 5、可以访问当前工程以外的资源
 */

如图:
JavaWeb----知识点总结2_ide_04

代码示例:

我们在web.xml中配置好/response1和/response2后

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("曾经到此一游  Response1");

        req.setAttribute("key","陈柏宇");
        //设置响应状态码302
        //resp.setStatus(302);

        //设置响应头,说明新的地址在哪里
        //resp.setHeader("Location","http://localhost:8080/demo/WEB-INF/a.html");

        resp.sendRedirect("http://localhost:8080/demo/response2");
    }

response2:

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("response2's result");
        System.out.println(req.getAttribute("key"));
    }

我们在浏览器输入如下网址:

http://localhost:8080/demo/response1

最终我们跳转到了

http://localhost:8080/demo/response2

这里说明一点,请求重定向是无法访问WEB-INF目录下的内容的

控制台输出:

曾经到此一游  Response1
null

 这说明我们在response1中设置的requset域数据根本就没有被response2获取到。

 

总结一下请求转发和请求重定向的区别:

1.请求的转发:地址栏是初次发出请求的地址。

  请求的重定向:地址栏不是初次发出请求的地址,为最后响应的地址。

2.请求转发:在最终的Servlet中,request和中转的那个request是同一个对象。

  请求的重定向:在最终的Servlet中,request和中转的那个request不是同一个对象。

3.请求转发:只能转发给当前web应用的资源。

  请求的重定向:可以重定向到任何资源(除了WEB-INF目录下的资源)。

4.请求的转发:/代表的是当前web应用的根目录。

  请求的重定向:/代表的是当前web站点的根目录。