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

我正在寻找一种方法将URL的片段(#)中的值注入bean(JSF),就像注入查询参数值一样。 我正在使用Ben Alman的Bookmarkable 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-决赛,
JSF:2.0.2-FCS,
PrettyFaces:3.0.1

Web应用程序生成以下类型的URL,其中参数在散列(#)之后列出。 我们的想法是拥有一个基于ajax的Bookmarkable 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片段发送到服务器端逻辑,

  • http://maps.yahoo.com/#mvt=m&lat=36.952736&lon=-95.84758&zoom=11&tt=starbucks&tp=1&ioride=us
  • http://www.cbc.ca/video/#/Shows/Death_Comes_to_Town/ID=1365210427

无论如何将URL片段中的值注入服务器端bean?

您可以在window.onhashchange帮助下完成此操作,该window.onhashchange填充隐藏表单的输入字段,该字段在输入字段更改时异步提交。

这是Facelets页面的启动示例:

    SO question 3475076          

Change the fragment in the URL. Either manually or by those links: foo, bar, baz

Fragment is currently:

以下是适当的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; } } 

就这样。

请注意, onhashchange事件相对较新,旧版浏览器不支持。 如果没有浏览器支持(未定义等),您需要使用setInterval()定期检查window.location.hash 。 上面的代码示例至少应该给出一个很好的启动。 它至少适用于FF3.6和IE8。

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

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

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

观看这个问题,特别是答案: JSP Servlet锚点

  • 在服务器端无法看到片段。
  • 您可以在客户端提取片段,将其转换并通过Ajax发送到服务器。

从服务器端看不到该片段,它只能由客户端脚本访问。 通常这样做的方式是服务器端生成非参数化页面,然后根据片段参数由脚本修改。 脚本可以使用查询参数发出AJAX请求,其中AJAX响应由JSF使用由参数控制的bean生成。

如果您绝对希望服务器端在呈现页面本身时能够访问片段参数,则需要使用参数作为查询参数重新加载页面。

编辑:要重新加载页面,您可以使用此代码:

 if (window.location.hash != '') { var newsearch = window.location.search; if(newsearch != '') { newsearch += '&'; } newsearch += window.location.hash.match(/#?(.*)/)[1]; window.location.hash = ''; window.location.search = newsearch; } 

非常感谢您的想法和特别是BalusC(对您而言非常荣幸)。 我的最终解决方案是轻微的变异,我想与大家分享。

由于我使用的是richfaces 3.3.3,它就像使用jsf1.2,因此没有

在传统情况下,您应该点击链接,其中href指向内部链接 。 我正在使用许多预先打包的组件,而不是每个可点击的项目都是链接 。 它可以是任何html元素。 使用Ben Alman的Bookmarkable jQuery插件非常有用( http://benalman.com/projects/jquery-bbq-plugin/

请注意下面的,onclick我可以通过编程方式将片段的值设置为键/值,并在下面的代码中用新值jQuery.bbq.pushState(state,2)替换旧值(或者我可以简单地添加旧值jQuery.bbq.pushState(state)后面。

在我的例子中, ws->md->nd是一个分层数据,它足以让其中一个及其父项在服务器上计算,所以我用父值替换父值。

     

在richfaces中,这是一种使用参数从浏览器调用setter方法的很酷的方法。 请注意, sendURLFragment被视为具有5个参数的JS方法,并且值将传递给服务器(这非常酷)。

  

当您复制粘贴新url并加载页面时,请执行此操作。

 window.onload = function(){ if(window.location.hash != ""){ //Parse the fragment (hash) from a URL, deserializing it into an object var deparamObj = jQuery.deparam.fragment(); var ws= '', md= '', nd= '', ld= '', ln = ''; jQuery.each(deparamObj, function(key, value) { switch(key){ case 'ws': ws = value; break; case 'md': md = value; break; case 'nd': nd = value; break; case 'ld': ld = value; break; case 'ln': ln = value; break; default: break; } }); sendURLFragment(ws,md,nd,ld,ln); } };