2

我有几个 portlet,每个 portlet 在单个 Web 应用程序中使用汇集的 CSS 和 JS 文件的聚合。目前每个portlet 都会在doHeaders() 中添加适当的head 标签。但是,当多个 portlet 位于同一页面上时,这会导致头部中出现重复的标记。

目前,portlet 部署在运行于 GateIn的eXo上。eXo 有它自己的 JS AMD 框架和 portlet 皮肤系统,但我们使用 doHeaders() 添加头元素以尽可能地与平台无关以降低风险。

头元素以下列方式添加:

@Override
public void doHeaders(RenderRequest request, RenderResponse response)
{
    Element element = response.createElement("link");
    element.setAttribute("type", "text/css");
    element.setAttribute("rel", "stylesheet");
    element.setAttribute("href", request.getContextPath() + "/service/resource/themes/stylesheet.css");
    response.addProperty(MimeResponse.MARKUP_HEAD_ELEMENT, element);
}

我需要从头中删除重复的条目,或者首先防止重复写入。

我正在尝试编写一个可以去除重复头部元素的通用 RenderFilter。但我似乎无法从RenderResponse访问当前的 Element 属性;我只能 setProperty() 或 addProperty()。

我还可以编写 RenderFilter 来替换每个单独的 portlet 的 doHeaders() 方法,并将整个 CSS 和 JS 池添加到头部。但是我不能确保这个逻辑只会在每个用户会话页面呈现时运行。

4

1 回答 1

2

我目前实现的一个解决方案是 RenderFilter,如果池尚未写入,它将整个 JS 和 CSS 资源池写入头部。这在某种程度上是次优的,因为检测待处理的头部元素不是我发现可以以独立于平台的方式完成的事情。但是,决定如何处理冗余头元素完全取决于平台委托,因为 JSR-286 并未规定在这种情况下应该做什么。

通过使用 eXo 的 PortalRequestContext,可以获得待处理的头元素列表。通过添加元元素来标识资源池,RenderFilter 可以决定是否需要写入资源池或是否已经写入资源池。

这是基本的检测逻辑:

boolean addHeaderElements = true;
if (Util.getPortalRequestContext() != null && Util.getPortalRequestContext().getExtraMarkupHeaders() != null)
{
    for (Element markupHeaderElement : Util.getPortalRequestContext().getExtraMarkupHeaders())
    {
        if (markupHeaderElement.getTagName().equalsIgnoreCase("meta") &&
            markupHeaderElement.getAttribute("name") != null &&
            markupHeaderElement.getAttribute("name").equalsIgnoreCase("project-name"))
        {
            addHeaderElements = false;
            break;
        }
    }
}

这也可以编写为基于文件进行操作,但我的 portlet 的资源池通常是共享的,以至于可以使用全有或全无的方法。

于 2013-11-06T17:33:55.810 回答