Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How get the base URL via context path in JSF?

I have this structure:

WebContent     resources         components             top.xhtml      company         about_us.xhtml      index.xhtml 

top.xhtml is a component, that is used in index.xthml and about_us.xhtml too.

top.xhtml

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

So my problem is, when the current page is index.xhtml the component generates URLs correctly, but when the current page is about_us.xhtml, it generates wrong URLs. I cannot use relative path because it's going to generate the wrong URL too. I think it is because the component is based on the current path of the *.xhtml page.

The only solution I could found out is:

<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> 

But I think is not 'elegant' at all. Any ideas?

like image 932
Valter Silva Avatar asked Jul 29 '11 19:07

Valter Silva


People also ask

What is context path in URL?

The context path is the path to Confluence relative to the root directory of the webserver. For example, the context path for this site is an empty string, because it is deployed at the root. The context path for a Confluence instance deployed at http://www.example.com/confluence would be /confluence .

What is request context path?

String getContextPath() Returns the context path of the web application. The context path is the portion of the request URI that is used to select the context of the request. The context path always comes first in a request URI.


1 Answers

URLs are not resolved based on the file structure in the server side. URLs are resolved based on the real public web addresses of the resources in question. It's namely the webbrowser who has got to invoke them, not the webserver.

There are several ways to soften the pain:

JSF EL offers a shorthand to ${pageContext.request} in flavor of #{request}:

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

You can if necessary use <c:set> tag to make it yet shorter. Put it somewhere in the master template, it'll be available to all pages:

<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 offers the <h:link> which can take a view ID relative to the context root in outcome and it will append the context path and FacesServlet mapping automatically:

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

HTML offers the <base> tag which makes all relative URLs in the document relative to this base. You could make use of it. Put it in the <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> 

(note: this requires EL 2.2, otherwise you'd better use JSTL fn:substring(), see also this answer)

This should end up in the generated HTML something like as

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

Note that the <base> tag has a caveat: it makes all jump anchors in the page like <a href="#top"> relative to it as well! See also Is it recommended to use the <base> html tag? In JSF you could solve it like <a href="#{request.requestURI}#top">top</a> or <h:link value="top" fragment="top" />.

like image 194
BalusC Avatar answered Sep 18 '22 20:09

BalusC