如何在“中使用jsf”;名称空间模式“;
在一个网站中,我们希望集成jsf应用程序提供的一些代码片段,可以考虑一个仪表板应用程序或“门户灯”。在分析需求时,我们看到Arjan Tjims在上的一篇博客文章,其中提到了一种新的“名称空间模式”: 在名称空间模式中,该模式专门用于Portlet,但也可以在其他环境中使用,部分响应被赋予一个id,该id被视为“命名容器id”。所有预定义的回发参数名称(如“javax.faces.ViewState”、“javax.faces.ClientWindow”、“javax.faces.RenderKitId”等)都以该名称和命名分隔符(默认值为“:”)作为前缀。e、 当UIViewRoot实例实现NamingContainer接口时,名称空间模式被激活 我们的应用程序可能是“名称空间模式”的一个用例,所以我们想尝试一下 我们构建了一个如何在“中使用jsf”;名称空间模式“;,jsf,mojarra,jsf-2.3,Jsf,Mojarra,Jsf 2.3,在一个网站中,我们希望集成jsf应用程序提供的一些代码片段,可以考虑一个仪表板应用程序或“门户灯”。在分析需求时,我们看到Arjan Tjims在上的一篇博客文章,其中提到了一种新的“名称空间模式”: 在名称空间模式中,该模式专门用于Portlet,但也可以在其他环境中使用,部分响应被赋予一个id,该id被视为“命名容器id”。所有预定义的回发参数名称(如“javax.faces.ViewState”、“javax.faces.ClientWindow”、“javax.faces.RenderK
MyUIViewRoot
,在这里我们实现了NamingContainer
,并包装了原始的UIViewRoot
-实例。我们在faces config.xml
中注册了一个MyViewHandler
来处理ViewRoot的包装。为了进行测试,我们使用了一个带有两个
-元素的简单计数器应用程序(似乎很重要)
我们发现“名称空间模式”“似乎被激活了,例如,javax.faces.ViewState
确实是由某个名称空间预先设置的,并且变成了j_id1:javax.faces.ViewState:0
。但是这两个操作都不再起作用了-回发请求不再恢复视图,而是创建一个新的视图。因此,使用我们的简单方法,我们缺少了一些东西(顺便说一句,仅从MyUIViewRoot
中删除实现NamingContainer
,计数器应用程序再次正常工作)
- 有没有我们忽略的文档、指南或工作示例
- 如何正确激活“名称空间模式”?我们错过了什么使回发再次工作
- 如何使
在ViewState前面加上MyUIViewRoot
myNamespace
索引.xhtml
:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head/>
<h:body>
<h:form id="counterForm">
<h:panelGrid columns="2">
<h:outputLabel value="Counter" />
<h:outputText value="#{counterUiController.counter}" />
</h:panelGrid>
<h:commandButton value="inc" action="#{counterUiController.incAction}">
<f:ajax execute="@form" render="@form" />
</h:commandButton>
</h:form>
<h:form id="resetForm">
<h:commandButton value="reset" action="#{counterUiController.resetAction}">
<f:ajax execute="@form" render=":counterForm" />
</h:commandButton>
</h:form>
</h:body>
</html>
我们的UIViewRoot
-实现:
public class MyUIViewRoot extends UIViewRoot implements NamingContainer, FacesWrapper<UIViewRoot> {
private static final Logger LOG = Logger.getLogger(MyUIViewRoot.class.getName());
private UIViewRoot wrapped;
public MyUIViewRoot(UIViewRoot wrapped) {
this.wrapped = wrapped;
LOG.log(Level.INFO, "new instance created: {0}", this);
}
@Override
public UIViewRoot getWrapped() {
return wrapped;
}
@Override
public String createUniqueId() {
return wrapped==null ? null : wrapped.createUniqueId();
}
@Override
public void setId(String id) {
if( wrapped!=null ) {
wrapped.setId(id);
}
}
// all other methodes delegated to `wrapped` directly
}
您需要替换
UIViewRoot
而不是包装它
public class NamespacedView extends UIViewRoot implements NamingContainer {
//
}
然后在faces config.xml
中
<component>
<component-type>javax.faces.ViewRoot</component-type>
<component-class>com.example.NamespacedView</component-class>
</component>
javax.faces.ViewRoot
com.example.NamespacedView
基本上就这些了。另请参见。Ouch,这很简单。要使用
myNamespace
作为前缀,我们只需要覆盖getId
,我想?不支持
。所以覆盖getId()
可能是最好的选择。
public class NamespacedView extends UIViewRoot implements NamingContainer {
//
}
<component>
<component-type>javax.faces.ViewRoot</component-type>
<component-class>com.example.NamespacedView</component-class>
</component>