重定向和导航/转发之间有什么区别以及何时使用什么? [英] What is the difference between redirect and navigation/forward and when to use what?

查看:37
本文介绍了重定向和导航/转发之间有什么区别以及何时使用什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

JSF 中的导航有什么区别

What is difference between a navigation in JSF

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

和重定向

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

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

and how to decide when to use what?

导航的问题在于,除非将 faces-redirect=true 添加到导航 URL 的查询字符串中,否则页面 URL 不会更改.但是,在我的情况下,如果我想重定向到非 JSF 页面(如纯 HTML 页面),附加 faces-redirect=true 会引发错误.

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.

另一个选项是 BalusC 在 JSF 2.0 重定向错误

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

推荐答案

首先,术语重定向"在 Web 开发世界中,向客户端发送一个空的 HTTP 响应的操作只有一个 Location 标头,其中包含客户端必须在其上发送全新 GET 请求的新 URL.所以基本上:

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:

  • 客户端向 somepage.xhtml 发送 HTTP 请求.
  • 服务器使用 Location: newpage.xhtml 标头发回 HTTP 响应
  • 客户端向 newpage.xhtml 发送 HTTP 请求(这会反映在浏览器地址栏中!)
  • 服务器发送回带有 newpage.xhtml 内容的 HTTP 响应.
  • Client sends a HTTP request to somepage.xhtml.
  • Server sends a HTTP response back with Location: newpage.xhtml header
  • Client sends a HTTP request to newpage.xhtml (this get reflected in browser address bar!)
  • Server sends a HTTP response back with content of newpage.xhtml.

您可以使用网络浏览器的内置/插件开发人员工具集对其进行跟踪.在 Chrome/IE9/Firebug 中按 F12 并检查网络"部分查看.

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.

JSF 导航处理程序不发送重定向.相反,它使用目标页面的内容作为 HTTP 响应.

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

  • 客户端向 somepage.xhtml 发送 HTTP 请求.
  • 服务器发送回带有 newpage.xhtml 内容的 HTTP 响应.
  • Client sends a HTTP request to somepage.xhtml.
  • Server sends a HTTP response back with content of newpage.xhtml.

但是由于最初的 HTTP 请求是针对 somepage.xhtml,浏览器地址栏中的 URL 保持不变.如果你熟悉基本的Servlet API,那么你应该明白这和RequestDispatcher#forward().

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().

至于是否从JSF底层拉取HttpServletResponse并在其上调用sendRedirect()是正确的用法;不,这不是正确的用法.您的服务器日志将被 IllegalStateException 弄得杂乱无章,因为这样您就不会告诉 JSF 您已经接管了响应处理的控制,因此 JSF 不应执行其默认的响应处理工作.您实际上应该执行 <代码>FacesContext#responseComplete() 之后.

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.

另外,每当你需要从 javax.servlet.* 包中导入一些东西,比如托管 bean 时,你应该绝对停止编写代码,如果你真的这样做了,你应该三思而后行以正确的方式做事,问问自己是否还没有标准的 JSF 方式";对于您想要实现的任何目标和/或任务是否真的属于 JSF 托管 bean(即在某些情况下,一个简单的 servlet 过滤器 本来是一个更好的地方.

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).

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

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

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

或者使用 ExternalContext#redirect() 当您不在动作方法(例如 ajax 或预渲染侦听器方法)中时:

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

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

(是的,你不需要在 IOException 的周围放一个 try-catch,只要让异常通过 throwscode>,servletcontainer会处理)

(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)

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

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

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

至于为什么纯 HTML"导航处理程序失败?文件,这仅仅是因为导航处理程序只能处理 JSF 视图,而不能处理其他文件.那么你应该使用 ExternalContext#redirect().

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.

这篇关于重定向和导航/转发之间有什么区别以及何时使用什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆