#重定向与转发的区别
开发Web应用中会遇到从一个页面跳转到另一个页面的问题,在JSP中有两种跳转方式:
1.重定向
2.转发(转向)
重定向:首先服务器受到浏览器客户端请求之后,服务器发送新的链接到客户端浏览器,浏览器接收到新的链接之后又重新请求收到的链接地址,在整个过程中完成之后在客户端浏览器看来是发生了一次跳转,其实是客户端浏览器请求了两次而已,所以在浏览器的地址栏里网络地址自然就会改变成新的连接
转发:服务器接收到客户端的请求之后,服务器把控制权交到另一个JSP页面手里,新的JSP页面接收到请求之后根据情况是继续转交控制权或者显示页面由自己决定,到最后显示页面的整个过程就是一个页面跳转过程,在这个过程中,服务器可以把请求的数据在经过的页面进行传递,而不会担心数据的丢失
重定向:
response.sendRedirect("success.jsp");
转发(转向):
request.getRequestDispatcher("success.jsp").forward(request,response);
转向(Forward)是通过RequestDispatcher对象的forward(HttpServletRequest req,HttpServletResponse res)方法来实现的。RequestDispatcher可以通过HttpServletRequest的getRequestDispacher()方法获得。例如,下面的代码跳转到另一个Servlet:
RequestDispatcher dispatcher=
request.getRequestDispatcher(“/servlet/LifeCycleServlet”);
dispatcher.forward(request,response);
getRequestDispatcher()方法的参数必须以“/”开始,“/”表示本Web应用程序的根目录。如果要跳转到Servlet为http://localhost:8080/servlet/
servlet/LifeCycleServlet,则参数应为”/servlet/LifeCycleServlet”.
转向(Forward)是MVC框架中常用的一种技术。Forward不仅可以跳转到本应用的另一个Servlet,JSP页面,也可以跳转到另外一个文件,甚至WEB-INF文件夹下的文件。其中跳转到Servlet与JSP页面是最常见的。框架中常使用一个Servlet来集中处理请求然后跳转到响应的Servlet,或者在Servlet中处理业务逻辑,然后跳转到JSP页面中显示处理结果。
注意:当执行forward动作的时候不能有任何输出到达客户端,否则会抛出IllegalStateException.也就是在forward之前尽量不要使用out.println()语句向客户端输出结果。
重定向(Redirect)是利用服务器返回的状态码来实现的。客户端浏览器请求服务器的时候,服务器端会返回一个状态码。服务器端通过HttpServletResponse的setStatus(int status)方法设置状态码。如果服务器返回301或者302,则浏览器会到新的网址重新请求该资源。状态码代表的含义如下表所示:
301、302都表示重定向,区别是301是永久性重定向,302是临时性重定向。下面的代码将访问该Servlet的请求重定向到另一个网址。
//设置状态码为302
response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
//新网址
response.setHeader(“Location”,”http://www.hello.com”);
HttpServletResponse类中把常用的状态码都封装成了静态的常量。
HttpServletResponse把setStatus与setHeader方法封装成另一个方法
sendRedirect(Stringlocation),只需要调用sendRedirection()就可以实现。
下面总结一下两者的区别:
1.请求的次数的不同,重定向总共请求了两次服务器;转发则是用户请求一次可能经过N个JSP页面由返回到用户浏览器中,是一次请求多次处理的过程;
2.跳转过程中链接的变化,重定向在跳转中请求了两次服务器并且是两次不同的链接地址,在浏览器的地址栏可以看到两次是有变化的;转发在跳转过程中浏览器请求了一次服务器,服务器经过了n个JSP页面并没有改变请求的链接地址,因为用户只请求了一次,所以在整个跳转过程中链接地址是没有改变的,在浏览器的地址栏就可以看到
3.目的不同,重定向只是简单的让用户访问一个新的链接,而转发是服务器要得到用户的请求内容并需要进行一部分处理的,所以两者目的是不同的
1.转发在服务器端完成的;重定向是在客户端完成的
2.转发的速度快;重定向速度慢
3.转发的是同一次请求;重定向是两次不同请求
4.转发不会执行转发后的代码;重定向会执行重定向之后的代码
5.转发地址栏没有变化;重定向地址栏有变化
6.转发必须是在同一台服务器下完成;重定向可以在不同的服务器下完成
自动刷新(Refresh):
自动刷新不仅可以实现一段时间之后自动跳转到另外一个页面,还可以实现一段时间之后自动刷新本页面。Servlet中通过HttpServletResponse对象设置Header属性实现自动刷新效果,例如:
response.setHeader(“Refresh”,
”1000;URL=http://localhost:8080/servlet/example.html”);
其中1000为时间,单位毫秒。URL参数指定的网址就是1秒钟之后跳转的页面。
当URL设置的路径为Servlet自己的路径时,就会每隔1秒钟自动刷新本页面一次。提示:自动刷新与重定向原理是差不多的。如果把时间设为0,把URL设为另外一个网址,效果就是重定向。
Servlet不是线程安全的,多个客户端请求同一个Servlet时,会出现多线程并发的读写导致数据不同步的问题。解决的办法是尽量不要在Servlet中定义全局属性,若需要则定义到doGet()与doPost()方法内。虽然使用synchronized(){}语句块也可以解决问题,但是会造成线程的等待,不是很科学的办法。多线程并发的读写Servlet类属性会导致数据不同步。但是如果只是并发地读取属性而不写入,则不存在数据不同步问题。因此,Servlet里的只读属性最好定义为final类型的。
#同一用户的不同页面如何共享数据:
1. cookie技术
2. sendRedirect()转向
3. 隐藏表单
4. session技术
#session实现计数器功能:
HttpSession hs =request.getSession(true);
String heading;
Integer accessCount =(Integer)session.getAttribute(“accessCount”);
If(accessCount==null){
accessCount= new Integer(0);
heading= “Welcome,Newcomer!”;
}else{
Heading= “Welcome Back”;
accessCount= new Integer(accessCount.intValue()+1);
}
session.setAttribute(“accessCount”,accessCount);