Servlet mapping jsf - jsf

I'm asking myself which way is the best for servlet mapping in jsf? And Why?
Especially I'm wondering always about the different suffix of the facelet resources and the suffix of the url-pattern of the servlet-mapping. My servlet mapping is always coherent to the suffix of my resources.
For Example if I'm using xhtml as facelets my servlet mapping does it also:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
But I see examples where the resources are xhtml files and the servlet mapping is on jsf?
For Example:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
So which way is the best way?
And also I'm wondering why the second way working at all?

For now you won't need an answer on which servlet mapping to use, I think. You would probably be better of with some reading first.
I have taken the liberty to find two related questions which might open your eyes a little considering JSF and the file extension.
What is the difference between creating JSF pages with .jsp or .xhtml or .jsf extension
JSF Facelets: Sometimes I see the URL is .jsf and sometimes .xhtml. Why?

Related

Why use *.jsf as servlet-mapping url pattern in web.xml [duplicate]

Been try to learn JSF, and sometimes I see the URL is *.jsf and sometimes is *.xhtml or /faces/*. Can someone fill my knowledge, please? When I create a JSF using Facelet, the file extension is .xhtml, so where does .jsf URL extension come from?
The .jsf extension is where the FacesServlet is during the JSF 1.2 period often mapped on in the web.xml.
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
The .xhtml extension is of the actual Facelets file as you've physically placed in the webcontent of your webapp, e.g. Webapp/WebContent/page.xhtml.
If you invoke this page with the .jsf extension, e.g. http://localhost:8080/webapp/page.jsf then the FacesServlet will be invoked, locate the page.xhtml file and parse/render its JSF components. If the FacesServlet isn't invoked, then the enduser would end up getting the raw XHTML source code (which can be seen by rightclick, View Source).
Sometimes a *.faces extension or /faces/* foldermapping is been used. But this was from back in the JSF 1.0/1.1 ages. You're free to choose and use whatever mapping you'd like to let FacesServlet listen on, even if it's a nothing-saying *.xyz. The actual page itself should always have the .xhtml extension, but this is configureable by the following <context-param> in web.xml:
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xml</param-value>
</context-param>
This will change the FacesServlet to locate page.xml instad of (default) page.xhtml.
More recently, with JSF/Facelets 2.0 a *.xhtml mapping is been used. In JSF/Facelets 1.x it was not possible to use the same mapping extension as the physical file. It would result in an infinite loop. But since JSF/Facelets 2.0 it is possible and this allows you to call the page by http://localhost:8080/webapp/page.xhtml.
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
This way you don't need to configure some security restrictions to hide the raw source files away for cases whenever the enduser changes for example .jsf in URL to .xhtml in browser address bar. Only tooling (IDEs and plugins) and learning resources still need to catch up the advocated move from *.jsf to *.xhtml. As per JSF 2.3, the FacesServlet will by default be autoregistered on *.xhtml too (next to /faces/*, *.faces and *.jsf). This is backported to Mojarra 2.2.11.
See also:
Can we use regular expressions in web.xml URL patterns?
Set default home page via <welcome-file> in JSF project
JSF returns blank/unparsed page with plain/raw XHTML/XML/EL source instead of rendered HTML output
What is the difference between creating JSF pages with .jsp or .xhtml or .jsf extension
Which XHTML files do I need to put in /WEB-INF and which not?
Customize FacesServlet <url-pattern> to get rid of .xhtml extension

<t:inputFileUpload> not working anymore after migration JSF 1.2 to JSF 2.2

I am upgrading my application from JSF 1.2 to JSF 2.2 and using Tomahawk 1.1.14 version.
After upgrading, <t:inputFileUpload> tag has stopped working and value of the component is not bound to backingbean property any more.
web.xml
<context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>/WEB-INF/facelets/tags/tomahawk.taglib.xml</param-value>
</context-param>
However, I saw on myfaces site that the above parameter is deprecated. Is there any other way to include tag libraries or is it not even required with JSF 2.2?
<filter>
<filter-name>MyFacesExtensionsFilter</filter-name>
<filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
<init-param>
<param-name>uploadMaxFileSize</param-name>
<param-value>50m</param-value>
</init-param>
<init-param>
<param-name>uploadThresholdSize</param-name>
<param-value>1024k</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MyFacesExtensionsFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>MyFacesExtensionsFilter</filter-name>
<url-pattern>/faces/myFacesExtensionResource/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>MyFacesExtensionsFilter</filter-name>
<url-pattern>*.faces</url-pattern>
</filter-mapping>
Before this filter, I do have another filter in my web.xml and it is
<filter>
<filter-name>AjaxAnywhere</filter-name>
<filter-class>org.ajaxanywhere.AAFilter</filter-class>
<init-param>
<param-name>preSendHandlerClass</param-name>
<param-value>org.ajaxanywhere.jsf.MyFacesClientStateSavingPreSendHandler</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>AjaxAnywhere</filter-name>
<url-pattern>*.faces</url-pattern>
</filter-mapping>
Can anyone please help me if I need to do any more configuration changes for Tomahawk to work with JSF 2.2?
Thanks!
Since JSF 2.2, the FacesServlet will automatically parse multipart/form-data requests all by itself with help of new Servlet 3.0 #MultiartConfig annotation. Also, since JSF 2.2 there is (finally!) a standard file upload component, the <h:inputFile>.
The MyFaces extensions filter and Tomahawk file upload component is basically incompatible with JSF 2.2. The filter would consume and parse the request its own way and the FacesServlet would end up getting no request data at all (and therefore not be able to continue the JSF lifecycle "as usual"). Removing the filter alone would also not work as <t:inputFileUpload> is internally relying on the semantics/specifics of the MyFaces extensions filter.
Your best bet is really to just remove the filter from the web.xml altogether and replace the <t:inputFileUpload> by <h:inputFile>. It must be bound to a javax.servlet.http.Part property which offers a.o. getInputStream() which you can just continue using the same way as before with <t:inputFileUpload>.
<h:inputFile value="#{bean.uploadedFile}" />
private Part uploadedFile;
public void save() {
String name = uploadedFile.getSubmittedFileName();
String type = uploadedFile.getContentType();
long size = uploadedFile.getSize();
InputStream content = uploadedFile.getInputStream();
// ...
}
The upload maximum and threshold size configuration of the filter can be migrated to <multipart-config> entry of the <servlet> entry of the FacesServlet in web.xml like below:
<servlet>
<servlet-name>facesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<multipart-config>
<max-file-size>52428800</max-file-size>
<file-size-threshold>1048576</file-size-threshold>
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
See also:
How to upload file using JSF 2.2 <h:inputFile>? Where is the saved File?
Unrelated to the concrete problem, the facelets.LIBRARIES is Facelets 1.x specific. During the JSF 1.x era, Facelets was a standalone view technology. Since JSF 2.0, Facelets is embedded in JSF itself and all its context parameters are migrated from facelets.XXX to javax.faces.FACELETS_XXX. You can find them all in a.o Overview of all JSF-related web.xml context parameter names and values. However, you don't need to explicitly register that Tomahawk taglib as well. Just get rid of it.

FullAjaxExceptionHandler doesnt redirect to error page on omnifaces 1.7

I have a problem with the FullAjaxExceptionHandler on ajax requests using the Omnifaces.
Environment:
Tomcat 7.0.50
Mojarra 2.1.27
Omnifaces 1.7
I declared the error pages in my web.xml:
<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>*.jsf</url-pattern>
</servlet-mapping>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error/errorPage.jsf</location>
</error-page>
<filter>
<filter-name>facesExceptionFilter</filter-name>
<filter-class>org.omnifaces.filter.FacesExceptionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>facesExceptionFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
And I declared the exception handler on faces-config.xml
<factory>
<exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory</exception-handler-factory>
</factory>
With this environment the error page is shown correctly when throw an exception on a #PostConstruct method on a non-ajax request.
When I throw an exception on an ajax request, the error page is not shown, but I see this log message.
FullAjaxExceptionHandler: An exception occurred during processing JSF ajax request. Error page '/error/errorPage.jsf' will be shown.
After a while, I see another log message and the browser opens the "hardcoded error page".
FullAjaxExceptionHandler: Well, another exception occurred during rendering error page '/error/erroPage.jsf'. Trying to render a hardcoded error page now.
javax.faces.FacesException: org.apache.jasper.JasperException: /error/errorPage.jspx (line: 11, column: 39) Attribute "xmlns:h" must be declared for element type "html".
It seems that the JSP is trying to render the JSF page.
If I change the error page declaration to:
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error/errorPage.jspx</location>
</error-page>
The ajax request redirects correctly to my page, but the non-ajax request doesn't redirect anymore to the error page.
So, is this a configuration problem, environment problem or a bug on Omnifaces?
Thanks in advance.
From showcase page:
Please note that the error page must be a valid Facelets page! JSP is not supported.
From javadoc:
This exception handler will parse the web.xml and web-fragment.xml files to find the error page locations of the HTTP error code 500 and all declared specific exception types. Those locations need to point to Facelets files (JSP is not supported).
It's time to convert from JSP to Facelets. JSP is deprecated since 2009 anyway. It works with JSPX extension because it could then be parsed as if it's a Facelets file (which is also XML based).

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:
animation
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.
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>

JSF template not applied

I'm running into a problem with JSF and templating. I'm following this tutorial but the only output I see is the one I'm defining in my index.xhtml with
<ui:composition template="/WEB-INF/templates/BasicTemplate.xhtml">
<ui:define name="content">
my custom content
</ui:define>
without adding the footer and header even though I'm not defining/overwriting the default one in my index file.
If I view the source in the browser it's showing up the same way as in my index.xhtml with ui:composition etc. So it looks like it's not "converting" it to HTML.
The relevant parts of my web.xml:
<servlet>
<description>Controller Servlet for data input</description>
<display-name>InputServlet</display-name>
<servlet-name>InputServlet</servlet-name>
<servlet-class>form.controller.InputServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>InputServlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
My directory structure looks like this:
http://i.imgur.com/ZslOQNr.png
Thanks!
You're using the wrong servlet.
JSF comes with its own servlet, the FacesServlet.
Get rid of the InputServlet from web.xml altogether and map JSF's FacesServlet as follows:
<servlet>
<servlet-name>facesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
That should do it.
See also:
Our JSF wiki page - contains a Hello World and several links to sane tutorials

Resources