JSP compilation in servlet mapping during runtime [duplicate] - java

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>

Related

Servlet not opening the welcome page [duplicate]

I have a confusion regarding the structure of the web.xml for the servlet mapping, I don't have any problem by executing it but I am trying to figure it how why we have such a pattern in the deployment descriptor.
<web-app>
<servlet>
<servlet-name>Servlet1</servlet-name>
<servlet-path>foo.Servlet</servlet-path>
</servlet>
<servlet-mapping>
<servlet-name>Servlet1</servlet-name>
<url-pattern>/enroll</url-pattern>
</servlet-mapping>
</web-app>
Now as far as my understanding whenever a request is comes for url-pattern "/enroll", servlet container is going to match the servlet-name with the url-pattern and will try to find the corresponding servlet-path and will forward the control to foo.Servlet. so basically there would be two passes one for finding servlet-name and another for servlet-path, my question is if container is designed to work in the following way
<web-app>
<servlet>
<servlet-name>foo.Servlet</servlet-path>
<url-pattern>/enroll</url-pattern>
</servlet>
</web-app>
what would be the drawback if we use the following approach. Wouldn't that be more efficient and the response time would be fast.
It allows servlets to have multiple servlet mappings:
<servlet>
<servlet-name>Servlet1</servlet-name>
<servlet-path>foo.Servlet</servlet-path>
</servlet>
<servlet-mapping>
<servlet-name>Servlet1</servlet-name>
<url-pattern>/enroll</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Servlet1</servlet-name>
<url-pattern>/pay</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Servlet1</servlet-name>
<url-pattern>/bill</url-pattern>
</servlet-mapping>
It allows filters to be mapped on the particular servlet:
<filter-mapping>
<filter-name>Filter1</filter-name>
<servlet-name>Servlet1</servlet-name>
</filter-mapping>
Your proposal would support neither of them. Note that the web.xml is read and parsed only once during application's startup, not on every HTTP request as you seem to think.
Since Servlet 3.0, there's the #WebServlet annotation which minimizes this boilerplate:
#WebServlet("/enroll")
public class Servlet1 extends HttpServlet {
See also:
How do servlets work? Instantiation, sessions, shared variables and multithreading
Difference between each instance of servlet and each thread of servlet in servlets?
Our Servlets wiki page

Tomcat 7 and Grails deployment - what should the conf/web.xml look like?

I have added this to my web.xml file in Tomcat:
<servlet-mapping>
<servlet-name>GroovyTemplate</servlet-name>
<url-pattern>*.gsp</url-pattern>
</servlet-mapping>
But I get this from Catalina:
Caused by: java.lang.IllegalArgumentException: Servlet mapping specifies an unknown servlet name GroovyTemplate
The problem is that it will not load the manager anymore or any other apache tools that come with it.
But also if I do not have that in my web.xml then my Grails app will not start and returns a 404 error.
So what is the correct set up of the web.xml for grails app?
This is how it looks now (part of it):
<!-- The mapping for the default servlet -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- The mappings for the JSP servlet -->
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>GroovyTemplate</servlet-name>
<url-pattern>*.gsp</url-pattern>
</servlet-mapping>
please check out file yourGrailsProject/target/work/web.xml.tmp or here: https://github.com/wshearn/grails-test/blob/master/target/web.xml.tmp
where you can find sections like:
<!-- The Groovy Server Pages servlet -->
<servlet>
<servlet-name>gsp</servlet-name>
<servlet-class>org.codehaus.groovy.grails.web.pages.GroovyPagesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gsp</servlet-name>
<url-pattern>*.gsp</url-pattern>
</servlet-mapping>
which contain full path to GroovyPagesServlet.

Jersey JAX-RS: Specifying /* as base URL pattern

I have a Dynamic Web application, and because of the requirements, I am specifying two types of servlet mappings in the web.xml file; Faces Servlet & Jersey(JAX-RS implementation).
My problem is, that if I try to use '/' as the base url-pattern in the Jersey configuration, then the resources of Faces Servlets stop working, i.e., nothing happens if I make REST call to those resources, otherwise everything works fine if I place something like'/rest/' in the Jersey Configuration. My web.xml file looks like this:
<!-- Jersey -->
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.saf.web.v2.beans</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- Faces Servlet -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>100</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
Is there a way to specify the Jersey mapping so there is nothing in the url-pattern but '/*' and Faces Servlet resources also work fine at the same time.
Thanks!
If you define that Jersey should serve all requests (this is what /* means) the Faces Servlet doesn't have a chance any more. So in general: There is no such way.
Maybe you could work around this be mapping Jersey to /rest and writing an own Servlet mapped to /* which dispatches to one of the other servlets. I would not recommend that.
I had the same problem but I fixed it by using
/rest/*
for jersey's servlet
and other part of application can have any other url-pattern, as in your case it is *.xhtml for JSF's servlet.

Run JSF project on Apache Tomcat

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

Accessing a servlet's mapping from Tomcat?

The following code accesses a servlet's name: servletConfig.getServletName().
Can I access a servlet's URL pattern in a similar way?
An excerpt from web.xml:
<servlet-mapping>
<servlet-name>This is the servlet's name</servlet-name>
<url-pattern>/this-is-its-url-pattern/*</url-pattern>
</servlet-mapping>
In Servlet 3.0 (or Java EE 6) spec exist something:
http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRegistration.html
You can get a ServletRegistration using ServletContext.html#getServletRegistration.
Nothing is available in the Servlet API. Either parse the web.xml yourself, or duplicate it as an <init-param> of the servlet wherein you'd like to access it.
<servlet>
<servlet-name>servlet</servlet-name>
<servlet-class>com.example.Servlet</servlet-class>
<init-param>
<param-name>url-pattern</param-name>
<param-value>/servlet</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>servlet</servlet-name>
<url-pattern>/servlet</url-pattern>
</servlet-mapping>
This way it's available by servletConfig.getInitParameter("url-pattern").

Categories