2015年7月26日 星期日

Tomcat 8 and Spring Framework

Tomcat 8 and Spring Framework

TOMCAT Manager WAR File Limitation
Edit the file D:\Program Files\apache-tomcat-8.0.24\webapps\manager\WEB-INF\web.xml and update the section with the following:

    <multipart-config>
      <!-- 50MB max, 52428800. 7/26/2015 Changed to 1024,000,000 -->
      <max-file-size>1024000000</max-file-size>
      <max-request-size>1024000000</max-request-size>
      <file-size-threshold>0</file-size-threshold>
    </multipart-config>



Servlet Filter
Servlet Filter is attached before or after Servlet container.  A web application may have multiple servlets. 
A common scenario for a filter is one in which you want to apply preprocessing or postprocessing to requests or responses for a group of servlets, not just a single servlet. If you need to modify the request or response for just one servlet, there is no need to create a filter—just do what is required directly in the servlet itself.
Note that filters are not servlets. They do not implement and override HttpServlet methods such as doGet() or doPost(). Rather, a filter implements the methods of the javax.servlet.Filter interface. The methods are:
  • init()
  • destroy()
  • doFilter()
Any java class that implements these three methods can be configured as a filter.  The servlet container dispatches client HTTP request based on the filter mapping (URL patterns) that are registered in the web.xml by individual filters.   The filter uses the co-routine pattern where all lines of code before
    chain.doFilter(request,response);
are executed.  Here the content of HTTP request can be examined and actions taken.   Then the 'chain.doFilter' calls next filter and eventually the servlet (i.e. application code), which returns HTTP Response.

The execution path then returns to the filter and continues after 'chain.doFilter(request, response)'.   Here, the filters can examine the content of Http Response.   The actions taken can be logging, auditing, security checking, and monitoring.

The order the filters are invoked depends on the order in which they are configured in the web.xml file. The first filter in web.xml is the first one invoked during the request, and the last filter in web.xml is the first one invoked during the response. Note the reverse order during the response.

See Oracle document - http://docs.oracle.com/cd/B14099_19/web.1012/b14017/filters.htm

Spring Security, Servlet, and Web.xml
The architecture of Spring Security is based entirely on Servlet Filters and, as such, comes before Spring MVC in regards to the processing of HTTP requests.

Declare filters in the web.xml of the application:








<filter>
   <filter-name>springSecurityFilterChain</filter-name>
   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
   <filter-name>springSecurityFilterChain</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>
The filter must be named ‘springSecurityFilterChain’  to match the default bean created by Spring Security in the container.

Event Listeners
The servlet specification includes the capability to track key events in your Web applications through event listeners. This functionality allows more efficient resource management and automated processing based on event status.
There are two levels of servlet events:
  • Servlet context-level (application-level) event
    This event involves resources or state held at the level of the application servlet context object.
  • Session-level event
    This event involves resources or state associated with the series of requests from a single user session; that is, associated with the HTTP session object.
Each of these two levels has two event categories:
  • Lifecycle changes
  • Attribute changes
You can create one or more event listener classes for each of the four event categories. A single listener class can monitor multiple event categories.
Create an event listener class by implementing the appropriate interface or interfaces of the javax.servlet package or javax.servlet.http package.

Event Listener Declaration and Invocation
Event listeners are declared in the application web.xml deployment descriptor through <listener> elements under the top-level <web-app> element. Each listener has its own <listener> element, with a <listener-class> subelement specifying the class name. Within each event category, event listeners should be specified in the order in which you would like them to be invoked when the application runs.
After the application starts up and before it services the first request, the servlet container creates and registers an instance of each listener class that you have declared. For each event category, listeners are registered in the order in which they are declared. Then, as the application runs, event listeners for each category are invoked in the order of their registration. All listeners remain active until after the last request is serviced for the application.
Upon application shutdown, session event listeners are notified first, in reverse order of their declarations, then application event listeners are notified, in reverse order of their declarations.


The execution of a listener is like a interrupt call or aspect concern call.    This call could happen anywhere in the application serving some other requests.   This is not thread safe so shared objects must be protected with 'sync' operation.

Thread Safety
In fact, you can bypass injecting EntityManagerFactory and instead inject the EntityManager directly into BookDBAO. This is because thread safety is not an issue with request-scoped beans. Conversely, developers need to be concerned with thread safety when working with servlets and listeners. Therefore, a servlet or listener needs to inject an EntityManagerFactory instance, which is thread-safe, whereas a persistence context is not thread-safe.

Spring org.springframework.web.filter.DelegatingFilterProxy Class
Proxy for a standard Servlet Filter, delegating to a Spring-managed bean that implements the Filter interface. Supports a "targetBeanName" filter init-param in web.xml, specifying the name of the target bean in the Spring application context.
web.xml will usually contain a DelegatingFilterProxy definition, with the specified filter-name corresponding to a bean name in Spring's root application context. All calls to the filter proxy will then be delegated to that bean in the Spring context, which is required to implement the standard Servlet Filter interface.

NOTE: The lifecycle methods defined by the Servlet Filter interface will by default not be delegated to the target bean, relying on the Spring application context to manage the lifecycle of that bean. Specifying the "targetFilterLifecycle" filter init-param as "true" will enforce invocation of the Filter.init and Filter.destroy lifecycle methods on the target bean, letting the servlet container manage the filter lifecycle.

Spring org.springframework.web.SpringServletContainerInitializer  Class
The jar, spring-web.jar, is part of the application. The following file is the name of the Interface which will be implemented by the class in the content of this file.   This service will be started by Catalina automatically.

C:\Users\shendlz\.m2\repository\org\springframework\spring-web\3.2.4.RELEASE\spring-web-3.2.4.RELEASE.jar\META-INF\services\javax.servlet.ServletContainerInitializer

The content of this file is org.springframework.web.SpringServletContainerInitializer.

Run Web Application in Tomcat from Eclipse
The steps are:
1. Run As - Maven 'clean'
2. Maven 'Update project'
3.Run As -  Maven 'Build'
4. Tomcat Server - Clean (this will do publish after clean)
5. Run As - Run on Server

Before this, one should create a 'Server' in Eclipse by using the installed Tomcat server (assign the Tomcat installed directory).

In 'Server configuration page' (right click on the server) and under 'Server Locations' section, select the 2nd radio button 'Use Tomcat Instalation (takes control of Tomcat instalation)'.

Tomcat Slow Start-up Problem
Refer to this link.  Mostly due to Tomcat's scanning of Servlet 3.0 annotation tags through every jar during start-up time.
http://iswwwup.com/t/9ba94e27ea0a/java-tomcat-7-slow-start-metadata-complete-true-web-xml.html

At least one JAR was scanned for TLDs yet contained no TLDs

To make the warning go away add in catalina.properties :
# Additional JARs (over and above the default JARs listed above) to skip when
# scanning for TLDs. The list must be a comma separated list of JAR file names.
org.apache.catalina.startup.TldConfig.jarsToSkip=logback-classic-1.0.7.jar,\
joda-time-2.1.jar,joda-time-2.1-javadoc.jar,mysql-connector-java-5.1.24-bin.jar,\
logback-core-1.0.7.jar,javax.servlet.jsp.jstl-api-1.2.1.jar

Build a Web Application on Context Path "/"

1. In Eclipse, double click the 'Servers' tab and 'Modules' tab inside server view.  Click on the web app and change the 'Path' to '/'.
2. In maven pom, change the <finalName>/</finalName> to '/' instead of the web app name.

Then, do 'maven update project', clear server working directory, Run as Maven clean, then Run as Maven install, 'clean...' server.   Finally Run as 'Run on Server'.

There are two important points in the the documentation of the Context Container:
  • In individual files (with a ".xml" extension) in the $CATALINA_BASE/conf/[enginename]/[hostname]/ directory. The name of the file (less the .xml extension) will be used as the context path. Multi-level context paths may be defined using #, e.g. foo#bar.xml for a context path of /foo/bar. The default web application may be defined by using a file called ROOT.xml.
  • Only if a context file does not exist for the application in the $CATALINA_BASE/conf/[enginename]/[hostname]/, in an individual file at /META-INF/context.xml inside the application files. If the web application is packaged as a WAR then /META-INF/context.xml will be copied to $CATALINA_BASE/conf/[enginename]/[hostname]/ and renamed to match the application's context path. Once this file exists, it will not be replaced if a new WAR with a newer /META-INF/context.xml is placed in the host's appBase.
So, when you bundle a META-INF/context.xml, the file gets renamed to the name of the WAR and this name becomes the context path, regardless of any path defined in the Context element.
I see thus two options here:
  1. Either set the name of the generated war to a shorter name (I suggest using <finalName> over<warName> which is deprecated AFAIK):
    <project>
      ...
      <build>
        <finalName>mycontext</finalName>
        ...
      </build>
      ...
    </project>
  2. Or use the maven-tomcat-plugin for the deployment and set the context path in the plugin configuration:
    <project>
      ...
      <build>
        ...
        <plugins>
          ...
          <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>tomcat-maven-plugin</artifactId>
            <version>1.0-SNAPSHOT</version>
            <configuration>
              <path>/mycontext</path>
            </configuration>
          </plugin>
          ...
        </plugins>
        ...

沒有留言:

張貼留言