重定向和导航的区别是什么?什么时候使用什么?

[英]What is the difference between redirect and navigation/forward and when to use what?


What is difference between a navigation in JSF

在JSF中导航的区别是什么?

FacesContext context = FacesContext.getCurrentInstance();
context.getApplication().getNavigationHandler().handleNavigation(context, null, url);

and a redirect

和重定向

HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.sendRedirect(url);

and how to decide when to use what?

以及如何决定何时使用什么?

The issue with navigation is that page URL does not change unless faces-redirect=true is added to the query string of the navigation URL. However, in my case appending faces-redirect=true throws error if I want to redirect to a non-JSF page like a plain HTML page.

导航的问题是,除非将faces-redirect=true添加到导航URL的查询字符串中,否则页面URL不会更改。但是,在我的情况下,如果我想重定向到一个非jsf页面,比如一个普通的HTML页面,那么append -redirect=true抛出错误。

And another option is as BalusC suggested at JSF 2.0 redirect error

另一个选项是BalusC在JSF 2.0重定向错误中建议的。

1 个解决方案

#1


74  

First of all, the term "redirect" is in web development world the action of sending the client an empty HTTP response with just a Location header with therein the new URL on which the client has to send a brand new GET request. So basically:

首先,“重定向”这个术语是在web开发世界中,它的作用是将一个空的HTTP响应发送到一个位置标头,其中的一个新URL,客户端必须发送一个全新的GET请求。所以:

  • Client sends a HTTP request to somepage.xhtml.
  • 客户机向somepage.xhtml发送一个HTTP请求。
  • Server sends a HTTP response back with Location: newpage.xhtml header
  • 服务器发送一个带有位置的HTTP响应:newpage。xhtml页眉
  • Client sends a HTTP request to newpage.xhtml (this get reflected in browser address bar!)
  • 客户端发送一个HTTP请求到newpage。xhtml(这在浏览器地址栏中得到了体现!)
  • Server sends a HTTP response back with content of newpage.xhtml.
  • 服务器以newpage.xhtml的内容发送HTTP响应。

You can track it with the webbrowser's builtin/addon developer toolset. Press F12 in Chrome/IE9/Firebug and check the "Network" section to see it.

您可以使用webbrowser的builtin/addon developer工具集跟踪它。按F12在Chrome/IE9/Firebug,并检查“网络”部分看它。

The JSF navigationhandler doesn't send a redirect. Instead, it uses the content of the target page as HTTP response.

JSF navigationhandler不发送重定向。相反,它使用目标页面的内容作为HTTP响应。

  • Client sends a HTTP request to somepage.xhtml.
  • 客户机向somepage.xhtml发送一个HTTP请求。
  • Server sends a HTTP response back with content of newpage.xhtml.
  • 服务器以newpage.xhtml的内容发送HTTP响应。

However as the original HTTP request was to somepage.xhtml, the URL in browser address bar remains unchanged. If you are familiar with the basic Servlet API, then you should understand that this has the same effect as RequestDispatcher#forward().

但是,由于最初的HTTP请求是在somepage上的。xhtml中,浏览器地址栏中的URL保持不变。如果您熟悉基本的Servlet API,那么您应该理解这与RequestDispatcher#forward()具有相同的效果。


As to whether pulling the HttpServletResponse from under the JSF hoods and calling sendRedirect() on it is the proper usage; no, that isn't the proper usage. Your server logs will get cluttered with IllegalStateExceptions because this way you aren't telling JSF that you've already taken over the control of the response handling and thus JSF shouldn't do its default response handling job. You should in fact be executing FacesContext#responseComplete() afterwards.

至于是否从JSF罩下拉HttpServletResponse并调用sendRedirect()是正确的用法;不,那不是正确的用法。您的服务器日志将会被illegalstateexception混乱,因为这样您就不会告诉JSF您已经接管了响应处理的控制,因此JSF不应该做它的默认响应处理作业。实际上,您应该在之后执行FacesContext#responseComplete()。

Also, everytime whenever you need to import something from javax.servlet.* package in a JSF artifact like a managed bean, you should absolutely stop writing code and think twice if you're really doing things the right way and ask yourself if there isn't already a "standard JSF way" for whatever you're trying to achieve and/or if the task really belongs in a JSF managed bean (there are namely some cases wherein a simple servlet filter would have been a better place).

而且,每当您需要从javax.servlet中导入某些东西时。*包在工件JSF托管bean,你应该绝对不写代码,三思而后行,如果你用正确的方法做事情,问问你自己如果没有已经“标准JSF方式”无论你想实现和/或如果任务真的属于JSF托管bean(即有一些情况下,一个简单的servlet过滤器是一个更好的地方)。

The proper way of performing a redirect in JSF is using faces-redirect=true query string in the action outcome:

在JSF中执行重定向的正确方法是在操作结果中使用事实重定向=true查询字符串:

public String submit() {
    // ...
    return "/newpage.xhtml?faces-redirect=true";
}

Or using ExternalContext#redirect() when you're not inside an action method such as an ajax or prerender listener method:

或者使用ExternalContext#redirect()当您不在一个操作方法中时,例如ajax或prerender侦听器方法:

public void listener() throws IOException {
    // ...
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    ec.redirect(ec.getRequestContextPath() + "/newpage.xhtml");
}

(yes, you do not need to put a try-catch around it on IOException, just let the exception go through throws, the servletcontainer will handle it)

(是的,您不需要在IOException上放置try-catch,只是让异常通过抛出,servletcontainer将处理它)

Or using NavigationHandler#handleNavigation() in specific cases if you're using XML navigation cases and/or a custom navigation handler with some builtin listener:

或者在特定情况下使用NavigationHandler#handleNavigation(),如果您使用的是XML导航案例和/或一个带有内置侦听器的自定义导航处理程序:

public void listener() {
    // ...
    FacesContext fc = FacesContext.getCurrentInstance();
    NavigationHandler nh = fc.getApplication().getNavigationHandler();
    nh.handleNavigation(fc, null, "/newpage.xhtml?faces-redirect=true");
}

As to why the navigation handler fails for "plain HTML" files, that is simply because the navigation handler can process JSF views only, not other files. You should be using ExternalContext#redirect() then.

至于为什么导航处理程序不能使用“纯HTML”文件,这仅仅是因为导航处理程序只能处理JSF视图,而不是其他文件。您应该使用ExternalContext#redirect()。

See also:

智能推荐

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.itdaan.com/blog/2012/06/30/7dee67ed0d3771553afe2c432f97b282.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告