未为 myfaces 中的 Head 触发 PostAddToView 事件
PostAddToView event not fired for Head in myfaces
我正在向所有页面动态注入一些 JS,这在 Mojarra 中运行良好,但我发现它在 myfaces 中失败了。
我的事件侦听器配置为:
<application>
<system-event-listener>
<system-event-listener-class>a.b.HeadResourceListener</system-event-listener-class>
<system-event-class>javax.faces.event.PostAddToViewEvent</system-event-class>
<source-class>javax.faces.component.UIOutput</source-class>
</system-event-listener>
</application>
代码类似于:
public class HeadResourceListener implements SystemEventListener {
@Override
public boolean isListenerForSource(Object source) {
return "javax.faces.Head".equals(((UIComponent) source).getRendererType());
}
@Override
public void processEvent(SystemEvent event) {
UIComponent outputScript = new UIOutput();
outputScript.setRendererType("javax.faces.resource.Script");
UIOutput content = new UIOutput();
content.setValue("var abc='';");
outputScript.getChildren().add(content);
context.getViewRoot().addComponentResource(context, outputScript, "head");
}
}
不幸的是,对于 myfaces,源的 rendererType 从来不是 javax.faces.Head(我只发现 javax.faces.resources.Script 和 javax.faces.resources.Stylesheet)
这里的行为不同有什么具体原因吗?
对其他解决方案有什么建议吗?
编辑
如建议的那样,当将此侦听器链接到 source-class 时,它会在 myfaces 中触发。但是,在回发时,我收到重复的 ID 错误...
Caused by: org.apache.myfaces.view.facelets.compiler.DuplicateIdException: Component with duplicate id "j_id__v_7" found. The first component is {Component- Path : [Class: javax.faces.component.UIViewRoot,ViewId: /user/login.xhtml][Class: org.apache.myfaces.component.ComponentResourceContainer,Id: javax_faces_location_head][Class: javax.faces.component.UIOutput,Id: j_id__v_7]}
at org.apache.myfaces.view.facelets.compiler.CheckDuplicateIdFaceletUtils.createAndQueueException(CheckDuplicateIdFaceletUtils.java:148)
at [internal classes]
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:73)
at org.apache.myfaces.tomahawk.application.ResourceViewHandlerWrapper.renderView(ResourceViewHandlerWrapper.java:169)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:73)
这是 MyFaces 中的错误。
JSF 2.3 specification 在 table 9.2 中表示以下内容:
TABLE 9-2 Standard HTML RenderKit Tag Library
getComponentType() getRendererType()
javax.faces.Output javax.faces.Head
根据同一规范的第 4.1.10.1 章,javax.faces.Output
映射到 javax.faces.component.UIOutput
。
4.1.10.1 Component Type
The standard component type for UIOutput
components is “javax.faces.Output
”.
因此,<h:head>
必须是 UIOutput
的实例。
如果我们回顾一下 table 9.2,javax.faces.Output
可以有多个渲染器,所以你确实只能监听 javax.faces.component.UIOutput
的 <source-class>
并且你会必须手动检查其渲染器类型为 javax.faces.Head
。你的 HeadResourceListener
是正确的。
另请参阅:
我正在向所有页面动态注入一些 JS,这在 Mojarra 中运行良好,但我发现它在 myfaces 中失败了。
我的事件侦听器配置为:
<application>
<system-event-listener>
<system-event-listener-class>a.b.HeadResourceListener</system-event-listener-class>
<system-event-class>javax.faces.event.PostAddToViewEvent</system-event-class>
<source-class>javax.faces.component.UIOutput</source-class>
</system-event-listener>
</application>
代码类似于:
public class HeadResourceListener implements SystemEventListener {
@Override
public boolean isListenerForSource(Object source) {
return "javax.faces.Head".equals(((UIComponent) source).getRendererType());
}
@Override
public void processEvent(SystemEvent event) {
UIComponent outputScript = new UIOutput();
outputScript.setRendererType("javax.faces.resource.Script");
UIOutput content = new UIOutput();
content.setValue("var abc='';");
outputScript.getChildren().add(content);
context.getViewRoot().addComponentResource(context, outputScript, "head");
}
}
不幸的是,对于 myfaces,源的 rendererType 从来不是 javax.faces.Head(我只发现 javax.faces.resources.Script 和 javax.faces.resources.Stylesheet)
这里的行为不同有什么具体原因吗? 对其他解决方案有什么建议吗?
编辑
如建议的那样,当将此侦听器链接到 source-class 时,它会在 myfaces 中触发。但是,在回发时,我收到重复的 ID 错误...
Caused by: org.apache.myfaces.view.facelets.compiler.DuplicateIdException: Component with duplicate id "j_id__v_7" found. The first component is {Component- Path : [Class: javax.faces.component.UIViewRoot,ViewId: /user/login.xhtml][Class: org.apache.myfaces.component.ComponentResourceContainer,Id: javax_faces_location_head][Class: javax.faces.component.UIOutput,Id: j_id__v_7]}
at org.apache.myfaces.view.facelets.compiler.CheckDuplicateIdFaceletUtils.createAndQueueException(CheckDuplicateIdFaceletUtils.java:148)
at [internal classes]
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:73)
at org.apache.myfaces.tomahawk.application.ResourceViewHandlerWrapper.renderView(ResourceViewHandlerWrapper.java:169)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:73)
这是 MyFaces 中的错误。
JSF 2.3 specification 在 table 9.2 中表示以下内容:
TABLE 9-2 Standard HTML RenderKit Tag Library
getComponentType() getRendererType() javax.faces.Output javax.faces.Head
根据同一规范的第 4.1.10.1 章,javax.faces.Output
映射到 javax.faces.component.UIOutput
。
4.1.10.1 Component Type
The standard component type for
UIOutput
components is “javax.faces.Output
”.
因此,<h:head>
必须是 UIOutput
的实例。
如果我们回顾一下 table 9.2,javax.faces.Output
可以有多个渲染器,所以你确实只能监听 javax.faces.component.UIOutput
的 <source-class>
并且你会必须手动检查其渲染器类型为 javax.faces.Head
。你的 HeadResourceListener
是正确的。