一件Java笔试题引发的蠢绝人寰的故事——转发和重定向
Posted 美少女降临人世间
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一件Java笔试题引发的蠢绝人寰的故事——转发和重定向相关的知识,希望对你有一定的参考价值。
开端——小老弟着急了
- 按正常作息,平时本人早晨八点起床。可今天不知怎么的,生物钟早了俩小时,揉揉惺忪的双眼,一大早就去微信学习群打卡去了,谁知道发了关键词“冲刺”后群机器人半天没反应。
- 要说平时我是不会在意这些细节,可是今天我不一样,早起的人呐,正开心自己又向周公争取了一点学习时间,就耐不住寂寞弱弱问了句:今天机器人没开吗?
- 很快我就收到群友及官方回应:“上午10:00-12:00打卡哦”、“小老弟着急了”…看到某个笑哭脸,瞬间感觉有点脸红,出了个小糗,就用表情包掩饰自己的尴尬,表情包上端庄、优雅、含蓄、斯文、乖巧、懂事的小人仿佛就是我。就是那个为了学习比谁打卡早的我。
发展——考点有点懵
过了一会终于到了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);
结果是:
我就下了一个结论(错误示范):转发的地址栏根目录不变,拼接请求名,重定向是内部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初学解惑群”向大佬提问:
来一起看看我的代码:
- 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">students</a><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>Title</title> </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>
看看以上代码明眼人都能看出哪里出了问题吧!
结尾——恍然大悟
!!!粗心大意
index.jsp中a标签先请求了/getallstudents。
1、遍历表格:<a href="/getallstudents">students</a><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笔试题引发的蠢绝人寰的故事——转发和重定向的主要内容,如果未能解决你的问题,请参考以下文章