0

我有一个 JSF 2.0(和 Richfaces 4.0)应用程序,我想做一些看似简单的事情。

我有一个登录页面 (/index.xhtml),它是当有人键入“www.xxx.com”时出现的“欢迎页面”,其中 xxx 作为我的域。

  1. 我希望有一个备用目标网页,它将成为我们正在运行的广告的目标。因为我要高度定制这个内容,所以我打算处理这个的方法就是有一个新页面:www.xxx.com/intro.xhtml。到目前为止,一切都很好。我的索引页面 index.xhtml(及其副本 intro.xhtml)有一堆链接的公共页面:“它是如何工作的”、“注册”等......非常典型的东西。
  2. 问题是当转到“它是如何工作的”然后返回主页时,如何保存或跟踪目标用户通过 intro.xhtml 进入我的站点的事实?

将成为问题的用例是:

  • 用户通过广告进入,他们在 intro.xhtml 中包含自定义内容。
  • 他们转到一个共享的主页(“它是如何工作的”)。
  • 然后他们单击主页(或站点图标)返回主页。现在他们回到了欢迎页面(index.xhtml),这会让他们感到困惑。

我能想到的只有:

  • 我可以制作我所有其他公共页面的“深拷贝”(例如,将 how_it_works 复制到 how_it_works_intro),然后当有人从中选择主页时,将 _intro 页面链接返回到 intro.xhtml 页面,但这似乎真的很愚蠢。
  • 在 servlet 过滤器中对请求进行一些后期处理(比如在用户最初点击 intro.xhtml 时设置会话变量),并在他们点击主页时使用这个事实将它们路由回 intro.xhtml。但这似乎是个坏主意,因为我不想在他们登录之前开始会话。它还避免了将所有页面流保留在 faces-config.xml 中,到目前为止我为整个应用程序所做的。
4

3 回答 3

0

Ok guys, I <think> I completely nailed it and came up with an elegant solution. It may be obvious to those whom are experts in JSF but I'm definitely not (I'm more a backend Java EE programmer)

Here's exactly what I did.

  1. added a landingPage attribute to my userBean (my user session bean). As stated above I don't care that I'm starting a session on my home page(s) because I'm doing it anyway.
  2. in all my landing pages I add the follwing with the appropriate URI that points back to the page itself. In this case /index resolves to the index page itself. in index.xhtml added:

     #{userBean.setLandingPage('/index')}
    

in intro.xhtml added:

     #{userBean.setLandingPage('/intro')}
  1. Then all I needed to do is adjust all references in my JSF pages to reference the session value. So in my header.xhtml I change all

    <h:commandLink class="active" action="/index">home</h:commandLink>
    

    to

    <h:commandLink class="active" action="#{userBean.getLandingPage}">home</h:commandLink>
    
  2. Only the home page references need to change, none of the other links need to change

  3. It will also be REAL easy to add additional landing pages and the stateful behavior.

I'm real happy with the solution. Thanks everyone!

于 2012-08-14T23:45:07.840 回答
0

通常这是通过向查询字符串添加一些参数来实现的。例如:

从您的 intro.xhtml 中,将这些参数附加到“工作原理”页面,如下所示:

<h:link value="How it works" outcome="howitworks" includeViewParams="true">
   <f:param name="landingvia" value="intro"/>
</h:link>

然后在你的 howitworks.xhtml 中渲染主页链接,如下所示:

<h:link value="Home" outcome="intro" rendered="#{param.landingvia == 'intro'}" />
<h:link value="Home" outcome="index" rendered="#{param.landingvia == 'index'}" />
于 2012-08-12T23:40:20.920 回答
0

在尝试实施 Ravi 提出的解决方案时,存在以下问题:

  1. 我的应用程序大量利用 JSF 模板(通过 ui:composition),因此下面的答案不会直接起作用。但解决方法是使用确实有效的 ui:param 标签。所以我在索引和介绍页面中添加了以下内容:

    <!-- this is in my intro.xhtml page -->
    <ui:composition template="templates/header-public.xhtml">
    <ui:param name="landingvia" value="intro"/>
    

与 index.xhtml 页面中的类似行

    <ui:param name="landingvia" value="index"/>
  1. 然后在 header-public.xhtml 页面中,我需要根据 Ravi 更改链接(从内存中执行此操作),但您明白了。请注意,我需要使用“landingvia”而不是“param.landingvia”可能是因为诱人。

    <h:commandLink value="Home" outcome="/intro" rendered="#{landingvia == 'intro'}" ><f:param name="landingvia" value="intro" /> </h:commandLink
    <h:commandLink value="Home" outcome="/index" rendered="#{landingvia == 'index'}" ><f:param name="landingvia" value="index" /> </h:commandLink
    <h:commandLink value="About" outcome="/about" rendered="#{landingvia == 'intro'}" ><f:param name="landingvia" value="intro" /> </h:commandLink
    <h:commandLink value="About" outcome="/about" rendered="#{landingvia == 'index'}" ><f:param name="landingvia" value="index" /> </h:commandLink
    

    ...我需要对模板中包含的页眉和页脚(具有其他链接)和图像链接(徽标等)上的所有链接(contactus、faq 等)进行相同的复制。 ..) 以及从say faq 到termsAndConditions.xhtml 的链接......不是一个好的解决方案。

  2. 如果我不将 f:param 标记添加到上面的所有 commandLinks 中,则状态为“丢失”,这是有道理的。当我从介绍转到 About 时,About 页面如何在没有 f:param 标签的情况下跟踪登录页面?

  3. 更糟糕的是,从任何页面到任何页面的所有链接都需要遵循这种模式。所以这不是一个好的解决方案,除非我做错了什么。

  4. 作为最后一个问题,我发现即使所有链接都如上所述重复,该解决方案仍然无法正常工作,因为当有即时表单(这些表单将 form.submit() 发送回它们自己)时,无论如何状态都会丢失。

在这一点上,我将只管理服务器端的状态。所以我可以使用我的用户会话 bean 或设置会话 cookie。

  • 无论如何,我正在我的主页上创建一个会话级别的“用户”对象。所以我可以通过从 intro.xhtml 调用来使用它

    #{userBean.setLandingPage('intro')
    
  • 或者从任一页面设置 cookie。

一旦我将一个值(“index”或“intro”)放入会话中(通过 cookie 或会话 bean),我就可以询问 ServletFilter 中的所有 URL,以及它的目标是“/index”还是“/”或“ /index.xhtml" 然后我将使用会话变量。如果它包含值“intro”,我会将用户发送到 /intro.xhtml。

如果没有大量的工作,我不知道该怎么做。但是上面的解决方案在不改变任何链接的情况下运行良好,而且它还有一个额外的好处,就是可以根据我的需要扩展到尽可能多的登陆页面。让我知道你的想法,Ravi 如果我没有得到你的解决方案,请告诉我。

于 2012-08-14T18:35:33.160 回答