如何在JSF中进行重定向 [英] How to make a redirection in JSF

查看:102
本文介绍了如何在JSF中进行重定向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个网络应用程序,用户可以直接发送到某些特定页面(例如他可以查看或编辑项目的页面)。为实现这一目标,我们提供了一个特定的网址。这些网址位于外部当前网络应用程序中(即它们可以存在于其他网络应用程序或电子邮件中)。

I have a web-application where the users can be sent directly to some specific pages (such as a page where he can view or edit an item). To achieve that, we provide a specific url. These urls are located outside the current web-application (i.e. they can be present in another web-application, or in an email).

该网址看起来像 http://myserver/my-app/forward.jsf?action = XXX& param = YYY ,其中:

The url looks like http://myserver/my-app/forward.jsf?action=XXX&param=YYY, where:


  • 操作表示用户将被重定向的页面。您可以将此视为导航案例中任何JSF操作的 from-outcome faces-config.xml

  • actionParam 是上一个操作的参数(通常是项目ID)

  • action represents the page where the user will be redirected. You can consider this as the from-outcome of any JSF action in navigation-case in faces-config.xml.
  • actionParam is a parameter for the previous action (generally an item ID)

例如,我可以拥有这些网址:

So for example, I can have these kind of urls:


  • http://myserver/my-app/forward.jsf?action = viewItem& actionParam = 1234

  • http://myserver/my-app/forward.jsf?action = editItem& actionParam = 1234

  • http://myserver/my-app/forward.jsf?action=viewItem&actionParam=1234
  • http://myserver/my-app/forward.jsf?action=editItem&actionParam=1234

当然,我有一个Java类(bean)会检查一些安全性约束(即用户是否允许查看/编辑相应的项?)然后将用户重定向到正确的页面(例如 edit.xhtml view.xhtml access-denied.xhtml )。

Of course, I have a Java class (bean) that will check some security constraints (i.e. is the user allowed to see / edit the corresponding item?) and then redirect the user to the correct page (such as edit.xhtml, view.xhtml or access-denied.xhtml).

当前实施

目前,我们有一种完成转发的基本方法d。当用户点击链接时,会调用以下XHTML页面:

Currently, we have a basic way to accomplish the forward. When the user clicks on the link, the following XHTML page is called:

<html>
    <body id="forwardForm">
        <h:inputHidden id="myAction" binding="#{forwardBean.hiddenAction}"/>
        <h:inputHidden id="myParam" binding="#{forwardBean.hiddenActionParam}"/>
        <h:commandButton id="forwardBtn" actionListener="#{forwardBean.doForward}" style="display: none;"/>
    </body>
    <script type="text/javascript">
        document.getElementById('forwardForm:forwardBtn').click();
    </script>
</html>

如你所见,我绑定两个< h:inputHidden> 我的Java bean中的组件。它们将用于存储 action actionParam 请求参数的值(使用 FacesContext .getCurrentInstance()getExternalContext()getRequestParameterMap()得到( actiontParam);。。。)。我还提供了 doForward 方法,该方法将在呈现页面时立即调用,这将(再次)将用户重定向到真实页面。方法是:

As you can see, I bind two <h:inputHidden> components in my Java bean. They will be used to store the value of both action and actionParam request parameter (using FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("actiontParam");). I also provide the doForward method that which will be called immediately when the page is rendered, which will redirect (again) the user to the real page. The method is:

public void doForward(ActionEvent evt) {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    String redirect = // define the navigation rule that must be used in order to redirect the user to the adequate page...
    NavigationHandler myNav = facesContext.getApplication().getNavigationHandler();
    myNav.handleNavigation(facesContext, null, redirect);
}






此解决方案正常运行,但我有两个问题:


This solution is working, but I have two problems with that:


  • 我不喜欢它的实现方式。我确信我可以有更简单的东西(使用Servlet?)。

  • 这个解决方案使用的是Javascript,我不能使用Javascript(因为这个版本可能会被旧版Blackberry使用)用户,不支持Javascript。)。

所以我的问题是如何重构此重定向/转发功能?

技术信息

Java 1.6,JSF 1.2,Facelets, Richfaces

Java 1.6, JSF 1.2, Facelets, Richfaces

推荐答案

faces-config.xml 这样你就不需要手动收集它们了:

Set the GET query parameters as managed properties in faces-config.xml so that you don't need to gather them manually:

<managed-bean>
    <managed-bean-name>forward</managed-bean-name>
    <managed-bean-class>com.example.ForwardBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
        <property-name>action</property-name>
        <value>#{param.action}</value>
    </managed-property>
    <managed-property>
        <property-name>actionParam</property-name>
        <value>#{param.actionParam}</value>
    </managed-property>
</managed-bean>

这样请求 forward.jsf?action = outcome1& actionParam = 123 将让JSF将 action actionParam 参数设置为操作 actionParam ForwardBean 的属性。

This way the request forward.jsf?action=outcome1&actionParam=123 will let JSF set the action and actionParam parameters as action and actionParam properties of the ForwardBean.

创建一个小视图 forward.xhtml (这么小,它适合默认的响应缓冲区(通常为2KB),以便导航处理程序可以重置它,否则你需要增加servletcontainer配置中的响应缓冲区,它在 f:view beforePhase 上调用bean方法c>:

Create a small view forward.xhtml (so small that it fits in default response buffer (often 2KB) so that it can be resetted by the navigationhandler, otherwise you've to increase the response buffer in the servletcontainer's configuration), which invokes a bean method on beforePhase of the f:view:

<!DOCTYPE html>
<html xmlns:f="http://java.sun.com/jsf/core">
    <f:view beforePhase="#{forward.navigate}" />
</html>

ForwardBean 可能如下所示:

public class ForwardBean {
    private String action;
    private String actionParam;

    public void navigate(PhaseEvent event) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        String outcome = action; // Do your thing?
        facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, null, outcome);
    }

    // Add/generate the usual boilerplate.
}

navigation-rule 说明一切(请注意< redirect /> 条目,它们将执行 ExternalContext#redirect()而不是 ExternalContext #dispatch()在封面下):

The navigation-rule speaks for itself (note the <redirect /> entries which would do ExternalContext#redirect() instead of ExternalContext#dispatch() under the covers):

<navigation-rule>
    <navigation-case>
        <from-outcome>outcome1</from-outcome>
        <to-view-id>/outcome1.xhtml</to-view-id>
        <redirect />
    </navigation-case>
    <navigation-case>
        <from-outcome>outcome2</from-outcome>
        <to-view-id>/outcome2.xhtml</to-view-id>
        <redirect />
    </navigation-case>
</navigation-rule>






另一种方法是使用 forward.xhtml as

<!DOCTYPE html>
<html>#{forward}</html>

并更新 navigate()方法在 @PostConstruct 上调用(将在bean构造和所有托管属性设置之后调用):

and update the navigate() method to be invoked on @PostConstruct (which will be invoked after bean's construction and all managed property setting):

@PostConstruct
public void navigate() {
    // ...
}    

它具有相同的效果,但视图方面并非真正自我记录。所有它基本上都是打印 ForwardBean#toString()(并因此隐含地构造bean,如果还不存在)。

It has the same effect, however the view side is not really self-documenting. All it basically does is printing ForwardBean#toString() (and hereby implicitly constructing the bean if not present yet).

请注意,对于JSF2用户,有一种更简洁的方法可以使用< f:viewParam> 传递参数,并且更加健壮通过< f:event type =preRenderView> 处理重定向/导航的方式。另请参见:

Note for the JSF2 users, there is a cleaner way of passing parameters with <f:viewParam> and more robust way of handling the redirect/navigation by <f:event type="preRenderView">. See also among others:

  • Hit a bean method and redirect on a GET request
  • Is there any easy way to preprocess and redirect GET requests?

这篇关于如何在JSF中进行重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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