使用可选的 facelet 标签库
Using optional facelet tag libraries
我有一个使用可选模块的 Web 应用程序。这些模块作为 Web 片段项目实现,它们的 jar 可能会或可能不会部署 war 取决于构建配置文件。
一个模块可以包含它自己的 module.taglib.xml
,带有 http://company.com/module
命名空间和一些标签。
war xhtml 模板使用如下模块标签:
<ui:composition ... xmlns:mod="http://company.com/module">
<c:if test="#{moduleDeployed}">
<mod:someTag />
</c:if>
问题。
- 当模块未部署时,war 页面工作正常,但在 ProjectStage.Development 中我收到 FacesMessage warnings:
Warning: This page calls for XML namespace
http://company.com/module declared with prefix mod but no
taglibrary exists for that namespace.
- 据我所知,JSF 规范没有定义当模板使用不存在的标签库时会发生什么。因此,使用我当前的方法 war 页面可以在升级或切换到不同的 JSF 实现后停止工作。
问题。
- 有没有(不是很丑陋的)方法来禁用这个特定的 warning?
- 是否有更好的方法来使用可选的 facelet 标记库?
截至目前,我计划尽我所能禁用 warning:例如覆盖消息渲染器并在必要时检查消息字符串。如果出现问题 2,请为未部署的模块创建构建供应占位符 taglib.xml 文件。
尽管占位符标签库似乎是一个很好的解决方案,但它们似乎也更难实施和维护。
所以最后我过滤了消息。这可能是 Mojarra 特有的:消息文本,迭代器允许删除的事实(规范不禁止,但也不是必需的)。它可以与 Mojarra 2.2.8 到 2.2.13 一起使用。
public class SuppressNoTaglibraryExistsFacesMessage implements SystemEventListener {
private static final Pattern PTTRN_NO_TAGLIBRARY_EXISTS_FOR_NAMESPACE =
Pattern.compile("Warning: This page calls for XML namespace \S+ declared with "
+ "prefix \S+ but no taglibrary exists for that namespace.");
@Override
public void processEvent(SystemEvent event) {
Iterator<FacesMessage> messages = FacesContext.getCurrentInstance().getMessages();
while (messages.hasNext()) {
String messageSummary = messages.next().getSummary();
if (PTTRN_NO_TAGLIBRARY_EXISTS_FOR_NAMESPACE.matcher(messageSummary).matches()) {
messages.remove();
}
}
}
@Override
public boolean isListenerForSource(Object source) {
return true;
}
}
仅在开发项目阶段绑定侦听器。
public class SubscribeListenersAfterApplicationPostConstructListener
implements SystemEventListener {
@Override
public void processEvent(SystemEvent event) throws AbortProcessingException {
Application application = (Application) event.getSource();
if (ProjectStage.Development.equals(application.getProjectStage())) {
application.subscribeToEvent(PostAddToViewEvent.class, UIViewRoot.class,
new SuppressNoTaglibraryExistsFacesMessage());
}
}
@Override
public boolean isListenerForSource(Object source) {
return source instanceof Application;
}
}
在脸上-config.xml:
<system-event-listener>
<system-event-listener-class><packages>.SubscribeListenersAfterApplicationPostConstructListener</system-event-listener-class>
<system-event-class>javax.faces.event.PostConstructApplicationEvent</system-event-class>
</system-event-listener>
我有一个使用可选模块的 Web 应用程序。这些模块作为 Web 片段项目实现,它们的 jar 可能会或可能不会部署 war 取决于构建配置文件。
一个模块可以包含它自己的 module.taglib.xml
,带有 http://company.com/module
命名空间和一些标签。
war xhtml 模板使用如下模块标签:
<ui:composition ... xmlns:mod="http://company.com/module">
<c:if test="#{moduleDeployed}">
<mod:someTag />
</c:if>
问题。
- 当模块未部署时,war 页面工作正常,但在 ProjectStage.Development 中我收到 FacesMessage warnings:
Warning: This page calls for XML namespace http://company.com/module declared with prefix mod but no taglibrary exists for that namespace.
- 据我所知,JSF 规范没有定义当模板使用不存在的标签库时会发生什么。因此,使用我当前的方法 war 页面可以在升级或切换到不同的 JSF 实现后停止工作。
问题。
- 有没有(不是很丑陋的)方法来禁用这个特定的 warning?
- 是否有更好的方法来使用可选的 facelet 标记库?
截至目前,我计划尽我所能禁用 warning:例如覆盖消息渲染器并在必要时检查消息字符串。如果出现问题 2,请为未部署的模块创建构建供应占位符 taglib.xml 文件。
尽管占位符标签库似乎是一个很好的解决方案,但它们似乎也更难实施和维护。
所以最后我过滤了消息。这可能是 Mojarra 特有的:消息文本,迭代器允许删除的事实(规范不禁止,但也不是必需的)。它可以与 Mojarra 2.2.8 到 2.2.13 一起使用。
public class SuppressNoTaglibraryExistsFacesMessage implements SystemEventListener {
private static final Pattern PTTRN_NO_TAGLIBRARY_EXISTS_FOR_NAMESPACE =
Pattern.compile("Warning: This page calls for XML namespace \S+ declared with "
+ "prefix \S+ but no taglibrary exists for that namespace.");
@Override
public void processEvent(SystemEvent event) {
Iterator<FacesMessage> messages = FacesContext.getCurrentInstance().getMessages();
while (messages.hasNext()) {
String messageSummary = messages.next().getSummary();
if (PTTRN_NO_TAGLIBRARY_EXISTS_FOR_NAMESPACE.matcher(messageSummary).matches()) {
messages.remove();
}
}
}
@Override
public boolean isListenerForSource(Object source) {
return true;
}
}
仅在开发项目阶段绑定侦听器。
public class SubscribeListenersAfterApplicationPostConstructListener
implements SystemEventListener {
@Override
public void processEvent(SystemEvent event) throws AbortProcessingException {
Application application = (Application) event.getSource();
if (ProjectStage.Development.equals(application.getProjectStage())) {
application.subscribeToEvent(PostAddToViewEvent.class, UIViewRoot.class,
new SuppressNoTaglibraryExistsFacesMessage());
}
}
@Override
public boolean isListenerForSource(Object source) {
return source instanceof Application;
}
}
在脸上-config.xml:
<system-event-listener>
<system-event-listener-class><packages>.SubscribeListenersAfterApplicationPostConstructListener</system-event-listener-class>
<system-event-class>javax.faces.event.PostConstructApplicationEvent</system-event-class>
</system-event-listener>