1.转发(Forward)
1.1 转发的原理
转发的原理如下图所示:
浏览器的请求发送给组件1,组件1经过一些处理之后,将请求传递“传递”给组件2,由组件2继续处理,然后输出响应(当然,也可以继续向其他组件“传递”),这个传递的过程称之为“转发”。整个过程只涉及一次浏览器和服务器之间的“请求-响应”。
这种方式是在服务器端作的重定向。服务器往client发送数据的过程是这样的:服务器在向客户端发送数据之前,是先将数据输出到缓冲区,然后将缓冲区中数据发送给client端。什么时候将缓冲区里的数据发送给client端呢?(1)当对来自client的request处理完,并把所有数据输出到缓冲区,(2)当缓冲区满,(3)在程序中调用缓冲区的输出方法out.flush()或response.flushbuffer(),web container才将缓冲区中的数据发送给client。
这种重定向方式是利用服务器端的缓冲区机制,在把缓冲区的数据发送到客户端之前,原来的数据不发送,将执行转向重定向页面,发送重定向页面的数据,重定向调用页的数据将被清除。如果在forward之前有很多输出,前面的输出已使缓冲区满,将自动输出到客户端,这时候会抛出IllegalStateException。因此,forward之前尽量不要使用out.println()语句向客户端输出结果。
1.2 转发的应用
转发(Forward)是通过RequestDispatcher对象的forward(HttpServletRequest req,HttpServletResponse res)方法来实现的。RequestDispatcher可以通过HttpServletRequest的getRequestDispatcher()方法获得。getRequestDispatcher()方法的参数必须以“/”开始,“/”表示本Web应用程序的根目录。eg:
RequestDispatcher dispatcher=request.getRequestDispatcher("/ServletB");
dispatcher.forward(request, response);
上述代码是在ServletA中跳转到ServletB,在控制台打印出ServletA和ServletB中的request和response对象如下图所示:
从图中可以看出,组件1和组件2拿到的HttpRequest对象不是同一个,但是组件2的HttpRequest对象可以获取组件1的HttpRequest对象的内容。组件1和组件2拿到的HttpResponse对象是同一个。
Forward不仅可以跳转到本应用的另一个Servlet,JSP页面,也可以跳转到另一个文件,甚至是WEB-INF文件夹下的文件。其中跳转到Servlet与JSP页面时最常见的。框架中常使用一个Servlet来集中处理请求然后跳转到响应的Servlet,或者在Servlet中处理业务逻辑,然后跳转到JSP页面中显示处理结果。
1.3 组件之间传递参数
转发时,组件之间有3种方式可以传递参数:
-
URL传递
-
Session传递
-
request.setAttribute
下面的几个例子中都是以ServletA传递到ServletB为例。
1.3.1 URL传递
ServeltA中传递参数:
RequestDispatcher dispatcher=request.getRequestDispatcher("/ServletB?a=1");
dispatcher.forward(request, response);
ServletB中获取参数:
String a=request.getParameter("a");
1.3.2 Session传递
ServletA中传递参数:
request.getSession().setAttribute("a", 2);
RequestDispatcher dispatcher=request.getRequestDispatcher("/ServletB");
dispatcher.forward(request, response);
ServletB中获取参数:
Object a=request.getSession().getAttribute("a");
1.3.3 request.setAttribute
ServletA中传递参数:
request.setAttribute("a", 3);
RequestDispatcher dispatcher=request.getRequestDispatcher("/ServletB");
dispatcher.forward(request, response);
ServletB中获取参数:
Object a=request.getAttribute("a");
2.重定向(Redirect)
2.1 重定向原理
重定向的原理如下图所示:
注意:重定向响应中包含重定向地址的部分。
2.2 重定向的应用
重定向是通过服务器端返回状态码来实现的。301,302都表示重定向,区别是301表示永久性重定向,302表示临时性重定向。通过sendRedirect(String location)就可以实现重定向。eg:
response.sendRedirect("Servlet2");
如果是重定向到外部服务器,必须是完整的URL地址。eg:如果上面的代码改成
response.sendRedirect("www.baidu.com");
服务器会报404错误:
response.sendRedirect("http://www.baidu.com");
2.3 组件之间传递参数
重定向时,组件之间传递参数一定有效的方法就是URL传参。eg:假设从Servlet1跳到转相同父路径的Servlet2
Servlet1传递参数:
response.sendRedirect("Servlet2?a=111");
Servlet2接收参数:
String a=request.getParameter("a");
另外,如果两个Servlet都是在同一个Web应用里,是可以通过session传递参数的。
3.转发和重定向的区别
sendRedirect | forward |
是不同的request | 虽然是不同的对象,但可以取到上一个request里的内容 |
是不同的response | 是同一个response |
速度慢 | 速度快 |
需要到客户端的往返,可以转到任何页面 | 服务器内部跳转 |
浏览器地址栏有变化 | 浏览器地址栏没有变化 |
“/”代表的是应用服务器根路径,和HTML页面的“/”一个意思。 response.sendRedirect("/test/ServletToJSP"); <form action="/test/ServletToJSP"> <a href="/test/ServletToJSP">test</a> | “/”代表的是该Web应用的根路径,并且只能以“/”开头。 this.getServletContext().getRequestDispatcher ("/servlet_jsp/ServletUseJsp.jsp")
|
4.自动刷新(Refresh)
自动刷新不仅可以实现一段时间之后自动跳转到另一个页面,还可以实现一段时间后自动刷新本页面。Servlet中可以HttpServletResponse对象设置Header属性实现自动刷新效果。例如:
response.setHeader("Refresh", "3;URL=http://localhost/Servlet/Servlet01");
上面的代码是在Servlet01中写的,表示每3秒钟刷新本页面一次。HTTP响应结果如下:
某些情况下自动刷新很有用处。例如实时显示股市走势,或者定时检查是否有新邮件到达。
提示:自动刷新与重定向原理是差不多的。如果把时间设置为0,把URL设置为另一个网址,效果就是重定向。
参考内容:
http://www.java3z.com/cwbwebhome/article/article2/21129.html
http://hi.baidu.com/cubdgqszhtbckqq/item/1d318cc7e7707d23e90f2eea
《Java Web整合开发王者归来》第3章 深入Servlet技术
尚学堂Servlet与JSP讲义