如何在“中使用jsf”;名称空间模式“;

如何在“中使用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

在一个网站中,我们希望集成jsf应用程序提供的一些代码片段,可以考虑一个仪表板应用程序或“门户灯”。在分析需求时,我们看到Arjan Tjims在上的一篇博客文章,其中提到了一种新的“名称空间模式”:

在名称空间模式中,该模式专门用于Portlet,但也可以在其他环境中使用,部分响应被赋予一个id,该id被视为“命名容器id”。所有预定义的回发参数名称(如“javax.faces.ViewState”、“javax.faces.ClientWindow”、“javax.faces.RenderKitId”等)都以该名称和命名分隔符(默认值为“:”)作为前缀。e、 当UIViewRoot实例实现NamingContainer接口时,名称空间模式被激活

我们的应用程序可能是“名称空间模式”的一个用例,所以我们想尝试一下

我们构建了一个
MyUIViewRoot
,在这里我们实现了
NamingContainer
,并包装了原始的
UIViewRoot
-实例。我们在
faces config.xml
中注册了一个
MyViewHandler
来处理ViewRoot的包装。为了进行测试,我们使用了一个带有两个
-元素的简单计数器应用程序(似乎很重要)

我们发现“名称空间模式”“似乎被激活了,例如,
javax.faces.ViewState
确实是由某个名称空间预先设置的,并且变成了
j_id1:javax.faces.ViewState:0
。但是这两个操作都不再起作用了-回发请求不再恢复视图,而是创建一个新的视图。因此,使用我们的简单方法,我们缺少了一些东西(顺便说一句,仅从
MyUIViewRoot
中删除
实现NamingContainer
,计数器应用程序再次正常工作)

  • 有没有我们忽略的文档、指南或工作示例
  • 如何正确激活“名称空间模式”?我们错过了什么使回发再次工作
  • 如何使
    MyUIViewRoot
    在ViewState前面加上
    myNamespace
该应用程序正在payara-5应用程序服务器中运行

我们的
索引.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>