一件Java笔试题引发的蠢绝人寰的故事——转发和重定向

开端——小老弟着急了

  • 按正常作息,平时本人早晨八点起床。可今天不知怎么的,生物钟早了俩小时,揉揉惺忪的双眼,一大早就去微信学习群打卡去了,谁知道发了关键词“冲刺”后群机器人半天没反应。
  • 要说平时我是不会在意这些细节,可是今天我不一样,早起的人呐,正开心自己又向周公争取了一点学习时间,就耐不住寂寞弱弱问了句:今天机器人没开吗?
  • 很快我就收到群友及官方回应:“上午10:00-12:00打卡哦”、“小老弟着急了”…看到某个笑哭脸,瞬间感觉有点脸红,出了个小糗,就用表情包掩饰自己的尴尬,表情包上端庄、优雅、含蓄、斯文、乖巧、懂事的小人仿佛就是我。就是那个为了学习比谁打卡早的我。

一件Java笔试题引发的蠢绝人寰的故事——转发和重定向_第1张图片

发展——考点有点懵

过了一会终于到了10:00打卡时间,成功打卡后官方发布了今天的笔面试题——一道有关转发和重定向的考点选择题。

今日考点【java语言-java特性-传值&引用】的题目来啦,赶紧来和喵喵一起来讨论吧~

下面有关forward和redirect的描述,正确的是( )?
A.forward是服务器将控制权转交给另外一个内部服务器对象,由新的对象来全权负责响应用户的请求
B.执行forward时,浏览器不知道服务器发送的内容是从何处来,浏览器地址栏中还是原来的地址
C.执行redirect时,服务器端告诉浏览器重新去请求地址
D.forward是内部重定向,redirect是外部重定向
E.redirect默认将产生301 Permanently moved的HTTP响应

看到这么多字,先是头晕,然后纠结纠结,仔细看过后蹦出了一句话:

  • forward是转发,redirect是重定向。

在群里说了这句话后就火速前往IEDA,试一下一个Demo:点击index.jsp上的一个链接后跳转至show.jsp,其中用到了转发。

req.getRequestDispatcher("show.jsp").forward(req, resp);

结果是:
一件Java笔试题引发的蠢绝人寰的故事——转发和重定向_第2张图片
一件Java笔试题引发的蠢绝人寰的故事——转发和重定向_第3张图片

我就下了一个结论(错误示范):转发的地址栏根目录不变,拼接请求名,重定向是内部2次请求,会丢失作用域中的值,地址栏改变。

  • 完了我想,转发地址栏不变,应该就是前面localhost:8080/部分吧,请求名可能不算。还自我感觉特别良好,觉得自己是操作过的人,谁知道现在我觉得自己当时这个想法十分愚蠢

  • 当时完事儿了我就去看群里的讨论,发现大家在聊jsp,有小伙伴说jsp是前端,我就回复他jsp是简易版servlet。后来有小伙伴坚持说jsp是前端页面,于是我为了巧妙避开话题,就说:话说每日一题我不会哎,有人指点一下吗?

    其实我心里是想:我都会,你们不会的来问我吧。(事后才知道自己的弱小无知与愚蠢)

  • 这个话题顺利开启后大家都在说转发地址栏不会改变,还有一位小伙伴列举了转发和重定向的区别:

    转发和重定向的区别:
    1.从地址栏显示来说
    forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
    redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.
    2.从数据共享来说
    forward:转发页面和转发到的页面可以共享request里面的数据
    redirect:不能共享数据.
    3.从运用地方来说
    forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
    redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等.

高潮——一个诡异的问题

正沉浸在学习的激情中,我突然想到,转发地址栏显示不变啊,我那个为什么会从index.jsp变成getallstudents呢?就又弱弱的问了一句:有个疑问,转发跳转之后为什么地址栏中会显示请求名?

  • 这个问题都把群里一个小伙伴问懵了,问我是不是用了get请求……我看到这个回复也一脸懵,所以又去看了看自己的代码,确定确实是用的req.getRequestDispatcher("show.jsp").forward(req, resp);
  • 盯了好久自己的代码都没个结果,不想浪费时间了,打开了万能的百度,查了半天“为什么转发地址栏会显示请求名?”我当时觉得一定有人遇到过这个问题,可是查了半天,能查到才怪!这个问题真的很诡异,也是被自己气笑了。
  • 于是我到一个大佬刚成立不到一天的“Java初学解惑群”向大佬提问:
    一件Java笔试题引发的蠢绝人寰的故事——转发和重定向_第4张图片

来一起看看我的代码:

  • getallstudent请求的servlet代码:
    package web;
    
    import bean.Student;
    import service.StudentService;
    import service.StudentServiceImpl;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.List;
    
    /**
     * @author Elvira
     * @date 2020/11/16 20:48
     * @description
     */
    @WebServlet(value = "/getallstudents")
    public class StudentServlet extends HttpServlet {
           
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
           
            //1. 接收参数
            //2. 调取service方法
            StudentService studentService = new StudentServiceImpl();
            List<Student> allStudent = studentService.getAllStudent();
            //3. 跳转页面
            req.setAttribute("students",allStudent);
            req.getRequestDispatcher("show.jsp").forward(req, resp);
        }
    }
    
    
  • index.jsp代码:
    <%--
      Created by IntelliJ IDEA.
      User: Elvira
      Date: 2020/11/16
      Time: 20:47
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>主页title>
    head>
    <body>
    1、遍历表格:<a href="/getallstudents">studentsa><br>
    form>
    body>
    html>
    
    
  • show.jsp代码:
    	<%--
      Created by IntelliJ IDEA.
      User: Elvira
      Date: 2020/11/16
      Time: 23:12
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head>
        <title>Titletitle>
    head>
    <body>
    <h1>成功跳转至show.jsp页面h1>
    <table border="1" cellpadding="0" width="800px">
        <tr>
            <td>学员编号td>
            <td>学生姓名td>
            <td>学生年龄td>
        tr>
    <c:forEach items="${students}" var="stu">
        <tr>
            <td>${stu.studentNo}td>
            <td>${stu.stuName}td>
            <td>${stu.stuAge}td>
        tr>
    c:forEach>
    
    table>
    body>
    html>
    
    

看看以上代码明眼人都能看出哪里出了问题吧!

结尾——恍然大悟

!!!粗心大意
一件Java笔试题引发的蠢绝人寰的故事——转发和重定向_第5张图片
index.jsp中a标签先请求了/getallstudents。

1、遍历表格:<a href="/getallstudents">studentsa><br>
  • 这时url已经从index.jsp变成/getallstudents了。
  • 然后到了/getallstudents,才转发到show.jsp,这时候地址栏并没有发生改变。
    req.getRequestDispatcher("show.jsp").forward(req, resp);
    

真相大白!此外还需要了解:

forward只是把请求转发给了另外一个servlet,另外一个servlet处理完业务逻辑之后,会向外输出这个页面,输出的是数据流,所以页面地址不会变
redirect是客户端跳转的,所以会变
show.jsp不要把它当成是页面,它就是一个servlet

总结

今日每日一题你会了嘛?我是记住了转发和重定向了!

正确答案是 BCD
重定向是需要response将信息返回给浏览器,而请求转发是request对象的行为
1.从地址栏显示来说
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.
2.从数据共享来说
forward:转发页面和转发到的页面可以共享request里面的数据.
redirect:不能共享数据.
3.从运用地方来说
forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等.

你可能感兴趣的:(【笔试面试】初级Java知识点,【奇妙朵朵】学习中的神奇小故事,转发和重定向,redirect,forward,Java基础,Java转发与重定向)