假设一个登录系统,要求用户输入用户名和密码:



用户在上面表单当中输入了信息之后,点击登录按钮(type="submit")将表单作为请求参数进行提交。

这一提交就有两种形式:getpost

GET:显式获取,请求参数明晃晃地放入url(以?开始)中,通过TCP链接传给目标服务页。

POST:分邮获取,先向目标服务器发出请求首部,如获得肯定答复(816 I'm a teapot! 100 Continue)之后向目标服务页发出请求体,请求体被暗含。

一般出于一定安全性和功能性考虑(URL的长度有限直接导致GET自身的局限性),像这种登录请求一般都通过POST发送,而且POST可以进行请求信息的编码,而GET只有一种编码方式(也是因为URL的编码方式有限),但如果只是用于用户查询的这种临时性的信息出于速度考虑会使用GET(因为GET是直接发出一次请求)。

当然,这不是今天讨论的重点

我们使用POST(仅讨论这种方式)方式发出请求信息,服务端页面内部嵌入的JSP代码或服务端后台的Servlet代码(实际上,JSP严格说属于后台代码,因为JSP可以等价为一个Servlet,只不过通常处理前端业务)就开始处理请求,服务端处理请求之后就要进行验证处理,如果验证通过就会以这个用户信息登录。

于是我们有了这样的局面:

如果登录正确,则服务端将主页(index.jsp)呈现到用户(客户端)面前,否则将错误登录的页面(error.jsp)提示给用户。

然而,请求的处理方式就有了两种:请求转发(Request Dispatch)重定向(Redirection)

  1. 请求转发:服务端LoginServlet收到来自于login.jsp的请求,LoginServlet对请求的信息进行验证,根据验证结果,通过请求分发器(Request Dispatcher)将登录的请求信息分发到index.jsperror.jsp(下文简称结果页
  2. 重定向:服务端LoginServlet收到来自于login.jsp的请求,LoginServlet对请求的信息进行验证,根据验证结果,服务端向客户端发出重定向到对应页面的响应(301 Redirect),客户端收到重定向响应之后进行第二次请求发送。

显然,这两个过程的事情是不一样的,其结果也不一样。

请求转发

小明:李华,麻烦告诉物理老师一声,下节物理课改成体育了

李华:但是,我是英语课代表,你应该去找牛顿同学,他知道物理老师的办公室,这样吧我帮你转告给他(默记:下节物理课改成体育了)。

李华找到了牛顿同学

李华:牛顿,告诉物理老师一声,(回想到默记内容:下节物理课改成体育了),下节物理课改成体育了

牛顿:(默记:下节物理课改成体育了)好的,我把这个消息转告物理老师

请求转发正是这样的一个类似于传火的过程:

login.jsp将用户的登录信息封成一个请求发送给LoginServletLoginServlet检查无误之后就把这个请求随手转发给了index.jsp,这样一来index.jsp能够知道:

啊,原来是那个该死的管理员登录了呢,我真恨不得踢他的屁股呢。

也就是说,请求的信息在转发过程中是被保留下来的,这固然是很好的。

请求转发通过Servlet的request内置对象(主要负责请求的处理)的getDispatcher(url).forward(requ,resp)方法实现。表示向url页面转发请求。requresp参数通常直接填写requestresponse这两个内置对象,表示对当前的请求和响应进行传递。

由于请求转发是在服务端完成的,服务端将结果页作为一个response整体返回,因此客户端根本察觉不到任何事情,地址栏指示为处理该请求的Servlet的URI。

这也无形中埋下了一个隐患,由于请求是一脉相承的,因此一旦用户在这个过程中一个不小心按了一下F5(刷新),整个转发过程要重新走一遍,假设这个请求处理购买业务,那将是非常致命的(比如重复购买和重复支付)。

重定向

小明:李华,麻烦告诉物理老师一声,下节物理课改成体育了

李华:(心不在焉)我是英语课代表,你找错人了,自己跟物理课代表牛顿同学说去。

吃了个闭门羹,小明一脸尴尬的找到了牛顿同学

小明:牛顿同学……

牛顿:嗯??怎么了??

小明:……(唉??我要说啥来着O.O……)

重定向是一种服务端的响应(Response),HTTP中规定的重定向的响应信息是3系的(301 Permanent moved302 Found)。

重定向,顾名思义,就是新确你的请求方,比如说,本来你在地址栏里敲的AAA.com(纯属虚构,如有雷同不胜荣幸),但是AAA.com因业务调整迁移到了BBB.com,这种情况下服务商通常会保留AAA.com的域名然后在此域名下提供一个重定向将你带到BBB.com。

重定向的响应服务端发出,但重定向之后的请求仍然由客户端发出。

重定向方式是通过内置对象responsesendRedirect(url)方法实现,因为根据HTTP的规定,一个规范的重定向响应必须包含一个重定向的目标地址[RFC 2616]。

The new permanent URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s).

HTTP/1.1 301 Moved Permanently
Location: http://www.example.org/index.asp

url就是规范中规定的目标地址。

但是,这个url本身也就代表了客户端的第二次访问请求,但通常重定向信息中仅仅包含目标页面的URL,将此URL作为新的访问请求时,原本的登录信息就不复存在了(因为新的访问请求不包含这些内容)。

这样一来,即使登录成功,index.jsp也无从知晓是谁登录了,他只能知道的是:

好像有个很厉害的家伙登录了耶,是谁呢,算了老实装死就好了。

综上,重定向的方式会导致请求丢失(Request Loss)

但这个问题应该有办法解决吧

确实如此,回顾一下上面的GET请求方式,

GET:显式获取,请求参数明晃晃地放入url(以?开始)中,通过TCP链接传给目标服务页。

这也就意味着,我可以把从POST获取的请求再重新以GET的方式塞入URL中,这样反馈给客户端重新发送的请求就再一次包含了之前的信息。

但是!

正如前面所说的,由于GET和POST之间的差异,这种做法可能会带来某种风险。

那么我看X度啦,X宝啦,都不会出现上面两种情况呢

其实,作为登录功能,一般还是青睐采用重定向的方式(其实教务处的CAS认证跳转也是重定向的方式),毕竟登录了一溜十三招,发现地址栏还是那个位置似乎也是非常的古怪。

但是正如前面所说的,重定向有信息丢失的风险,因为重定向的内容往往不包含登录信息。

于是乎另一个内置对象就有了作用——会话(Sessions)

会话是服务端在服务器上创建的一个对象,专门用于对一个具体用户进行交互,可以简单理解为一个一对一服务员

既然重定向会导致信息丢失,那么就在重定向之前在服务端创建一个会话,在会话中指明登录的信息,这样重定向之后,会话内容在服务端自然是不会丢失的,而用户重新访问页面的时候直接从会话读取登录信息就可以了。

【Servlet与JSP】请求转发与重定向的更多相关文章

  1. Servlet中的请求转发和重定向

    跳转和重定向 有的时候客户端请求到达服务端后需要对请求重新转发到其它Servlet甚至别的服务器,这就需要跳转和重定向. 区别 一般来说,跳转是服务器内部跳转,例如将请求从一个Servlet转发给另外 ...

  2. jsp请求转发与重定向区别小结

    1.当使用转发时,JSP容器将使用一个内部方法来调用目标页面,新的页面继续处理同一个请求,而浏览器不会知道这个过程; 2.重定向是第一个页面通知浏览器发送一个新的页面请求. 3.转发不改变URL,重定 ...

  3. JSP中的请求转发与重定向

    在说请求转发和重定向之前,得了解下JSP九大内置对象中的response和request response:将服务器端数据发送到客户端,可通过在客户端浏览器中显示,用户浏览页面的重定向以及在客户端创建 ...

  4. Spring MVC 3.0 请求转发和重定向

    首先看一下如何获得request对象.session对象: 普通的Controller类,示例代码如下: @Controller @RequestMapping(value = "user& ...

  5. HttpServletRequest 接口、HttpServletResponse 接口、请求转发与重定向

    上篇文章我们讲了servlet的基本原理,这章将讲一下剩余的部分. HttpServletRequest 接口 该接口是 ServletRequest 接口的子接口,封装了 HTTP 请求的相关信息, ...

  6. ServletRequest HttpServletRequest 请求方法 获取请求参数 请求转发 请求包含 请求转发与重定向区别 获取请求头字段

      ServletRequest 基本概念 JavaWeb中的 "Request"对象  实际为   HttpServletRequest  或者  ServletRequest, ...

  7. 04_web基础(六)之请求转发与重定向

    1.交互方式 Web组件之间跳转: 从AServlet 跳转到 BServlet. 三种类型: 1:请求转发(forward) 2:URL重定向(redirect) 3:请求包含(include) 3 ...

  8. spring mvc 请求转发和重定向(转)

    spring mvc controller间跳转 重定向 传参 url:http://zghbwjl.blog.163.com/blog/static/12033667220137795252845/ ...

  9. spring mvc 请求转发和重定向

    spring mvc controller间跳转 重定向 传参 url:http://zghbwjl.blog.163.com/blog/static/12033667220137795252845/ ...

  10. web之请求转发与重定向

    请求转发: 重定向:

随机推荐

  1. Intellij热部署插件JRebel

    Intellij热部署插件JRebel 安装JRebel 激活JRebel 相关设置 Intellij热部署插件JRebel 项目需求,一直用eclipse的我,也要改用IDEA了,一开始,很不习惯. ...

  2. rpm包安装mysql5.6.*版本

    1.查看是否已经安装Mysql rpm -qa | grep -i mysql #删除已经安装的Mysql程序 rpm -ev *****.rpm 2.检查是否还有残留mysql文件夹 find / ...

  3. 【HDOJ5520】Number Link(费用流)

    题意:NxM的格子有些上面有数字,现在要把奇数跟偶数配对连起来,其他的格子连成一个个回路, 单独的相邻两个格子相连也算是一个回路按两条边算,连线不能相交, 给出相邻两个格子相连的费用,求最小的总费用, ...

  4. [LeetCode] Search in Rotated Sorted Array II 二分搜索

    Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would this ...

  5. [LeetCode] Minimum Depth of Binary Tree 二叉树最小深度

    Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shor ...

  6. Python学习杂记_2_格式化字符串的一些操作

    name=input("Please input your name: ") sex=input("Please input your sex: ") prin ...

  7. 通过vSphere-client虚拟化服务器

    一.什么是vClientvClient是vSphere的重要组件之一.用于用户连接ESXi或vCenter管理和分配vSphere的各种资源.有vClient和WebvClient两个版本.安装部署了 ...

  8. hdu 1788(多个数的最小公倍数)

    Chinese remainder theorem again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 ...

  9. Codeforces Gym101063 C.Sleep Buddies (2016 USP-ICMC)

    C.Sleep Buddies It is nighttime in the Earth Colony on Mars and everyone is getting ready to sleep. ...

  10. Atcoder Contest 015 E

    题目大意 给定一条数轴. 数轴上有\(n\)个点, 它们的初始位置给定, 移动速度也给定. 从0时刻开始, 所有点都从其初始位置按照其移动速度向数轴正方向移动. 这些点开始时可能是红色的, 也可能是黑 ...