Declaring custom PDF servlets collides with .xhtml extension - jsf

I'm trying to implement a custom PDF file servlet (/fileprovider/name?param1=value&param2=otherValue) on a JSF 2 web application, but when declaring it on web.xml the application always adds .xhtml extension to every request. I believe due to the DEFAULT_SUFFIX context-param.
<!-- ... -->
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
<context-param>
<param-name>org.omnifaces.FACES_VIEWS_SCAN_PATHS</param-name>
<param-value>/*.xhtml</param-value>
</context-param>
<servlet>
<servlet-name>faces</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>MyPDFServlet</servlet-name>
<servlet-class>com.company.servlet.MyPDFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyPDFServlet</servlet-name>
<url-pattern>/fileprovider/name</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>faces</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<!-- ... -->
The exception thrown is:
FacesFileNotFoundException: /name.xhtml Not Found in ExternalContext as a Resource
So I believe that the path is not mapped correctly, maybe I'm missing something.
Is there any way to specify that I want specific paths to point to custom servlets without adding .xhtml extension?

Related

Facelets error page works during ajax request with FullAjaxExceptionHandler, but does not evaluate EL during synchronous request

I am trying to configure a normal (non-ajax) request error page using Omnifaces library. I am able to use the FullAjaxExceptionHandler and with ajax request error and its page as shown in the demo. When I use the same error page with normal request the error page is shown, but the values are displayed as source code (for example Date/time: #{of:formatDate(now, 'yyyy-MM-dd HH:mm:ss')} User agent: #{header['user-agent']} .. are displayed in the browser as it is).
I am using Tomcat 7, JSF 2.2 (MyFaces), Weld 2.6 (for CDI), Omnifaces 2.0 and Primefaces 5.1. The following is the relevant code.
The page:
<h:commandButton value="Throw runtime exception on normal request"
action="#{appbean.throwRuntimeException}"/>
<p:commandButton value="Throw runtime exception on AJAX request"
action="#{appbean.throwRuntimeException}"/>
The bean:
public void throwRuntimeException() {
throw new RuntimeException("peek-a-boo");
}
faces-config:
<factory>
<exception-handler-factory>
org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory
</exception-handler-factory>
</factory>
web.xml:
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<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>
<error-page>
<exception-type>java.lang.RuntimeException</exception-type>
<location>/WEB-INF/errorpages/error2.xhtml</location>
</error-page>
The <error-page><location> must match the FacesServlet mapping in order to get FacesServlet to run on the error page too during an exception on a synchronous request (which doesn't use ViewHandler#renderView(), but RequestDispatcher#forward()).
Alter the mapping accordingly:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
Using /faces/* (and *.faces) is soo JSF 1.0/1.1. If you really need to keep /faces/* for some reason (e.g. existing webapp with already published URLs), then just use both (and migrate with 301s accordingly):
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
See also:
JSF returns blank/unparsed page with plain/raw XHTML/XML/EL source instead of rendered HTML output

Direct two diferrent URL to the same page in JSF

I am developing a jsf2 + spring3 application with the following filesystem:
webapp
-resources (folder)
-WEB-INF (folder)
--applicationContext.xml
--faces-config.xml
--web.xml
-buy.xhtml
-company.xhtml
-home.xhtml
-sell.xhtml
And I got this in my web.xml:
<welcome-file-list>
<welcome-file>home.jsf</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>facesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
My faces-config.xml got nothing about navigation.
When I go to the following URL "http://:8080/website/" I got the "home.jsf" view.
I need to go to the same "home.jsf" view "http://:8080/website/home.jsf" when I write the following URL "http://:8080/website/caminha/"
How can I achieve this? What I need to change in web.xml or in faces-config.xml? Thanks!

Why FacesServlet cannot have a url-pattern of /*.?

This is my web.xml :
<servlet-mapping>
<servlet-name>Faces Servlet</servlet>
<url-pattern>/*</url-pattern>
</servlet-mapping>
When I navigate to:
http://localhost:8080/LearningRoot/index.xhtml
I can see the page just fine, however when I navigate to:
http://localhost:8080/LearningRoot/
I get the error:
An Error Occurred:
The FacesServlet cannot have a url-pattern of /*. Please define a different url-pattern.
But why?
And this is my welcome file:
<welcome-file-list>
<welcome-file>/index.xhtml</welcome-file>
</welcome-file-list>
Because that would mean Everything that ever hits that context-root will be handled by FacesServlet, a requirement that FacesServlet already knows it couldn't possibly fulfill (It obviously doesn't make sense).
To achieve the mapping you intend, use a .xhtml mapping on FaceServlet
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

RichFaces GUI displayed as text

I am running a simple RichFaces example. Mainly using Tabs. The example is shown on
JBoss website found at:
http://richfaces-showcase.appspot.com/richfaces/component-sample.jsf?demo=tabPanel&skin=blueSky
Running the code results in the following page:
Overview
«
↓
»
RichFaces is a component library for JSF and an advanced framework for easily integrating
AJAX capabilities into business applications.
100+ AJAX enabled components in two libraries
...
Notice the overview should be a clickable tab. Instead I get
Overview
«
↓
»
There is no error messages from the GlassFish server. I am using Netbeans with Facelets, RichFaces 4.0 and JSF 2.0.
My web.xml is
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.SKIN</param-name>
<param-value>blueSky</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.CONTROL_SKINNING</param-name>
<param-value>enable</param-value>
</context-param>
<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>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/richexample.xhtml</welcome-file>
</welcome-file-list>
</web-app>
Library:
richfaces-components-api-4.0.0.Final.jar
richfaces-components-ui-4.0.0.Final.jar
richfaces-core-api-4.0.0.Final.jar
richfaces-core-impl-4.0.0.Final.jar
sac-1.3.jar
guava-10.0.1.jar
cssparser-0.9.5.jar
GlassFish 3.x (libraries)
Appreciate any hint or feedback as I do not have a clue why graphics are not displayed.
What URL did you use to access your page? In your web.xml you mapped Faces Servlet to the /faces prefix, so your URL must include this (even though your actual page is not really on that path).
You can add additional mappings in your web.xml, like the common *.jsf or *.xhtml or replace the existing one, e.g.
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

Richfaces tree is giving me an "Uncaught ReferenceError tree is not defined"

I believe my problem is in a settings file somewhere, but I have no idea what file/setting that would be. I have a standalone project with a working tree, but when I try to integrate it with my real project I start getting the mentioned error. That's what makes me think I have a setting somewhere that's off.
I'm using JSF1.2 and richfaces 3.3.3. Here's my JSP file.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%-- jsf:pagecode language="java" location="/src/java/pagecode/agencyMappingPages/mapping/Mapping.java" --%><%-- /jsf:pagecode --%>
<%#page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%#taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%#taglib prefix="rich" uri="http://richfaces.org/rich"%>
<html>
<f:view>
<body>
<rich:tree switchType="client" value="#{mappingBean.nodes}" var="node">
</rich:tree>
</body>
</f:view>
</html>
Here's my bean code:
public TreeNode<String> getNodes() {
TreeNodeImpl<String> nodes = new TreeNodeImpl<String>();
TreeNodeImpl<String> root = new TreeNodeImpl<String>();
root.setData("Test Tree Root");
nodes.addChild(0, root);
return nodes;
}
I'm using the following jars. These are also the three jars I'm using in the functioning version of my tree.
richfaces-api-3.3.3.Final.Jar
richfaces-impl-3.3.3.Final.Jar
richfaces-ui-3.3.3.Final.Jar
I've got the following in my web.xml file.
<filter>
<display-name>RichFaces Filter</display-name>
<filter-name>richfaces</filter-name>
<filter-class>org.ajax4jsf.Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>richfaces</filter-name>
<servlet-name>Faces Servlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>-1</load-on-startup>
</servlet>
<servlet>
<servlet-name>JavaScript Resource Servlet</servlet-name>
<servlet-class>com.ibm.faces.webapp.JSResourceServlet</servlet-class>
<load-on-startup>-1</load-on-startup>
</servlet>
<servlet>
<servlet-name>Tiles2Servet</servlet-name>
<servlet-class>org.apache.tiles.web.startup.TilesServlet</servlet-class>
<init-param>
<param-name>org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG</param-name>
<param-value>/WEB-INF/tiles20-defs.xml</param-value>
</init-param>
<load-on-startup>2</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>/faces/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>JavaScript Resource Servlet</servlet-name>
<url-pattern>/.ibmjsfres/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
Not sure if this'll be helpful, but here's the javascript it chokes on. I had to omit quite a bit because the form wouldn't submit. I copied this from Chrome's developers window. It throws the exception at the second line: var tree = new tree......
<script type="text/javascript">(function() {
var tree = new Tree("j_id_jsp_1558828084_1", "j_id_jsp_1558828084_1:input", "client",
{
onselect: "",
onexpand: "",
oncollapse: "",
oncontextmenu: ""
},
function(event) {var params = {'j_id_jsp_1558828084_1:selectedNode':event.selectedNode} ;
if (!params.ajaxSingle && event.ajaxSingle) {
params.ajaxSingle = event.ajaxSingle;
}
So, what necessary file/setting am I missing?
I'm sure I'm forgetting the most important piece of info which is why I need you.
Thanks,
Dale
So I figured out what the problem was. For some reason Richfaces was not sending the script or styling files to the browser. It dynamically puts the links in the head.
So I add the following filters to the web.xml file and everything is happy now including me and my partner.
<context-param>
<param-name>org.richfaces.LoadStyleStrategy</param-name>
<param-value>ALL</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.LoadScriptStrategy</param-name>
<param-value>ALL</param-value>
</context-param>
Hopefully this helps someone else.

Resources