servlet跳转页面的几种方法
一直对Servlet的几种页面跳转方式,理解的糊里糊涂的,今天在网上搜了一把,找到一遍比较好的,记下来,以后看看。
跳转分两部分,一是发生在servlet,一是在JSP,其实JSP也就是servlet,不过还是有点差异滴。
Servlet:
当然,在servlet中,一般跳转都发生在doGet, doPost等方法里面。
1) redirect 方式
response.sendRedirect("/a.jsp");
页面的路径是相对路径。sendRedirect可以将页面跳转到任何页面,不一定局限于本web应用中,如:
response.sendRedirect("https://www.sodocs.net/doc/0b4068723.html,");
跳转后浏览器地址栏变化。
这种方式要传值出去的话,只能在url中带parameter或者放在session中,无法使用request.setAttribute来传递。
2) forward方式
RequestDispatcher dispatcher = request.getRequestDispatcher("/a.jsp"); dispatcher .forward(request, response);
页面的路径是相对路径。forward方式只能跳转到本web应用中的页面上。
跳转后浏览器地址栏不会变化。
使用这种方式跳转,传值可以使用三种方法:url中带parameter,session,request.setAttribute
JSP:
1) response.sendRedirect();
和servlet的response.sendRedirect()方式一样。
此语句前不允许有out.flush(),如果有,会有异常:
https://www.sodocs.net/doc/0b4068723.html,ng.IllegalStateException: Can't sendRedirect() after data has committed to the client.
at
com.caucho.server.connection.AbstractHttpResponse.sendRedirect(AbstractHttpRes ponse.java:558)
...
跳转后浏览器地址栏变化
如果要跳到不同主机下,跳转后,此语句后面的语句会继续执行,如同新开了线程,但是对response的操作已经无意义了;
如果要跳到相同主机下,此语句后面的语句执行完成后才会跳转;
2) response.setHeader("Location","");
此语句前不允许有out.flush(),如果有,页面不会跳转。
跳转后浏览器地址栏变化
此语句后面的语句执行完成后才会跳转
3)
此语句前不允许有out.flush(),如果有,会有异常:
https://www.sodocs.net/doc/0b4068723.html,ng.IllegalStateException: forward() not allowed after buffer has committed.
at
com.caucho.server.webapp.RequestDispatcherImpl.forward(RequestDispatcherImpl.ja va:134)
at
com.caucho.server.webapp.RequestDispatcherImpl.forward(RequestDispatcherImpl.ja va:101)
at com.caucho.jsp.PageContextImpl.forward(PageContextImpl.java:836)
...
跳转后浏览器地址栏不变,但是只能跳到当前主机下
此语句后面的语句执行完成后才会跳转
说一下JSP的几种跳转吧!
下面是两种比较重要的跳转,我还是与上次的一次,把我做的笔记贴出来:
A、
a.地址栏不改变跳转——服务器端跳转,服务器之间内部转,相同的request,可传参;
b.执行到跳转语句后无条件立刻跳转——之后的代码不再被执行;
注意:如果使用forward跳转,则一定要在跳转之前释放掉全部的资源;
c.使用forward时,request设置的属性依然能保留在下一个页面(setAttribute);
d.通过
e.地址中的”/”代表是:http://localhost:8080/Test
B、response.sendRedirect(“地址”):效率低,速度慢
a.地址栏改变跳转——客户端跳转(其中地址可以是任意的)
b.所有代码执行完毕之后再跳转,跳转语句后面的代码还是会执行,除非在其后面加上return(return)需复杂一些。
<%
Response.sendRedirect(“aa.jsp”);
boolean b = true;
if(b){
Return;
}
System.out.println(“aaaaaaaaaa”);
%>
c.不能保存request属性——地址改变了,客户端跳转,不同的request
d.通过对URL地址的重写传递参数:
response.sendRedirect(“responseDemo04.jsp?id=mldn”);
e.地址中的”/”代表是:http://localhost:8080/
再说一下这种href链接式跳转,其实它就是一个简单的html链接,它不能直接把表单的值传出去,除非把值放在地址后面带出去:
href="aa.do?bb=<%=bb%>&cc=<%=cc%>"
转发方式:request.getRequestDispatcher().forward();
重定向方式:response.sendRedirect();
下面是HttpServletResponse.sendRedirect方法实现的请求重定向与RequestDispatcher.f orward方法实现的请求转发的总结比较:
(1)RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的组件;而HttpServletResponse.sendRedirect 方法不仅可以重定向到当前应用程序中的其他资源,还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。如果传递给HttpServletResponse.sendRedirect 方法的相对URL以“/”开头,它是相对于
整个WEB站点的根目录;如果创建RequestDispatcher对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。
(2)调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;而调用RequestDi spatcher.forward 方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。
(3)HttpServletResponse.sendRedirect方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求,这个过程好比有个绰号叫“浏览器”的人写信找张三借钱,张三回信说没有钱,让“浏览器”去找李四借,并将李四现在的通信地址告诉给了“浏览器”。于是,“浏览器”又按张三提供通信地址给李四写信借钱,李四收到信后就把钱汇给了“浏览器”。可见,“浏览器”一共发出了两封信和收到了两次回复,“浏览器”也知道他借到的钱出自李四之手。RequestDispatcher.forward方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。这个过程好比绰号叫“浏览器”的人写信找张三借钱,张三没有钱,于是张三找李四借了一些钱,甚至还可以加上自己的一些钱,然后再将这些钱汇给了“浏览器”。可见,“浏览器”只发出了一封信和收到了一次回复,他只知道从张三那里借到了钱,并不知道有一部分钱出自李四之手。
(4)RequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;而HttpServletResponse.sendRedi rect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。对于同一个WEB应用程序的内部资源之间的跳转,特别是跳转之前要对请求进行一些前期预处理,并要使用HttpServletRequest.setAttribute方法传递预处理结果,那就应该使用RequestDispatcher.forward方法。不同WEB应用程序之间的重定向,特别是要重定向到另外一个WEB站点上的资源的情况,都应该使用HttpServletResponse.sendRedirect方法。
(5)无论是RequestDispatcher.forward方法,还是HttpServletResponse.sendRedir ect方法,在调用它们之前,都不能有内容已经被实际输出到了客户端。如果缓冲区中已经有了一些内容,这些内容将被从缓冲区中清除。
怎么选择是重定向还是转发呢?通常情况下转发更快,而且能保持request内的对象,所以他是第一选择。但是由于在转发之后,浏览器中URL仍然指向开始页面,此时如果重载当前页面,开始页面将会被重新调用。如果你不想看到这样的情况,则选择转发。
不要仅仅为了把变量传到下一个页面而使用session作用域,那会无故增大变量的作用域,转发也许可以帮助你解决这个问题。
重定向:以前的request中存放的变量全部失效,并进入一个新的request作用域。
转发:以前的request中存放的变量不会失效,就像把两个页面拼到了一起。
重定向和转发有一个重要的不同:当使用转发时,JSP容器将使用一个内部的方法来调用目标页面,新的页面继续处理同一个请求,而浏览器将不会知道这个过程。与之相反,重定向方式的含义是第一个页面通知浏览器发送一个新的页面请求。因为,当你使用重定向时,浏览器中所显示的URL会变成新页面的URL, 而当使用转发时,该URL会保持不变。重定向的速度比转发慢,因为浏览器还得发出一个新的请求。同时,由于重定向方式产生了一个新的请求,所以经过一次重定向后,request内的对象将无法使用。
怎么选择是重定向还是转发呢?通常情况下转发更快,而且能保持request内的对象,所以他是第一选择。但是由于在转发之后,浏览器中URL仍然指向开始页面,此时如果重载当前页面,开始页面将会被重新调用。如果你不想看到这样的情况,则选择转发。
转发和重定向的区别
不要仅仅为了把变量传到下一个页面而使用session作用域,那会无故增大变量的作用域,转发也许可以帮助你解决这个问题。
重定向:以前的request中存放的变量全部失效,并进入一个新的request作用域。转发:以前的request中存放的变量不会失效,就像把两个页面拼到了一起。
一.使用QueryString 使用QueryString在页面间传递值是一种非常常见的方法,我们在ASP中就常常用到。 (1)优点和缺点优点: 优点:1.使用简单,对于安全性要求不高时传递数字或是文本值非常有效。 缺点:1.缺乏安全性,由于它的值暴露在浏览器的URL地址中的。 2.不能传递对象。 (2)使用方法 1.在源页面的代码中用需要传递的名称和值构造URL地址。 2.在源页面的代码用Response.Redirect(URL);重定向到上面的 URL地址中。 3.在目的页面的代码使用Request.QueryString["name"];取出 URL地址中传递的值。 (3)应用举例 1.源页面*.aspx的代码: private void Button1_Click(object sender, System.EventArgs e) { String urlAddress; string Name1; string Name2; string Name3; string Name1Value = "HelloName1"; int Name2Value = 1234567; string Name3Value = "你好名称3"; urlAddress="destinationWebForm.aspx?Name1=" + Name1Value + "&" + "Name2=" + Name2Value.ToString() + "&" + "Name3=" + Name3Value; Response.Redirect(urlAddress); } 2.目的页面destinationWebForm.aspx的代码: private void Page_Load(object sender, System.EventArgs e) { String myName1Value; int myName2Value; string myName3Value; myName1Value = Request.QueryString["Name1"]; myName2Value=Convert.ToInt32(Request.QueryString["Name 2"]); myName3Value = Request.QueryString["Name3"]; } (4)可能出现的问题1在处理Resonse.QueryString函数汉字参数传递时,发生不能完整传递参数的具体值的错误,解决有两个方法。
1、在HTML中,()标记不可出现在
和标记符之间。(C) (A)