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



用户在上面表单当中输入了信息之后,点击登录按钮(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. ConcurrentHashMap 1.8为什么要使用CAS+Synchronized取代Segment+ReentrantLock

    大家应该都知道ConcurrentHashMap在1.8的时候有了很大的改动,当然,我这里要说的改动不是指链表长度大于8就转为红黑树这种常识,我要说的是ConcurrentHashMap在1.8为什么 ...

  2. Bzoj2829 信用卡凸包

    Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 333  Solved: 155 Description Input ...

  3. [LeetCode] Reorder List 反向插入链表

    Given a singly linked list L: L0→L1→…→Ln-1→Ln,reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… You must do thi ...

  4. Day 30 process&thread_2

    进程和线程_2 1.继承类创建线程 import threading,time class Mythread(threading.Thread): #建立类,继承threading.Thread de ...

  5. Day 22 Object_oriented_programming 3

    isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象,如果是返回True 1 class F ...

  6. 将linlayout布局转为bitmap图片和保存

    1.首先新建路径 File filedirs = new File(Environment.getExternalStorageDirectory(), "/YuLin/"); i ...

  7. Java IO 学习(一)同步/异步/阻塞/非阻塞

    关于IO,同步/异步/阻塞/非阻塞,这几个关键词是经常听到的,譬如: “Java oio是阻塞的,nio是非阻塞的” “NodeJS的IO是异步的” 但是这些东西听多了就容易迷糊,比方说同步是否就是阻 ...

  8. 正确地使用GIT FORK

    摘自github官方网站,稍后我将抽空翻译. Fork a repo https://help.github.com/articles/fork-a-repo/ Syncing a fork http ...

  9. 线程和进程(Java)

    一.线程概述 线程是程序运行的基本执行单元.当操作系统(不包括单线程的操作系统,如微软早期的DOS)在执行一个程序时,会在系统中建立一个进程,而在这个进程中,必须至少建立一个线程(这个线程被称为主线程 ...

  10. luogu P3376 【模板】网络最大流(no)ek

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...