Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does <h:link> change destination extension from .html to .xhtml?

I'm using JSF 2.1 and I'm experiencing some problems with the <h:link> tag. I'm trying to have the link's outcome point from my XHTML file to a plain HTML file. However, when I run my web application, the .html extension in link's generated URL is automatically converted to a .xhtml extension.

Here is my Facelet file:

<h:body>
    <h:form>        
        <h:link value="animation" outcome="#{contentForm.ccAnimationLink}"/>            
    </h:form>
<h:body>

Here is my contentForm bean:

package my.app.content;

import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class ContentForm implements Serializable {
    private static final long serialVersionUID = -8463354828156798513L; 
    private String ccAnimationLink = "";    

    @PostConstruct
    public void init() {        
        ccAnimationLink = "/content/cc/CC_animation/story.html";        
    }

    public String getCcAnimationLink() {
        return ccAnimationLink;
    }

    public void setCcAnimationLink(String ccAnimationLink) {
        this.ccAnimationLink = ccAnimationLink;
    }
}

Now, when I run this application, I get the following error:

Unable to find matching navigation case from view ID '/content/modifiedcc.xhtml' for outcome '/content/cc/CC_animation/story.html'

I made sure that I had the URL correct, so I created a story.xhtml file in that location as well. With that file there it runs without errors.

If I pull the source for the generated page, I can see that the <h:link> was correctly changed to an "a href" tag, as follows:

<a href="/MyWebApp/content/cc/CC_animation/story.xhtml">animation</a>

For some reason though the URL changes from story.html, like I have it in my bean, to story.xhtml.

How can I make sure that it stays as story.html and not change it to xhtml?

Here is my web.xml file as well:

  <display-name>MyWebApp</display-name>
  <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
  </context-param>
  <welcome-file-list>
    <welcome-file>jsf/login/login.xhtml</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.faces</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
  </servlet-mapping>
</web-app>

I tried adding the following to the web.xml, this didn't make a difference:

  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>

I'm sure this has a very simple solution which I'm just missing right now. Help would be highly appreciated. I hope the question is clear.

like image 669
Frost Avatar asked Dec 01 '13 08:12

Frost


1 Answers

JSF 2.0+ has introduced <h:link> component that takes a navigation case outcome in its outcome attribute and autogenerates the right URL on its own. This is why you had the error without adding yet another mapping for the faces servlet: just reread the error. It is useful for creation of inter-JSF application navigation.

Alternatively, there has always been a <h:outputLink> component that takes an URL in its value attribute instead. It is useful for creation of navigation external to a JSF application.

Be sure to read the classics from BalusC on the issue: When should I use h:outputLink instead of h:commandLink?.

That said, consider the following components:

<h:link outcome="/destination" value="link" />
<h:outputLink value="/destination.html">
    outputLink
</h:outputLink>

The former component will translate its outcome into an actual URL, by appending a faces servlet mapping, while the latter one will leave its value as-is.

So, your problem will be solved by using the following component:

<h:outputLink value="#{contentForm.ccAnimationLink}">
    Animation
</h:outputLink>
like image 159
skuntsel Avatar answered Sep 22 '22 13:09

skuntsel