Servlet之间的跳转

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 重定向原理

重定向的原理如下图所示:


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

注意:重定向响应中包含重定向地址的部分。

2.2 重定向的应用

重定向是通过服务器端返回状态码来实现的。301,302都表示重定向,区别是301表示永久性重定向,302表示临时性重定向。通过sendRedirect(String location)就可以实现重定向。eg:

response.sendRedirect("Servlet2");

如果是重定向到外部服务器,必须是完整的URL地址。eg:如果上面的代码改成
response.sendRedirect("www.baidu.com");

服务器会报404错误:

如果是完整的URL地址则可以正常跳转:
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")
  .forward(req, resp);

 

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讲义


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值