Run JSF project on Apache Tomcat - java

How can lunch JSP project on Tomcat? I copy WebContent folder to webapp folder of Apache but it can't find my jsp page, but if I change jsp to jsf (index.jsf) works fine. How can I solve this problem?
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>Graph</display-name>
<welcome-file-list>
<welcome-file>index.jsp</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>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<description>
This parameter tells MyFaces if javascript code should be allowed in
the rendered HTML output.
If javascript is allowed, command_link anchors will have javascript code
that submits the corresponding form.
If javascript is not allowed, the state saving info and nested parameters
will be added as url parameters.
Default is 'true'</description>
<param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<description>
If true, rendered HTML code will be formatted, so that it is 'human-readable'
i.e. additional line separators and whitespace will be written, that do not
influence the HTML code.
Default is 'true'</description>
<param-name>org.apache.myfaces.PRETTY_HTML</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.DETECT_JAVASCRIPT</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<description>
If true, a javascript function will be rendered that is able to restore the
former vertical scroll on every request. Convenient feature if you have pages
with long lists and you do not want the browser page to always jump to the top
if you trigger a link or button action that stays on the same page.
Default is 'false'
</description>
<param-name>org.apache.myfaces.AUTO_SCROLL</param-name>
<param-value>true</param-value>
</context-param>
<servlet>
<servlet-name>faces</servlet-name>
<servlet-class>org.apache.myfaces.webapp.MyFacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>UploadServlet</servlet-name>
<servlet-class>controler.UploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>faces</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>faces</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>UploadServlet</servlet-name>
<url-pattern>/Upload</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
</listener>
</web-app>
Error:
type Status report
message /Graph/index.jsp
description The requested resource
(/Graph/index.jsp) is not available.

That's not a problem. That's expected behaviour. You're just misunderstanding how the basic Servlet API works. You have configured the JSF-standard FacesServlet to listen on URLs matching /faces/* and you have configured Apache MyFaces specific MyFacesServlet to listen on URls matching *.jsf and *.faces.
To get JSF to run, you have to open the page in browser by an URL which matches the mapping of the FacesServlet. Given the fact that you've an index.jsp file and that your context path is Graph and that you have configured two JSF servlets on three different URL patterns, you can open the JSP by the following URLs:
http://localhost:8080/Graph/faces/index.jsp (invokes FacesServlet)
http://localhost:8080/Graph/index.jsf (invokes MyFacesServlet)
http://localhost:8080/Graph/index.faces (invokes MyFacesServlet)
Said that, your configuration is unnecessarily overcomplicated. Get rid of the MyFacesServlet entry and all of its associated URL mappings (with the servlet name of faces). Just stick to the standard FacesServlet and use its mapping instead, or alter it instead. I personally recommend using *.jsf.
<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>
Then you can just open the page by http://localhost:8080/Graph/index.jsf.
Unrelated to the concrete problem, your welcome-file won't work that way. Tomcat would give a HTTP 404 error on that (page/resource not found). You need to specify index.jsf as welcome-file and supply a concrete but empty index.jsf file in the same folder as your index.jsp. This way Tomcat will be fooled that the file exist and show the page by just calling http://localhost:8080/Graph.
If your concern is that it is possible to open JSF pages by their *.jsp extension which would result in a RuntimeException: FacesContext not found and you have actually no one JSP file which is to be served plain vanilla, then you can restrict direct access to JSP files by the following security constraint in web.xml:
<security-constraint>
<display-name>Restrict direct access to JSP files</display-name>
<web-resource-collection>
<web-resource-name>JSP files</web-resource-name>
<url-pattern>*.jsp</url-pattern>
</web-resource-collection>
<auth-constraint />
</security-constraint>
(in JSF 2.0 this is by the way not needed anymore, with the default view technology Facelets it's possible to map the FacesServlet on just *.xhtml, which is the same as the default extension of Facelets files)

you can deploy your application with the tomcat manager
http://tomcatIP:8080/manager/html
there you can upload your application and it should run out of the box
if you have no idea what username and password you should type in, you have to configure your tomcat-users.xml

Related

JSP compilation in servlet mapping during runtime [duplicate]

Is a JSP page detected by the page extension of .jsp only? Is there any other way it can be detected?
JSP pages in Tomcat are handled by a specific servlet that is meant to handle all requests that terminate with .jsp or .jspx in the HTTP request. This configuration exists in the global $CATALINA\conf\web.xml file where one can find the following significant lines. Note that is for Tomcat 6.
JSP Servlet registration
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
JSP Servlet URL mapping
<!-- The mapping for the JSP servlet -->
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
You could possibly add more URL mappings for other file extensions that are not already mapped to other servlets, in order to trigger the Jasper compiler, that is eventually responsible for translation of the JSP files into corresponding Java servlets, which are then compiled (using the Eclipse JDT compiler, by default). More information on configuring some of the options in the process can be obtained from the Tomcat documentation on configuring Jasper.
Here's a brief introduction from Built In Servlet Definitions section in $TOMCAT_HOME/conf/web.xml
The JSP page compiler and execution servlet, which is the mechanism
used by Tomcat to support JSP pages. Traditionally, this servlet
is mapped to the URL pattern "*.jsp".
And JSP page detection is done via servlet mapping (Built In Servlet Mappings section in $TOMCAT_HOME/conf/web.xml):
<!-- The mapping for the JSP servlet -->
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>

Servlet not loading on startup

TL;DR: <load-on-startup> does not seem to be causing my Jersey web services to load on startup
I’m trying to set up a simple RESTful web service that will act as a registry for the other RESTful services in the container.
To do this I had planned on registering each other web service with the registry service in a static initialize block. Everything was going well until I remembered that servlets aren’t loaded until their first access.
A quick web search turned up the <load-on-startup> tag that can be added to the servlet definition in web.xml. Unfortunately, this was already set in my configuration and adding some logging to the static blocks verified that the classes were indeed not being loaded until the first access of each service.
I’m developing these servlets using Jersey annotations and deploying them to Apache Tomcat (both 7.0.22 embedded in netbeans and 6.0.33 deployed remotely fail in the same way).
Besides this perceived misbehavior, the servlets have been performing correctly.
Any ideas on what I could be doing wrong?
My web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<filter>
<filter-name>CORSFilter</filter-name>
<filter-class>com.foo.bar.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CORSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet>
<servlet-name>ServletAdaptor</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<description>Multiple packages, separated by semicolon(;), can be specified in param-value</description>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.foo.bar.webservices</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ServletAdaptor</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
</web-app>
It was a couple years ago and a couple years of Java Web Stack knowledge later.
I believe this was a case of mistaken identity. I had a non container managed resource that I was trying to get to load on startup. The jersey servlet container was most assuredly loading on start up as the web.xml was specifying. The classes that I wanted to preload were not being referenced by the container itself so were not being loaded with the container.

How to serve static resources from a Vaadin/Spring application?

I have Vaadin web application with spring security integration for authentication. The configuration of the Vaadin servlet is pretty simple:
<servlet>
<servlet-name>Vaadin Application Servlet</servlet-name>
<servlet-class>com.example.SpringApplicationServlet</servlet-class>
<init-param>
<param-name>applicationBean</param-name>
<param-value>mainApplication</param-value>
</init-param>
<init-param>
<param-name>widgetset</param-name>
<param-value>com.example.widgetset.CustomWidgetSet</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Vaadin Application Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
The servlet initializes the Spring Context and returns the Vaadin application. I have also configured the security for that and have a custom login form configured like this:
<servlet>
<servlet-name>login</servlet-name>
<jsp-file>/jsp/login.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>login_error</servlet-name>
<jsp-file>/jsp/loginError.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>login_error</servlet-name>
<url-pattern>/login_error</url-pattern>
</servlet-mapping>
The login form is styled with an external css and there are also some images. Basically the images are located in /jsp/img and the stylesheet in /jsp/login.css. So the WAR structure looks like:
/jsp
/META-INF
/VAADIN
/WEB-INF
Neither the images nor the css gets loaded, because obviously all those requests are mapped to the vaadin servlet. How can I define some static resources directory, which wouldn't be served by the Vaadin servlet? I have tried the spring mvc:resources but that didn't work. Thank you for your help.
Bye,
Filip
I have figured this out. Although it is rather a workaround. I have mapped the Vaadin Application Servlet to something like /app/* instead of to /* (Remember that in this case you also have to map the same servlet to /VAADIN/*). With this configuration I am able to access the jsp directory from my webapp and everything works fine. I have deleted the whole Spring Resources configuration, as this just didn't work.
So once more, I am still pretty not pretty comfortable with this solution and would rather have my RESOURCES dir configured other way, but the client is happy :). If anyone has got the right solution I would appreciate to read it.
Use a url rewrite filter to get more contro on url mapping.
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
then map Vaadin application to /vaadin for example and configure url maping in urlrewrite.xml
<rule>
<from>/styles/**</from>
<to last="true">/styles/$1</to>
</rule>
<rule>
<from>/images/**</from>
<to last="true">/images/$1</to>
</rule>
<rule>
<from>/**</from>
<to>/vaadin/$1</to>
</rule>
<outbound-rule>
<from>/vaadin/**</from>
<to>/$1</to>
</outbound-rule>
EDIT
Other option is put static files in /VAADIN/ directory.
I have figured this out. Although it is rather a workaround. I have mapped the Vaadin Application Servlet to something like /app/* instead of to /* (Remember that in this case you also have to map the same servlet to /VAADIN/*). With this configuration I am able to access the jsp directory from my webapp and everything works fine. I have deleted the whole Spring Resources configuration, as this just didn't work.
So once more, I am still pretty not pretty comfortable with this solution and would rather have my RESOURCES dir configured other way, but the c
Might be late but for who is still having problems with serving static content while using vaadin /* mapping, the solution I found was using apache's default servlet org.apache.catalina.servlets.DefaultServlet, so a web.xml will have something like:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<servlet-name>myservlet</servlet-name>
<servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
<init-param>
<param-name>UI</param-name>
<param-value>com.ex.myprj.MyUI</param-value>
</init-param>
<!-- If not using the default widget set-->
<init-param>
<param-name>widgetset</param-name>
<param-value>com.ex.myprj.AppWidgetSet</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>myservlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Static content Servlet</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Static content Servlet</servlet-name>
<url-pattern>/customer/*</url-pattern>
</servlet-mapping>
</web-app>
So in the example above, despite having vaadin at /*, the /customer/* part will be served as static content by the DefaultServlet

Servlet Mapping: Only when a file or directory doesn't exist?

I'm setting up a web app on GlassFish and I'm wondering if there is a way to configure servlet mapping from the URL root to only apply in cases where a file or directory doesn't exist at the specified URL.
Currently, this will route everything through my Spring dispatcher:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>
/jsp/index.jsp
</welcome-file>
</welcome-file-list>
</web-app>
Is it somehow possible to preserve the above behavior unless a file or directory exists at a given path? Am I trying to solve this problem in the wrong place?
UPDATE: What about URL rewriting? Does GlassFish provide any degree of flexibility like Apache does with mod_rewrite? That way I could intercept things before it even reaches the servlet mapping stage.
Hacky, but doable: map it as <error-page> on an <error-code> of 404.
<servlet>
<servlet-name>errorServlet</servlet-name>
<servlet-class>com.example.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>errorServlet</servlet-name>
<url-pattern>/error</url-pattern>
</servlet-mapping>
<error-page>
<error-code>404</error-code>
<location>/error</location>
</error-page>
You might want to change the status code in the servlet whenever you want to return a "valid" response.
An alternative is to let the Spring servlet listen on a more specific url-pattern. E.g. /pages/*. You could then if necessary bring a Filter in front (on /*) which does roughly the following:
if (new File(servletContext.getRealPath(request.getRequestURI())).exists()) {
chain.doFilter(request, response);
} else {
request.getRequestDispatcher("/pages" + request.getRequestURI()).forward(request, response);
}
so that you don't see/need /pages in the URL.
Update: as per your new question:
UPDATE: What about URL rewriting? Does GlassFish provide any degree of flexibility like Apache does with mod_rewrite? That way I could intercept things before it even reaches the servlet mapping stage.
The JSP/Servlet equivalent of Apache HTTPD's mod_rewrite addon is the Tuckey's UrlRewriteFilter.

Explicit directory for JSF template files

I'm just getting into Seam/JSF development and looking for a way to lookup the XHTML template files from a different location.
When configuring the JSF application like this:
<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>*.seam</url-pattern>
</servlet-mapping>
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
when I enter a URL like:
http://localhost/test.seam
The system loads the XHTML file at
<webapp>/test.xhtml
What I'd like to configure is a prefix directory, so that the file is being looked up from
<webapp>/WEB-INF/views/test.xhtml
So, is there any way to achive something like this:
<context-param>
<param-name>javax.faces.DEFAULT_PREFIX</param-name>
<param-value>/WEB-INF/views/</param-value>
</context-param>
Thanks for your help!
There isn't a way. I wish there was a way because preventing them from direct access by hiding them in /WEB-INF would have been very useful. I bet that this is also your actual functional requirement. You can achieve this by (ab)using declarative container managed security. Add a security-constraint on an url-pattern of *.xhtml with an empty auth-constraint to web.xml like follows:
<security-constraint>
<display-name>Restrict direct access to XHTML files</display-name>
<web-resource-collection>
<web-resource-name>XHTML files</web-resource-name>
<url-pattern>*.xhtml</url-pattern>
</web-resource-collection>
<auth-constraint />
</security-constraint>

Categories