问题
viewId 已在应用程序范围内解决。解决只发生一次,而不是每次
任务
将 JSF 1.2 (Sun.RI) 应用程序迁移到 JSF2.0(Myfaces)。此应用程序有一个覆盖的 FacesViewHandler,其中包含自定义 FacletContext、DefaultFaceletFactory、DefaultFactory 和自定义 ResourceResolver。
我们根据会话数据为 viewId 提供自定义内容
示例:
浏览器需要 viewId order.jsf,应用程序将此 viewId 解析为 order_advanced.jsf。但是在浏览器中只有 order.jsf 可见。
这很容易实现。我们使用 MappingBean 来映射 viewId。这个 MappingBean 在会话开始时被实例化,Resolver 使用这个 Mapping Bean。
我们有什么:
- 我们的映射 Bean 已就位且功能齐全。
自定义资源解析器
@Override public URL resolveUrl(final String path) { final PageMappingBean pmb = (PageMappingBean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get( "pageMappingBean"); URL returnURL = _resolver.resolveUrl(pmb != null ? pmb.mapUrl(path) : path); return returnURL; }
观察
访问一个被映射的viewid,适用于第一个会话。它被映射和解析。
使用不同的映射启动新会话不再解析 viewid。
这是由于方法(来自 Myfaces)
public Facelet getFacelet(String uri){
URL url = (URL) _relativeLocations.get(uri);
if (url == null)
{
url = resolveURL(_baseUrl, uri);
if (url != null)
{
Map<String, URL> newLoc = new HashMap<String, URL>(_relativeLocations);
newLoc.put(uri, url);
_relativeLocations = newLoc;
}
else
{
throw new IOException("'" + uri + "' not found.");
}
}
return this.getFacelet(url);
}
在“DefaultFaceletFactory”类中
问题
我们如何在Myfaces(生产和测试环境)中覆盖上述方法。如上所述,我们已经为 JSF1.2 完成了此操作,但在 JSF 2.0 中有额外的 VDL 层。
还是有其他方法可以解决问题?
注意
FacesFlow 可能是我们问题的解决方案,但它不能在 WAS8.0 应用服务器中使用,我们不允许:-(
对于 Mojarra(RI),我们有一个解决方案。可以设置上下文-param com.sun.faces.faceletFactory。这个解决方案对我们有用,但只能在开发环境中使用。生产和测试基于Myfaces。
现在我们已经放弃了拥有一个应用程序范围的 FaceletFactory 的想法。我们正在使用 facelets 的动态分辨率:
<ui:component xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<ui:include src="#{faceletMapper.map('/pagetoload.xhtml')}"/>
</ui:component>