1. ホーム
  2. jsf

どのようにJSFのコンテキストパスを介してベースURLを取得するには?

2023-10-23 08:24:25

質問

このような構造になっています。

WebContent
    resources
        components
            top.xhtml

    company
        about_us.xhtml

    index.xhtml

top.xhtml はコンポーネントで index.xthmlabout_us.xhtml もあります。

top.xhtml

<ul>
    <li><a href="index.xhtml">Home</a></li>
    <li><a href="company/about_us.xhtml">About us</a></li>
    ...
</ul>

そこで問題なのは、現在のページが index.xhtml の場合、コンポーネントは正しく URL を生成しますが、現在のページが about_us.xhtml の場合は、間違った URL を生成してしまいます。相対パスも間違ったURLを生成してしまいそうで使えません。私は、このコンポーネントが、現在のパスの *.xhtml ページの現在のパスに基づいているからだと思います。

私が見つけられた唯一の解決策は

<ul>
    <li><a href="${pageContext.request.contextPath}/webname/index.xhtml">Home</a></li>
    <li><a href="${pageContext.request.contextPath}/webname/about_us.xhtml">About us</a></li>
    ...
</ul>

しかし、私はそれが全く "エレガント "ではないと思います。何かアイデアはありますか?

どのように解決するのですか?

URL は、サーバー側でファイル構造に基づいて解決されません。URL は、問題のあるリソースの実際のパブリック Web アドレスに基づいて解決されます。つまり、Web サーバーではなく、Web ブラウザーがそれらを呼び出す必要があるのです。

痛みを和らげる方法がいくつかあります。

JSF ELは ${pageContext.request} の風味で #{request} :

<li><a href="#{request.contextPath}/index.xhtml">Home</a></li>
<li><a href="#{request.contextPath}/about_us.xhtml">About us</a></li>

必要であれば <c:set> タグを使えば、もっと短くできます。これをマスターテンプレートのどこかに設置すると、すべてのページで利用できるようになります。

<c:set var="root" value="#{request.contextPath}/" />
...
<li><a href="#{root}index.xhtml">Home</a></li>
<li><a href="#{root}about_us.xhtml">About us</a></li>

JSF 2.xでは <h:link> で、コンテキストルートからの相対的なビュー ID を取ることができます。 outcome で、これはコンテキストのパスを追加し FacesServlet のマッピングが自動的に追加されます。

<li><h:link value="Home" outcome="index" /></li>
<li><h:link value="About us" outcome="about_us" /></li>

HTMLでは <base> タグがあり、ドキュメント内のすべての相対 URL をこのベースからの相対 URL にします。これを利用するとよいでしょう。これを <h:head> .

<base href="#{request.requestURL.substring(0, request.requestURL.length() - request.requestURI.length())}#{request.contextPath}/" />
...
<li><a href="index.xhtml">Home</a></li>
<li><a href="about_us.xhtml">About us</a></li>

(注意:これはEL2.2を必要とします。そうでない場合はJSTLを使用した方がよいでしょう。 fn:substring() も参照してください。 この答え )

これは、生成されたHTMLの中で次のようなものになるはずです。

<base href="http://example.com/webname/" />

なお <base> タグには注意点があります。それは、ページ内のすべてのジャンプ・アンカーを <a href="#top"> のようなページ内のすべてのジャンプアンカーを相対的なものとしてしまうのです! また html タグは <base> を使用することが推奨されていますか? JSFでは、次のように解決できます。 <a href="#{request.requestURI}#top">top</a> または <h:link value="top" fragment="top" /> .