【问题标题】:Get ViewID in JSF while using templates使用模板时在 JSF 中获取 ViewID
【发布时间】:2018-10-09 12:18:41
【问题描述】:

我试图在单击按钮后立即在 JSF 中获取我的 RequestID 或 RequestURI。我试过这个:

    FacesContext context = FacesContext.getCurrentInstance();
    ExternalContext exContext = context.getExternalContext();
    Map<String, String> x = exContext.getRequestHeaderMap();
    System.out.println(x.get("request"));
    System.out.println(context.getViewRoot().getViewId());
    System.out.println(exContext.getRequestContextPath());

问题是,我的页面是一个模板,它使用新的 XHTML 重新加载侧面的一部分。基本的一面是home.xhtml,我总是得到这个ID。

但我需要的是其中包含的 XHTML,例如 view1.xhtml(在 home.xhtml 中加载)。

这可能吗?我需要这个来将请求视图保存在我的小型翻译应用程序的数据库中。

编辑: 我的 WebApp 应该跟踪哪个视图调用了我的资源包中的特殊翻译标签,并将视图(view1.xthml,而不是 home.xhtml)和标签写入数据库。也许也可以获取 html 元素 ID(但这并不重要)?每个视图都有多个包含!

示例:login.xhtml 包含在 home.xhtml 中

<p:panel header="#{translations['titel']}">

现在应用应该保存(login.xhtml,标题)。

谢谢!

EDIT2:

XHTML:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
    <title>example</title>
    <link rel="shortcut icon" type="image/x-icon"
          href="#{request.contextPath}/resources/images/logo/example.ico"/>
</h:head>

<h:body>
    <h:form id="menubar">
        <p:menubar>
            <p:submenu label="#{translations['language']}" icon="fa fa-language">
                <p:menuitem value="German" action="#{language.setLocale(de)}"/>
                <p:menuitem value="English" action="#{language.setLocale(en)}"/>
            </p:submenu>
        </p:menubar>
    </h:form>
</h:body>

资源包的faces-config.xml 条目:

<resource-bundle>
    <base-name>example.i18n.resourcebundle.DBResourceBundle</base-name>
    <var>translations</var>
</resource-bundle>

Translation-Bean-Function:

public String test() {
    FacesContext fCtx = FacesContext.getCurrentInstance();
    UIComponent currentComponent = UIComponent.getCurrentComponent(fCtx);
    if (null != currentComponent) {
        Location location = (Location) currentComponent.getAttributes().get(UIComponent.VIEW_LOCATION_KEY);
        if (null != location) {
            System.out.println(location);
            System.out.println(location.getPath());
            return location.getPath();
        }
    }
    return null;
}

现在我想将label="#{translations['language']}" 的所有请求保存在地图中。该映射应以“language”作为键,以请求的 XHTML(例如“login.xhtml”)作为值。 Translations 包含我需要的大部分翻译,如果它不在里面,我也想要一个条目。

在这种情况下,如果请求调用test() 函数就足够了。

【问题讨论】:

  • 仅通过从视图中检索ui:include 并查找其值
  • 2 个问题:1) 有这样的功能吗? 2)我有多个包含,我如何区分哪个是正确的?
  • 1) 是的,google 用于在 jsf 视图中查找组件。 2) 是的,通过 id
  • 我稍微改进了我的问题,我认为这不是我想要的

标签: jsf view request


【解决方案1】:

在评估 #{translations['titel']} 时,您想知道该表达式在 XHTML 文件中的物理位置。

经过一番挖掘,我发现了如何获取当前渲染标签的位置:

相关API见

javax.faces.view.Location
UIComponent.VIEW_LOCATION_KEY
javax.faces.component.UIComponent.getCurrentComponent(FacesContext)

您可以使用这段代码来获取 XHTML 文件名:

public String getCurrentComponentPath() {
        FacesContext fCtx = FacesContext.getCurrentInstance();
        UIComponent currentComponent = UIComponent.getCurrentComponent(fCtx);
        if (null != currentComponent) {
            Location location = (Location) currentComponent.getAttributes().get(UIComponent.VIEW_LOCATION_KEY);
            if (null != location) {
                return location.getPath();
            }
        }
        return null;
    }

使用 JSF 2.3 (Mojarra) 对此进行了测试。

注意:如果您的 EL 表达式不在当前模板中的组件中,您将无法获得当前 XHTML 文件名,因为 UIComponent.getCurrentComponent 从 parent 模板 XHTML 包含当前 XHTML。

例如这不会按预期工作:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

<ui:composition>

    #{translations['titel']}

</ui:composition>
</html>

虽然这样做:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

<ui:composition>

    <h:outputText value="#{translations['titel']}"/>

</ui:composition>
</html>

【讨论】:

  • 抱歉让您休息了这么久!我如何使用这个功能?如果我用 调用它,它不会执行,如果我通过 调用它,我会得到空值。我有点困惑如何在您的示例中跟踪该输出文本。
  • 您可以将您在问题中编写的源代码替换为System.out.println(getCurrentComponentPath());
  • 是的,我这样做了,但我得到 null 作为响应。我认为发生这种情况是因为我不能在没有 remoteButton 的情况下使用 commandButton(它在复合材料中)。你能解释一下,我如何跟踪翻译的 outputText 调用['title']?也许我可以这样测试。谢谢!
  • 我添加了更详细的代码(EDIT2)希望这会有所帮助 - 谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-23
  • 1970-01-01
  • 2014-06-28
  • 1970-01-01
  • 2014-06-24
  • 2013-06-04
相关资源
最近更新 更多