摘要在javaEE Web组件开发中,页面之间的跳转无疑是必不可少且最常见的。除了使用HTML中的表单提交、超级链接进行跳转外,Servlet API中还提供了响应重定向和请求转发两种跳转技术。这两种技术在本质上是不同的,有很大的区别,尤其是跳转页面路径的写法,更是使很多开发人员头痛不已。本文主要围绕这两种跳转方式进行展开,为读者整理、总结这两种跳转方式的特点以及需要注意的问题。
本文由中软培训所著,由中软培训首发,中软培训具有本文的知识产权。本文可用于网上转载,但请在转载过程中附加本段说明。中软培训官方网站:www.csst.com.cn谢谢。
中软java培训技术文章
关键词
java技术、Java、RequestDispatcher、forward、ServletResponse、sendRedirect、请求转发、响应重定向
目前,大多数的Web应用都基于MVC模式进行开发。其中M代表模型层,主要实现业务逻辑以及数据逻辑,V代表视图层,主要实现视图逻辑,C代表控制层,主要实现控制逻辑。而MVC每部分的实现技术却五花八门,可以是J2EE的核心组件,如JSP/Servlet、EJB,也可以是流行的框架技术,如Struts、Hibernate等。本文主要以J2EE核心组件为例,来讲解如何在V和C之间进行跳转,因为即使使用Struts这样的框架,其本质也是以J2EE核心组件技术为基础,概念是相同的。
现在假设某Web应用上下文名字为LoginDemo,该应用是使用J2EE核心组件开发,即视图是采用JSP开发,控制器使用Servlet开发,实现了最简单的登录逻辑。基本逻辑如下:
登录首页为index.jsp,用户在本页面输入用户名(表单元素为username)以及密码(表单元素为password)。提交到控制器LoginServlet.java的doPost方法,此Servlet的url-pattern为:/login,servlet-name为:LoginServlet。此Servlet调用业务逻辑验证用户名及密码(本文不关注Model具体实现),如果验证成功,即跳转到视图/normal/loginSuccessful.jsp,如果失败,即跳转到视图/error/loginFail.jsp。
本文主要关注的重点是:控制器/login向/normal/loginSuccessful.jsp和/error/loginFail.jsp跳转的方式是什么?有什么区别?跳转时候路径应该怎么写?这些问题都是Web组件开发员在开发中常遇到、也最容易混淆出错的问题。在Servlet API中,在两个接口中提供了组件跳转的方法,分别是HttpServletResponse中的sendRedirect方法和RequestDispatcher中的forward方法。接下来,本文将结合LoginDemo应用,对两个接口中的方法进行详细分析。
1、HttpServletResponse接口中的sendRedirect方法
sendRedirect方法通常被称为“响应重定向”,如果用响应对象调用了该方法,本质上就是浏览器对服务器重新提交了请求。比如LoginDemo应用中,如果使用该方法跳转,那么写法是:
response.sendRedirect(“normal/loginSuccessful.jsp”);
response.sendRedirect(“error/loginFail.jsp”);
或者是:
response.sendRedirect(“/LoginDemo/normal/loginSuccessful.jsp”);
response.sendRedirect(“/LoginDemo/normal/loginFail.jsp”);
这两种写法的主要区别在于跳转页面路径的写法,第一种写法的路径没有用“/”开始,而第二种写法的路径使用了”/”开始。我们需要理解是否使用”/”有什么不同?
n 如果不使用”/”开头,代表是请求路径。是相对于当前的请求路径而言。
n 如果使用”/”开头,代表相对于容器根路径,即”/”表示容器的根路径,因此”/”后面使用的是应用上下文的名字”LoginDemo”。
注意:由于响应重定向的方式本质上是浏览器对服务器重新提交了请求,所以例子中的loginSucessful.jsp或者loginFail.jsp视图的请求对象是一个全新的请求,也就是说,Serlvet 组件/login的请求对象中的任何内容,在视图的请求中将不再存在。如果在视图中写了如下语句: request.getParameter(“username”)
该语句的返回值应该是null,因为视图的request已经是一个全新的请求对象,以前在/login的请求中存在的请求参数username,在视图的请求中已经不再存在。
中软java培训技术文章
2、RequestDispatcher接口中的forward方法
除了上文提到的响应重定向,RequestDispatcher(通常称为“请求转发器”)接口中提供的forward方法是另一个最常使用的跳转方法,此方法通常被称为“请求转发”。请求转发的本质是容器直接将当前请求提交给另一个资源,客户端一无所知,并不重新提交请求。与响应重定向不同的是,要调用forward方法,首先必须获得RequestDispatcher接口的对象。而响应对象由于容器会自动生成并传递给doXXX方法,可以直接使用。而获得RequestDispatcher类型的对象,可以通过两个接口获得,即ServletRequest中的getRequestDispatcher方法以及ServletContext中的getRequestDispatcher、getNamedDispatcher方法。接下来分别讨论两种接口中获得请求转发器的方法。
2.1通过ServletRequest获得RequestDispatcher对象
结合LoginDemo应用实例,如果使用该方法跳转(仅以成功页面为例),方式如下:
RequestDispatcher dis1=request.getRequestDispatcher(“normal/loginSuccessful.jsp”);
dis1.forward(request,response);
或者:
RequestDispatcher dis1=request.getRequestDispatcher(“/normal/loginSuccessful.jsp”);
dis1.forward(request,response);
这两种写法的主要区别在于转发路径的写法,第一种写法的路径没有用“/”开始,而第二种写法的路径使用了”/”开始。我们需要理解是否使用”/”有什么不同?
n 如果不使用”/”开头,代表是请求路径。是相对于当前的请求路径而言。
n 如果使用”/”开头,代表相对于当前上下文路径,即”/”表示应用上下文”/LoginDemo”的根。
注意:使用此方法获得的请求转发器,是不可能跳转到其他应用上下文下的。
如果在视图中写了如下语句:
request.getParameter(“username”)
该语句的返回值应该是客户输入的用户名,因为视图的request中包含了/login的请求对象中所有的内容,这一点也是请求转发与响应重定向最大的区别。
2.2、通过ServletContext获得RequestDispatcher对象
ServletContext中有两个方法可以获得RequestDispatcher对象,即getRequestDispatcher以及getNamedDispatcher。(ctxt为某一个ServletContext对象)。结合LoginDemo应用实例,如果使用getNamedDispatcher方法跳转(仅以成功页面为例),方式如下:
RequestDispatcher dis1=ctxt. getNamedDispatcher (“LoginServlet”);
dis1.forward(request,response);
结合LoginDemo应用实例,如果使用getRequestDispatcher方法跳转(仅以成功页面为例),方式如下:
RequestDispatcher dis1=ctxt.getRequestDispatcher(“/normal/loginSuccessful.jsp”);
dis1.forward(request,response);
与其他方法相比,这个方法中的路径只能以”/”开始,否则将出现错误!
“/”表示ctxt对象的根。而ctxt对象不一定就是当前的上下文对象(具体请参见ServletContext中的getContext)方法。因此,比起ServletRequest中的getRequestDispatcher方法,此接口中的方法最大的区别在于能跳转到其他上下文下的资源。
注意:如果在视图中写了如下语句:
request.getParameter(“username”)
该语句的返回值应该是客户输入的用户名,因为视图的request中包含了/login的请求对象中所有的内容,这一点也是请求转发与响应重定向最大的区别。
中软java培训技术文章
3、小结
综上所述,响应重定向与请求转发除了路径写法的区别外,最大的区别在于响应重定向是客户端重新给服务器端发送了请求,那么重定向资源的请求中将不再包含原请求的内容。而请求转发是服务器端进行的转发,不仅进行了跳转,同时将请求对象同时进行了转发。建议开发人员选择跳转方式时,首先考虑是否需要将当前请求对象转发,如果需要,选择使用请求转发,否则即可使用响应重定向,其次考虑使用哪种路径书写方式。在实际开发中,使用ServletRequest接口获得请求转发器,从而进行请求转发的方式居多,Struts框架的跳转方式默认也是此种方式。
转:http://incan.iteye.com/blog/295077
本文由中软培训所著,由中软培训首发,中软培训具有本文的知识产权。本文可用于网上转载,但请在转载过程中附加本段说明。中软培训官方网站:www.csst.com.cn谢谢。
中软java培训技术文章
关键词
java技术、Java、RequestDispatcher、forward、ServletResponse、sendRedirect、请求转发、响应重定向
目前,大多数的Web应用都基于MVC模式进行开发。其中M代表模型层,主要实现业务逻辑以及数据逻辑,V代表视图层,主要实现视图逻辑,C代表控制层,主要实现控制逻辑。而MVC每部分的实现技术却五花八门,可以是J2EE的核心组件,如JSP/Servlet、EJB,也可以是流行的框架技术,如Struts、Hibernate等。本文主要以J2EE核心组件为例,来讲解如何在V和C之间进行跳转,因为即使使用Struts这样的框架,其本质也是以J2EE核心组件技术为基础,概念是相同的。
现在假设某Web应用上下文名字为LoginDemo,该应用是使用J2EE核心组件开发,即视图是采用JSP开发,控制器使用Servlet开发,实现了最简单的登录逻辑。基本逻辑如下:
登录首页为index.jsp,用户在本页面输入用户名(表单元素为username)以及密码(表单元素为password)。提交到控制器LoginServlet.java的doPost方法,此Servlet的url-pattern为:/login,servlet-name为:LoginServlet。此Servlet调用业务逻辑验证用户名及密码(本文不关注Model具体实现),如果验证成功,即跳转到视图/normal/loginSuccessful.jsp,如果失败,即跳转到视图/error/loginFail.jsp。
本文主要关注的重点是:控制器/login向/normal/loginSuccessful.jsp和/error/loginFail.jsp跳转的方式是什么?有什么区别?跳转时候路径应该怎么写?这些问题都是Web组件开发员在开发中常遇到、也最容易混淆出错的问题。在Servlet API中,在两个接口中提供了组件跳转的方法,分别是HttpServletResponse中的sendRedirect方法和RequestDispatcher中的forward方法。接下来,本文将结合LoginDemo应用,对两个接口中的方法进行详细分析。
1、HttpServletResponse接口中的sendRedirect方法
sendRedirect方法通常被称为“响应重定向”,如果用响应对象调用了该方法,本质上就是浏览器对服务器重新提交了请求。比如LoginDemo应用中,如果使用该方法跳转,那么写法是:
response.sendRedirect(“normal/loginSuccessful.jsp”);
response.sendRedirect(“error/loginFail.jsp”);
或者是:
response.sendRedirect(“/LoginDemo/normal/loginSuccessful.jsp”);
response.sendRedirect(“/LoginDemo/normal/loginFail.jsp”);
这两种写法的主要区别在于跳转页面路径的写法,第一种写法的路径没有用“/”开始,而第二种写法的路径使用了”/”开始。我们需要理解是否使用”/”有什么不同?
n 如果不使用”/”开头,代表是请求路径。是相对于当前的请求路径而言。
n 如果使用”/”开头,代表相对于容器根路径,即”/”表示容器的根路径,因此”/”后面使用的是应用上下文的名字”LoginDemo”。
注意:由于响应重定向的方式本质上是浏览器对服务器重新提交了请求,所以例子中的loginSucessful.jsp或者loginFail.jsp视图的请求对象是一个全新的请求,也就是说,Serlvet 组件/login的请求对象中的任何内容,在视图的请求中将不再存在。如果在视图中写了如下语句: request.getParameter(“username”)
该语句的返回值应该是null,因为视图的request已经是一个全新的请求对象,以前在/login的请求中存在的请求参数username,在视图的请求中已经不再存在。
中软java培训技术文章
2、RequestDispatcher接口中的forward方法
除了上文提到的响应重定向,RequestDispatcher(通常称为“请求转发器”)接口中提供的forward方法是另一个最常使用的跳转方法,此方法通常被称为“请求转发”。请求转发的本质是容器直接将当前请求提交给另一个资源,客户端一无所知,并不重新提交请求。与响应重定向不同的是,要调用forward方法,首先必须获得RequestDispatcher接口的对象。而响应对象由于容器会自动生成并传递给doXXX方法,可以直接使用。而获得RequestDispatcher类型的对象,可以通过两个接口获得,即ServletRequest中的getRequestDispatcher方法以及ServletContext中的getRequestDispatcher、getNamedDispatcher方法。接下来分别讨论两种接口中获得请求转发器的方法。
2.1通过ServletRequest获得RequestDispatcher对象
结合LoginDemo应用实例,如果使用该方法跳转(仅以成功页面为例),方式如下:
RequestDispatcher dis1=request.getRequestDispatcher(“normal/loginSuccessful.jsp”);
dis1.forward(request,response);
或者:
RequestDispatcher dis1=request.getRequestDispatcher(“/normal/loginSuccessful.jsp”);
dis1.forward(request,response);
这两种写法的主要区别在于转发路径的写法,第一种写法的路径没有用“/”开始,而第二种写法的路径使用了”/”开始。我们需要理解是否使用”/”有什么不同?
n 如果不使用”/”开头,代表是请求路径。是相对于当前的请求路径而言。
n 如果使用”/”开头,代表相对于当前上下文路径,即”/”表示应用上下文”/LoginDemo”的根。
注意:使用此方法获得的请求转发器,是不可能跳转到其他应用上下文下的。
如果在视图中写了如下语句:
request.getParameter(“username”)
该语句的返回值应该是客户输入的用户名,因为视图的request中包含了/login的请求对象中所有的内容,这一点也是请求转发与响应重定向最大的区别。
2.2、通过ServletContext获得RequestDispatcher对象
ServletContext中有两个方法可以获得RequestDispatcher对象,即getRequestDispatcher以及getNamedDispatcher。(ctxt为某一个ServletContext对象)。结合LoginDemo应用实例,如果使用getNamedDispatcher方法跳转(仅以成功页面为例),方式如下:
RequestDispatcher dis1=ctxt. getNamedDispatcher (“LoginServlet”);
dis1.forward(request,response);
结合LoginDemo应用实例,如果使用getRequestDispatcher方法跳转(仅以成功页面为例),方式如下:
RequestDispatcher dis1=ctxt.getRequestDispatcher(“/normal/loginSuccessful.jsp”);
dis1.forward(request,response);
与其他方法相比,这个方法中的路径只能以”/”开始,否则将出现错误!
“/”表示ctxt对象的根。而ctxt对象不一定就是当前的上下文对象(具体请参见ServletContext中的getContext)方法。因此,比起ServletRequest中的getRequestDispatcher方法,此接口中的方法最大的区别在于能跳转到其他上下文下的资源。
注意:如果在视图中写了如下语句:
request.getParameter(“username”)
该语句的返回值应该是客户输入的用户名,因为视图的request中包含了/login的请求对象中所有的内容,这一点也是请求转发与响应重定向最大的区别。
中软java培训技术文章
3、小结
综上所述,响应重定向与请求转发除了路径写法的区别外,最大的区别在于响应重定向是客户端重新给服务器端发送了请求,那么重定向资源的请求中将不再包含原请求的内容。而请求转发是服务器端进行的转发,不仅进行了跳转,同时将请求对象同时进行了转发。建议开发人员选择跳转方式时,首先考虑是否需要将当前请求对象转发,如果需要,选择使用请求转发,否则即可使用响应重定向,其次考虑使用哪种路径书写方式。在实际开发中,使用ServletRequest接口获得请求转发器,从而进行请求转发的方式居多,Struts框架的跳转方式默认也是此种方式。
转:http://incan.iteye.com/blog/295077