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


问题内容

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

http://ocpsoft.com/docs/prettyfaces/snapshot/zh-
CN/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,其中URL类型在井号(#)后列出。这个想法是要有一个基于ajax的Bookmarkable
URL。因此,每次我单击更改系统状态的元素时,该值都会通过ajax和重写哈希后的URL发送到服务器。哈希后可以有1到3个参数,参数的数目是可选的。

我的目标是,当用户为URL添加书签(带有哈希)并重新访问已保存的页面时,该页面应将正确的值注入系统并以先前状态(如查询参数)可视化该页面。

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

//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中的方法?


问题答案:

您可以借助此方法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;
    }

}

就这样。

Note that the onhashchange event is relatively new and not supported by the
older browsers. In absence of the browser support (undefinied and so on),
you’d like to check
window.location.hash at
intervals using
setInterval()
instead. The above code example should at least give a good kickoff. It works
at at least FF3.6 and IE8.