我有一个使用可选模块的Web应用程序。这些模块是作为Web Fragment项目实现的,根据构建配置文件,它们的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>
问题。
警告:此页面调用XML命名空间 http://company.com/module用前缀mod声明但没有 该命名空间存在taglibrary。
问题。
截至目前,我计划尽可能禁用警告:例如如果必须,覆盖消息渲染器并检查消息字符串。如果问题2出现,请为未部署的模块创建构建供应占位符taglib.xml文件。
答案 0 :(得分:0)
尽管占位符taglib似乎是一个非常好的解决方案,但它们似乎也难以实现和维护。
所以最后我去了过滤消息。这可能是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;
}
}
在faces-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>