重定向(Rediret) 到另一个视图
在前面我们提到过,一个控制器通常会返回视图名,然后由视图解析器解析到某种视图实现。对于像JSP这样实际上由Servlet/JSP引擎处理的视图,我们通常使用InternalResourceViewResolver和InternalResourceView。这种视图实现最终会调用Servlet API的RequestDispatcher.forward(..)方法或RequestDispatcher.include()方法将用户指向最终页面。对于别的视图技术而言(比如Velocity、XSLT等等), 视图本身就会生成返回给用户的内容。
有些时候,在视图显示以前,我们可能需要给用户发一个HTTP redirect重定向指令。比如,一个控制器成功的处理了一个表单提交(数据以HTTP POST的方式发送),它最终可能委托给另一个控制器来完成剩下的工作。在这种情况下,如果我们使用内部forward,接手工作的那个控制器将会得到所有以POST方式提交的表单数据,这可能会引起潜在的混淆,干扰那个控制器的正常工作。 另一个在显示视图之前返回HTTP redirect的原因是这可以防止用户重复提交同一表单。具体一点讲,浏览器先用POST的方式提交表单,然后它接收到重定向的指令,它继续用GET的方式去下载新的页面。从浏览器的角度看,这个新的页面不是POST的返回结果,而是GET的。这样,用户不可能在点击刷新的时候不小心再次提交表单,因为刷新的结果是再次用GET 去下载表单提交后的结果页面,而不是重新提交表单。
RedirectView
在控制器中强制重定向的方法之一是让控制器生成并返回一个RedirectView的实例。在这种情况下,DispatcherServlet不会使用通常的视图解析机制,既然它已经拿到了一个(重定向)视图,它就让这个视图去做剩下的工作。
RedirectView会调用HttpServletResponse.sendRedirect()方法,其结果是给用户的浏览器发回一个HTTP redirect。所有的模型属性都被转换成以HTTP请求的访问参数。这意味着这个模型只能包含可以被简便的转换成string形式的HTTP请求访问参数的对象,比如String或者可以被转换成String的类型。
如果你使用RedirectView视图,并且它是由控制器生成的,重定向的URL最好是用Spring所提供的IoC功能注射到控制器里。这样这个URL就可以和视图名一起在上下文中被声明,而不是固化在控制器内。
redirect:前缀
尽管RedirectView帮我们达到了目的,但是如果控制器生成RedirectView的话,控制器不可避免地要知道某个请求的结果是让用户重定向到另一个页面。这不是最佳的实现,因为这使得系统不同模块之间结合得过于紧密。其实控制器不应该过问返回结果是怎么生成的,通常情况下,它应该只关心提供给它的视图名。
解决上述问题的方法是依靠redirect:前缀。如果返回的视图名包含redirect:前缀,UrlBasedViewResolver (以及它的子类) 会知道系统要生成一个HTTP redirect。 视图名其余的部分会被当作重定向URL。
这样做的最终结果跟控制器返回RedirectView是一样的,但现在控制器只需要和逻辑上的视图名打交道。 redirect:/my/response/controller.html这个逻辑视图名中的URL是当前servlet context中的相对路径。与之相比,redirect:http://myhost.com/some/arbitrary/path.html中的URL是绝对路径。 重要的是,只要这个重定向视图名和其他视图名以相同的方式注射到控制器中,控制器根本不知道重定向是否发生了。
forward:前缀
类似的,我们也可以使用包含有forward:前缀的视图名。这些视图名会被UrlBasedViewResolver和它的子类正确解析。解析的内部实现是生成一个InternalResourceView,这个视图最终会调用RequestDispatcher.forward()方法,将forward视图名的其余部分作为URL。所以,当你使用InternalResourceViewResolver/InternalResourceView,并且你所用的视图技术是JSP时,你没有必要使用这个前缀。但是,当你主要使用其它的视图技术,但仍需要对Servlet/JSP engine处理的页面强制forward时,这个forward前缀还是很有用的(但就这个问题而言,如果你不想用forward前缀,你也可以使用视图解析链)。
和redirect:前缀一样,如果含有forward前缀的视图名和其他视图名一样被注入控制器,控制器根本不知道forward是否发生了。
Spring web 重定向(Rediret) 到另一个视图
最新推荐文章于 2024-03-18 17:26:45 发布