从 URL 中检索片段(哈希),并将值注入 Bean 中

我正在寻找一种将URL片段(#)中的值注入bean(JSF)的方法,就像注入查询参数值一样。我正在使用Ben Alman的Backloadable jQuery插件(http://benalman.com/projects/jquery-bbq-plugin/)来创建URL片段。我希望来自prettyFaces的自定义正则表达式模式可以成为解决我问题的一种方法,但直到现在我还没有成功。

(http://ocpsoft.com/docs/prettyfaces/snapshot/en-US/html_single/#config.pathparams.regext)

我想在这里定义我的情况,如果有人有想法,我很乐意尝试一下。

我正在使用
RichFaces:3.3.3,
Spring:3.0.2.RELEASE,
Hibernate:3.5.3-Final,
JSF:2.0.2-FCS,
PrettyFaces:3.0.1

Web 应用程序生成以下类型的 URL,其中参数列在 hash(#) 之后。这个想法是有一个基于ajax的可书签URL。因此,每次我单击更改系统状态的元素时,该值都会在重写哈希值后通过ajax和URL发送到服务器。哈希后可以有1到3个参数,参数数量是可选的。

我的目标是,当用户为URL添加书签(使用哈希)并重新访问保存的页面时,页面应将正确的值注入系统,并以以前的状态可视化页面(如query-parameter)。

下面,我有一个正则表达式,可以捕获哈希值之后的所有参数。

//URL:   
http://localhost:8080/nymphaea/workspace/#node=b48dd073-145c-4eb6-9ae0-e1d8ba90303c&lod=75e63fcd-f94a-49f5-b0a7-69f34d4e63d7&ln=en

//Regular Expression:    
\#(\w*\=(\w{8}-\w{4}-\w{4}-\w{4}-\w{12}))|\&(\w*\=(\w{8}-\w{4}-\w{4}-\w{4}-\w{12}))|\&(\w*\=\w{2})

我知道有些网站是如何将URL片段发送到那里的服务器端逻辑,

是否无论如何都可以将URL片段中的值注入到服务器端Bean中?


答案 1

您可以借助 window.onhashchange 执行此操作,该窗口填充隐藏表单的输入字段,该表单在输入字段更改时异步提交自身。

以下是Facelets页面的启动示例:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>SO question 3475076</title>
        <script>
            window.onload = window.onhashchange = function() {
                var fragment = document.getElementById("processFragment:fragment");
                fragment.value = window.location.hash;
                fragment.onchange();
            }
        </script>
        <style>.hide { display: none; }</style>
    </h:head>
    <h:body>
        <h:form id="processFragment" class="hide">
            <h:inputText id="fragment" value="#{bean.fragment}">
                <f:ajax event="change" execute="@form" listener="#{bean.processFragment}" render=":showFragment" />
            </h:inputText>
        </h:form>
        <p>Change the fragment in the URL. Either manually or by those links:
            <a href="#foo">foo</a>, <a href="#bar">bar</a>, <a href="#baz">baz</a>
        </p>
        <p>Fragment is currently: <h:outputText id="showFragment" value="#{bean.fragment}" /></p>
    </h:body>
</html>

以下是适当的Bean的外观:

package com.stackoverflow.q3475076;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.event.AjaxBehaviorEvent;

@ManagedBean
@RequestScoped
public class Bean {

    private String fragment;

    public void processFragment(AjaxBehaviorEvent event) {
        // Do your thing here. This example is just printing to stdout.
        System.out.println("Process fragment: " + fragment);
    }

    public String getFragment() {
        return fragment;
    }

    public void setFragment(String fragment) {
        this.fragment = fragment;
    }

}

就这样。

请注意,该事件相对较新,旧版浏览器不支持该事件。在没有浏览器支持(未定义等)的情况下,您希望使用setInterval()每隔一段时间检查window.location.hash。上面的代码示例至少应该给出一个很好的开端。它至少可以工作FF3.6和IE8。onhashchange


答案 2

这是从语法上有效的URL / URI中提取片段的最可靠方法。

 URI uri = new URI(someString);
 String fragment = uri.getFragment();

如何将其注入 Bean 将取决于您使用的服务器端框架,以及您是使用 XML 或注释进行注入,还是以编程方式进行注入。