部分内容转自:http://blog.csdn.net/zhouysh/article/details/380364和http://blog.csdn.net/frank_jay/article/details/51243481

1.RequestDispatcher.forward()

是在服务器端起作用,当使用forward()时,Servletengine传递HTTP请求从当前的Servlet or JSP到另外一个Servlet,JSP 或普通HTML文件,也即你的form提交至a.jsp,在a.jsp用到了forward()重定向至b.jsp,此时form提交的所有信息在b.jsp都可以获得,参数自动传递.

但forward()无法重定向至有frame的jsp文件,可以重定向至有frame的html文件,同时forward()无法在后面带参数传递,比如servlet?name=frank,这样不行,可以程序内通过response.setAttribute("name",name)来传至下一个页面.

重定向后浏览器地址栏URL不变.

因为完成一个业务操作往往需要跨越多个步骤,每一步骤完成相应的处理后,转向到下一个步骤。比如,通常业务处理在Servlet中处理,处理的结果转向到一个 JSP页面进行显示。这样看起来类似于Servlet链的功能,但是还有一些区别。一个RequestDispatcher对象可以把请求发送到任意一个服务器资源,而不仅仅是另外一个Servlet。

注意,只有在尚未向客户端输出响应时才可以调用forward()方法,如果页面缓存不为空,在重定向前将自动清除缓存。否则将抛出一个异常

2.response.sendRedirect()

是在用户的浏览器端工作,sendRedirect()可以带参数传递,比如servlet?name=frank传至下个页面,同时它可以重定向至不同的主机上,且在浏览器地址栏上会出现重定向页面的URL.

HttpServletResponse接口定义了可用于转向的sendRedirect()方法。代码如下:

public void sendRedirect(java.lang.String location)throws java.io.IOException

这个方法将响应定向到参数location指定的、新的URL。location可以是一个绝对的URL,如response.sendRedirect ("http://java.sun.com")也可以使用相对的URL。如果location以"/"开头,则容器认为相对于当前Web应用的根,否则,容器将解析为相对于当前请求的URL。这种重定向的方法,将导致客户端浏览器的请求URL跳转。从浏览器中的地址栏中可以看到新的URL地址,作用类似于上面设置HTTP响应头信息的实现

sendRedirect()方法是通过浏览器重定向的,所以第二个JSP页面中获得的request并非是前一个页面的request(两次请求生成了前后两个不同的 request对象了)。sendRedirect()是请求从定向,和超连接是一个意思,比如你在A页面中写一个request.setAtribute,sendRedirect到B页面,就是说服务器从A页面中给你一个response,然后你的浏览器再去request到B页面,由于有两次request和response,是不能在B页面取到request.setAtribute里的值,能从地址栏看到url的改变。

request.getRequestDispatcher().forward(request,response)是请求分发器,比如你在A页面中写一个request.setAtribute,request.getRequestDispatcher().forward(request,response)到B页面,那就是说服务器给你的response是B页面的,并且只有一次request和response,所以是能在B页面取到request.setAtribute里的值,地址栏的url仍然是A页面的。

所以通常情况下,setAttribute()方法都和RequestDispatcher.forward()都在一起使用

看例子:

一个简单的登录界面,这里是个登录的servlet:

package com.library.service;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import com.library.dao.LoginDao;
import com.library.po.Librarian; public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L;
LoginDao loginDao = new LoginDao();//引入持久层 @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
super.doGet(req, resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
String userName = req.getParameter("inputAccount");
String password = req.getParameter("inputPassword");
System.out.println("#############test:userName:"+userName+" password:"+password);
Librarian user = loginDao.loginSuccess(userName, password); if(user==null) {//不存在,登录失败
Librarian userFail = new Librarian(userName, password);
HttpSession session = req.getSession();
req.setAttribute("theUser", userFail);
session.setAttribute("theUser", userFail);
System.out.println("Login Failed");
req.getRequestDispatcher("/templates/loginFail.jsp").forward(req, resp);
} else {
HttpSession session = req.getSession();
req.setAttribute("theUser", user);
session.setAttribute("theUser", user);
System.out.println("Login Success!");
resp.sendRedirect("/TestWeb/templates/mainPage.jsp");
}
}
}

其中登录成功的页面是通过req.getRequestDispatcher("/templates/loginFail.jsp").forward(req, resp);来重定向的

而登录失败页面是通过resp.sendRedirect("/TestWeb/templates/mainPage.jsp");来重定向的。

分别在登录成功页面和登录失败页面用session和request来获得数据

登录失败:

<body>
<h1>登录失败</h1>
<%
Librarian user = (Librarian)request.getAttribute("theUser");
out.print("test in the dispatcher:<br>");
%>
userName:<%=user.getUserName() %><br>
password:<%=user.getPassword() %><br><br> <%
Librarian user2 = (Librarian)session.getAttribute("theUser");
out.print("test in the session:<br>");
%>
userName:<%=user2.getUserName() %><br>
password:<%=user2.getPassword() %><br> </body>

登录成功:

<body>
<h1>成功登录!</h1> <%
//Librarian user = (Librarian)request.getAttribute("theUser");
//out.print("test in the dispatcher:<br>");
%> <%-- userName:<%=user.getUserName() %><br>
password:<%=user.getPassword() %><br>
age:<%=user.getAge() %><br> --%> <%
Librarian user2 = (Librarian)session.getAttribute("theUser");
out.print("test in the session:<br>");
%>
userName:<%=user2.getUserName() %><br>
password:<%=user2.getPassword() %><br>
age:<%=user2.getAge() %><br>
position:<%=user2.getPosition() %><br><br> </body>

结果是在登录失败页面两种方法都可以访问到user的信息,并且界面跳转后仍然是servlet的url(/login是form的action的url):

而登录成功页面只能在session中访问的到,而且url变了:

说明forward只有一次请求和回应,所以在重新定向的页面可以通过request访问的到之前request.setAttribute的数据,且url没变。

而sendRediect跟超链接其实是一个意思,从A页面sendRedirect到B页面,就是说服务器从A页面中给你一个response,然后你的浏览器再去request到B页面,由于有两次request和response,是不能在B页面取到request.setAtribute里的值,能从地址栏看到url的改变。

forward和sendRedirect的区别的更多相关文章

  1. JSP的getRequestDispatcher()与sendRedirect()的区别

    getRequestDispatcher()与sendRedirect()的区别   1.request.getRequestDispatcher()是请求转发,前后页面共享一个request ; r ...

  2. 细谈getRequestDispatcher()与sendRedirect()的区别

    问题?细谈getRequestDispatcher()与sendRedirect()的区别 首先我们要知道: (1)request.getRequestDispatcher()是请求转发,前后页面共享 ...

  3. difference between forward and sendredirect

    Difference between SendRedirect and forward is one of classical interview questions asked during jav ...

  4. Forward与include的区别

    Forward与include的区别 <jsp:include>标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入. < ...

  5. forward和redirect的区别?http状态码301,302分别代表什么?

    一.forward和redirect的区别 从地址栏显示来说:forward是服务器内部重定向,客户端浏览器的网址不会发生变化:redirect发生一个状态码,告诉服务器去重新请求那个网址,显示的的新 ...

  6. MVC - forward 和 redirect 的区别

    MVC - forward 和 redirect 的区别 forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服 ...

  7. response.sendRedirect(url)与request.getRequestDispatcher(url).forward(request,response)的区别

    response.sendRedirect(url)跳转到指定的URL地址,产生一个新的request,所以要传递参数只有在url后加参数,如: url?id=1.request.getRequest ...

  8. <jsp:forward>、requestDispatcher和sendRedirect()的区别

    1.会话信息保存在服务器内存上,可以断续访问,和cookie相比,其保存在服务器上. 2.男人就像蓝牙:只有在你接近时,他才会找上你.当你离开后,他便又去找其他的"设备"了.女人就 ...

  9. response.sendRedirect()和request.getRequestDispatcher().forward(request,response)的区别

    转发方式:request.getRequestDispatcher().forward(); 重定向方式:response.sendRedirect();  下面是HttpServletRespons ...

随机推荐

  1. 在C/C++中使用VLD检测内存泄漏

    VLD地址:https://kinddragon.github.io/vld/ 若出现内存泄漏,VS输出窗口会有如下提示: 若要确定造成内存泄漏的代码位置,仅需进入工程属性->链接器->调 ...

  2. spring cloud config 属性加解密

    首先需要(Java Cryptography Extension (JCE))的支持,下载路径: https://www.oracle.com/technetwork/java/javase/down ...

  3. 自定义表单SQL命令行批量删除垃圾留言

    1.每天被恶意留言困扰,花费大量的时间去清理却效果不理想,对于没有能力做二次开发并且靠纯手工删除留言的菜鸟来讲是一个大麻烦. 2.大家都知道织梦的留言内容是存在数据库里的,而数据库的内容是可以批量删除 ...

  4. codeforces 435 B. Pasha Maximizes 解题报告

    题目链接:http://codeforces.com/problemset/problem/435/B 题目意思:给出一个最多为18位的数,可以通过对相邻两个数字进行交换,最多交换 k 次,问交换 k ...

  5. jstl标签: c:Foreach详解

    为循环控制,它可以将集合(Collection)中的成员循序浏览一遍.运作方式为当条件符合时,就会持续重复执行的本体内容. 为循环控制,它可以将集合(Collection)中的成员循序浏览一遍.运作方 ...

  6. .NET 4.0 System.Threading.Tasks学习笔记

    由于工作上的需要,学习使用了System.Threading.Tasks的使用,特此笔记下来. System.Threading.Tasks的作用: Tasks命名空间下的类试图使用任务的概念来解决线 ...

  7. hdu-5718 Oracle(水题)

    题目链接: Oracle Time Limit: 8000/4000 MS (Java/Others)     Memory Limit: 262144/262144 K (Java/Others) ...

  8. SPOJ:String Play (?)

    String Play Milo has a string S of length L. Tutu picks a random prefix and Mota picks a random suff ...

  9. 「LuoguP2170」 选学霸(01背包

    Description 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一部分没有,同学们就会抗议.所以老师想请你帮他求出他该选多少学霸,才能既不让同学们抗议, ...

  10. Python测试框架doctest

    doctest是python自带的一个模块.本博客将介绍doctest的两种使用方式:一种是嵌入到python源码中,另外一种是放到一个独立文件. doctest 的概念模型 在python的官方文档 ...