servlet转发与重定向基本概念与区别

1.转发与重定向概念介绍

1.1转发

浏览器的请求发送给组件1,组件1经过一些处理之后,将request和response对象“传递”给组件2,由组件2继续处理,然后输出响应(当然,也可以继续向其他组件“传递”),这个传递的过程称之为“转发”。

转发过程:客户浏览器发送http请求—-》web服务器接受此请求–》调用内部的一个方法在容器内部完成请求处理和转发动作—-》将目标资源发送给客户。

整个过程只涉及一次浏览器和服务器之间的“请求-响应”,转发过程中的组件共享同一个请 求(request)和响应(response)对象。

转发的意义在于可以实现组件的“分工”。在基于MVC,多层结构的Web应用中,经常需要多个组件协同完成一次“请求-响应”工作。

RequestDispatcher对象封装了转发操作。通过request的getRequestDispatcher(String path)方法获得RequestDispatcher对象,其中String类型参数path表示要转发到的地址。调用Dispacther对象的 forward(request, response)方法实现转发。关于转发的具体操作,有如下几点需要注意:

  • 转发只能在同一个应用的组件之间进行,不可以转发给其他应用的地址。
  • 转发的地址可以用“相对地址”方式,也可以用“绝对地址”方式。但需要注意的是:用绝对地址方式时,应从应用名后(Context path)开始。例如:要转发到的地址为:http://192.168.5.100/tst/jsp/somewhere.jsp (其中tst为应用名),对应的绝对地址为:“/jsp/somewhere.jsp”。这是很好理解的,因为转发只能转到本应用内的地址,所以绝对地址是没有必要包含应用名的。
  • 组件之间通过转发来分工协作,势必涉及数据的传递,可以通过request对象传递数据。request对象的setAttribute和getAttribute分别用于以“名称-对象对”的形式存取数据。
  • 在一个组件转发给另外一个组件之前,通过response输出的响应内容是没有意义的。在转发之前的通过out对象输出的内容最终不会输出到浏览器,这是由于RequestDispatcher在转发之前清空了输出缓冲区。但如果在转发之前输出的信息超出了缓冲区,或者调用了 out对象的flush()方法,此响应内容已经输出到了客户端(称之为响应信息已提交),此时如果实施转发操作会抛出运行时异 常:java.lang.IllegalStateException。

1.2重定向

浏览器向某组件发出请求信息,组件向浏览器发回一个重定向响应信息,该响应信息不包含具体的数据内容,只是在响应头信息中包含了需要重定向到的地址信息,该地址可以是任何有效的URL。浏览器收到该重定向响应后会自动的向响应信息头中所指示的地址发出请求。整个重定向的过程涉及两次“请求-响应”。

重定向过程:客户浏览器发送http请求—-》web服务器接受后发送302状态码响应及对应新的location给客户浏览器–》客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址—-》服务器根据此请求寻找资源并发送给客户。

重定向可以通过response的sendRedirect(String url)方法来实现,注意String类型的参数url表示重定向到的地址,需要注意的是,如果表示重定向到本应用内的一个绝对地址时,要从应用名前开始,例如:tst应用中的某个组件要重定向到本应用内的/jsp/somewhere.jsp,则重定向的绝对地址应该是:“/tst/jsp /somewhere.jsp”这一点和转发中的绝对地址表示是不同的。关于重定向的具体操作,有如下几点需要注意:

  • 使用response.sendRedirect时,前面不能有HTML输出。这并不是绝对的,不能有HTML输出其实是指不能有HTML被送到了浏览器。事实上现在的server都有cache机制,一般在8K(我是说JSP  SERVER),这就意味着,除非你关闭了cache,或者你使用了out.flush()强制刷新,那么在使用sendRedirect之前,有少量的 HTML输出也是允许的。
  • response.sendRedirect之后,应该紧跟一句return;
    我们已经知道response.sendRedirect是通过浏览器来做转向的,所以只有在页面处理完成后,才会有实际的动作。既然你已经要做转向了,那么后的输出还有什么意义呢?而且有可能会因为后面的输出导致转向失败。

1.3转发与重定向的区别

  • (1)请求转发是一次请求一次响应,而重定向是两次请求两次响应;

  • (2)请求转发地址栏不会改变,而重定向地址栏会显示第二次请求的地址;

  • (3)请求转发只能转发给本项目的其他资源,而重定向不仅可以重定向到本项目的其他资源, 还可以重定向到其他项目;

  • (4)请求转发是服务器端的行为,转发时只需要给出转发的资源路径即可,如Servlet的访问路径;而重定向需要给出全路径,即路径要包含项目名;

  • (5)请求转发比重定向的效率高,因为请求转发是一个请求。在以后的开发中,如果需要地址栏的地址发生改变,就选择重定向;如果需要在Servlet之间通过request域进行数据通信,就选择请求转发。

2.请求转发与响应重定向的种类

有两种方式获得Servlet 转发对象(RequestDispatcher):

1)一种是通过HttpServletRequest的getRequestDispatcher()方法获得;
2)一种是通过ServletContext的getRequestDispatcher()方法获得。 Servlet

重定向的方法只有一种:HttpServletResponse的sendRedirect()方法。

3.请求转发与响应重定向中路径参数区别

假设通过http://localhost/myApp/cool/bar.do 请求到达该方法所属的Servlet。
3.1请求转发
◆HttpServletRequest.getRequestDispatcher(String)
参数可以指定为相对路径或绝对路径。

  • 相对路径情况下容器相对于原来请求URL的目录加参数来生成完整的URL——http://localhost/myApp/cool/foo/stuff.do。。
  • 绝对路径与Servlet重定向不同,容器将相对于Web应用的根目录加参数生成完整的URL(即“/”根路径就是相对于虚拟路径)这是因为转发是在服务器内部进行的,写绝对路径/开头指的是当前的Web应用程序。即:request.getRequestDispatcher(“/foo/stuff.do”)生成的URL是http://localhost/myApp/foo/stuff.do

◆ ServletContext.getRequestDispatcher(String)
- 参数只能指定为绝对路径,生成的完整URL与HttpServletRequest.getRequestDispatcher(String)相同。

3.2响应重定向
◆ HttpServletResponse.sendRedirect(String)
参数可以指定为相对路径、绝对路径或其它Web应用。

  • 相对路径:response.sendRedirect(“foo/stuff.do”),容器相对于原来请求URL的目录加参数来生成完整的URL——http://localhost/myApp/cool/foo/stuff.do

  • 绝对路径:response.sendRedirect(“/foo/stuff.do”),容器相对于Web应用本身加参数建立完整的URL,这是因为
    重定向response.sendRedirect(“”)是服务器向客户端发送一个请求头信息,由客户端再请求一次服务器,请求是在服务器外进行的,即完整的url是——http://localhost/foo/stuff.do

  • 其它Web应用:response.sendRedirect(“http://www.xxx.com “)容器直接定向到该URL。

3.3JSP 提交表单给 Servlet 路径问题
JSP页面提交表单给Servlet时,路径的写法要格外注意。

假如说,你工程名字为HibernateApp3,JSP页面提交表单给servlet时有两种写法:

  • 相对路径: <form action=servlet/addStudent method=post>...</form>
  • 绝对路径: <form action="/HibernateApp3/servlet/addStudent"
    method=post>...</form>
    或者 <form action="<%=request.getContextPath() %>/servlet/addStudent" method=post>...</form>

注意:/代表根目录,如果路径是使用/开头,Tomcat就是webApp那个目录,如果你不是/开头代表你从当前工程的目录开始,例如:webApp/HibernateApp3/。

附、<a href>的路径如果是”/”开头,则表示相对于主机,如果不是则表示相对于当前请求。

综上所述:这里最最关键的要能清楚 发出请求目的资源的请求是在服务器内部还是服务器外部:内部时,“/”就是项目的虚拟目录;外部时,“/”就是代表主机的根目录

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值