Table of Contents
|
Overview 1. Servlet Intro 2. JSP Intro 3. MVC 4. Environment 5. Container facilities 6. View facilities 7. JSP pages 8. Custom tags 9. Controller facilities 10. Model options 11. Asynchronous 12. Security
Introduction
The server hands requests to a Container in which the servlet is deployed. The Container gives the servlet the HTTP request and response, and calls the servlet's method, such as doPost() or doGet(). It creates the HttpServletResponse and HttpServletRequest objects.
Process:
- Container creates HttpServletRequest/HttpServletResponse objects
- Container determines servlet based on URL-pattern, creates thread and calls service()
- services calls doGet() or doPost()
- servlet writes to response
- service() completes, control returns to container
- thread dies or returns to pool
The container provides:
- web app communications support
- lifecycle management
- multithreading support
- declarative security
- support for JSPs
Attributes vs Parameters
- Attributes are used directly by programmers
- Parameters are set as part of deployment, or through user interactions
Attributes | Parameters | |
---|---|---|
Types | Application/context, Request, Session | context init parameters, Request parameters, Servlet init parameters |
Method to set | setAttribute(String name, Object value) | N/A |
Return type | Object | String |
Method to get | getAttribute(String name) | getInitParameter(String name) |
Attribute Scope
Accessibility | Scope | What it’s good for | |
---|---|---|---|
Context | Any part, including servlets, JSPs, ServletContextListeners, ServletContextAttributeListeners | Lifetime of the ServletContext, which means life of the deployed app. | Resources you want the entire application to share, including database connections, JNDI lookup names, email addresses., etc. NOT thread safe, use synchronized(getServletContext()) |
HttpSession | Any servlet or JSP with access to this particular session. | The life of the session. A session can be destroyed programmatically or can simply time-out. | Data and resources related to this client’s session, not just a single request. NOT thread safe, use synchronized(session) |
Request | Any part of the application that has direct access to the Request object. That mostly means only the Servlets and JSPs to which the request is forwarded using a RequestDispateher. Also Request-related listeners. | The life of the Request, which means until the Servlet’s service() method completes. In other words, for the life of the thread (stack) handling this request | Passing model info from the controller to the view… or any other data specific to a single client request. Thread-safe |
5.1 Understand the purpose and structure of deployment descriptors
Servlets have 3 names:
- client name: URL (url-pattern)
- internal name: e.g. HelloServlet (servlet-name)
- fully qualified name: mypackage.HelloServlet (servlet-class)
<web-app> <servlet> <servlet-name>Basic Servlet</servlet-name> <servlet-class>com.example.servlets.BasicServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Basic Servlet</servlet-name> <url-pattern>/BasicServlet</url-pattern> </servlet-mapping> </web-app>
<url-pattern>
- More specific URL patterns (paths) take precedence over less specific.
- You cannot have any prepending path for an extension mapping (e.g. test/*.jsp)
<load-on-startup>
<servlet> <servlet-name>KathyOne</servlet-name> <servlet-class>com.example.servlets.BasicServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>
<error-page>
<!-- catch-all error page --> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/errorPage.jsp</location> </error-page> <!-- override for more specific exception --> <error-page> <exception-type>java.lang.ArithmeticException</exception-type> <location>/arithmeticError.jsp</location> </error-page> <!-- error page based on an HTTP status code --> <error-page> <error-code>404</error-code> <location>/notFoundError.jsp</location> </error-page>
You cannot throw non runtime business exceptions from the servlet code because the signatures of the doXXX and service method only permit IOException and ServletException.
Let's say your AccountServlet wants to throw NotEnoughFundsException. It should be handled as follows:
//in doPost() of AccountServlet try { ...lot of code if(funds<amt) throw new NotEnoughFundsException(); ...lot of code } catch(NotEnoughFundsException nfe) { throw new ServletException(nfe) // wrap the exception inside ServletException }
The error mapping in DD should be:
<exception-type>com.mycorp.NotEnoughFundsException</exception-type> <location>/errorPage.jsp</location>
welcome files
No preceeding slash is allowed
<web-app> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
ejb tags
For more on these tags, see 10.2 Understand the many elements that make up the model
Local bean:
<ejb-local-ref> <ejb-ref-name>ejb/Customer</ejb-ref-name> <ejb-ref-type>Entity</ejb-ref-type> <local-home>com.wickedlysmart.CustomerHome</local-home> <local>com.wickedlysmart.Customer</local> </ejb-local-ref>
Remote bean:
<ejb-ref> <ejb-ref-name>ejb/LocalCustomer</ejb-ref-name> <ejb-ref-type>Entity</ejb-ref-type> <home>com.wickedlysmart.CustomerHome</home> <remote>com.wickedlysmart.Customer</remote> </ejb-ref>
JNDI
<env-entry> <env-entry-name>rates/discountRate</env-entry-name> <env-entry-type>java.lang.Integer</env-entry-type> <env-entry-value>10</env-entry-value> </env-entry>
<mime-mapping>
No dot before the extension name.
<mime-mapping> <extension>mpg</extension> <mime-type>video/mpeg</mime-type> </mime-mapping>
Directory locations
Any requests to access the resources in WEB-INF or META-INF directories must be returned with a SC_NOT_FOUND(404) response.
- JSPs
- WEB-INF
- classes
- compiled java classes
- tags folder
- tag files (.tag .tagx)
- any folder
- TLD files
- lib folder
- jar files
- META-INF
- tags
- TLD files
- any folder
- TLD files
- resources
- static resources available from /context/static_resource.ext
- META-INF (generated when application bundled into war)
5.2 Control context root and servlet mapping
Context root mapping
In full stack Java EE containers, the context root can be set in application.xml. e.g.
<module> <web> <web-uri>web-client.war</web-uri> <context-root>myContextRoot</context-root> </web> </module>
Servlet mapping
Can use wildcard (*).
<servlet> <servlet-name>Beer</servlet-name> <servlet-class>com.example.BeerSelect</servlet-class> </servlet> <servlet-mapping> <servlet-name>Beer</servlet-name> <url-pattern>/Beer/SelectBeer.do</url-pattern> </servlet-mapping>
The <enabled>element (subelement of <servlet>) set to "false" forces the container to make the request for the servlet respond with HTTP Code 503 (Service unavailable)
Servlet unavailability
It is appropriate for a servlet to throw a ServletException or UnavailableException (remember, UnavailableException extends ServletException) if it is not able to initialize. In this case, the container will not send any request to this servlet. Other servlets will remain unaffected.
UnavailableException has two different constructors that are used to specify whether the resource is permanently or temporarily unavailable:
- UnavailableException(java.lang.String msg): Constructs a new exception with a descriptive message indicating that the servlet is permanently unavailable.
- UnavailableException(java.lang.String msg, int seconds): Constructs a new exception with a descriptive message indicating that the servlet is temporarily unavailable and giving an estimate of how long it will be unavailable.
5.3 Create and use context and init parameters
ServletConfig
- Read only once when the Container initalizes the servlet
- One ServletConfig object per servlet.
- Use it to pass deploy-time information to the servlet that you don’t want to hard-code into the servlet.
- Use it to access the ServletContext.
- Parameters are configured in the Deployment Descriptor. Servlet cannot change values.
- Cannot use getServletConfig() until init() called
- Note that it's init(), not init(ServletConfig servletConfig) that is used in the superclass
<servlet> <servlet-name>BeerParamTests</servlet-name> <servlet-class>TestInitParams</servlet-class> <init-param> <param-name>adminEmail</param-name> <param-value>likewecare@wickedlysmart.com</param-value> </init-param> </servlet>
out.println(getServletConfg().getInitParameter("adminEmail"));
ServletContext
- One ServletContext per web app.
- Use it to access web app parameters (also configured in the Deployment Descriptor).
- Use it as a kind of application bulletin-board, where you can put up messages (called attributes) that other parts of the application can access
- Use it to get server info, including the name and version of the Container, and the version of the API that’s supported.
Place context-param outside of servlet tags:
<context-param> <param-name>adminEmail</param-name> <param-value>clientheaderror@wickedlysmart.com</param-value> </context-param>
out.println(getServletContext().getInitParameter("adminEmail"));
Note that the following are equivalent:
getServletConfig().getServletContext().getInitParameter() this.getServletContext().getInitParameter()
ServletContext interface
addListener(String classname) getInitParameter(String) getInitParameterNames() getAttribute(String) getAttributeNames() setAttribute(String, Object) removeAttribute(String) getMajorVersion() getServerInfo() getRealPath(String) getResource(String) : URL getResourceAsStream(String) : InputStream // path must begin with a "/" and is interpreted as relative to the context root getRequestDispatcher(String) log(String) setInitParameter() // can set initParams before container initialised
ServletContextListener
The interface has two methods which can be used to setup and tear down resources for the container.
contextInitialized(ServletContextEvent) contextDestroyed(ServletContextEvent)
web.xml requires:
<listener> <listener-class> com.example.MyServletContextListener </listener-class> </listener>
5.4 Use annotations to configure servlets
- @WebServlet(/path) - the path is relative to the context root
- web.xml configuration overrides annotation configuration
- web.xml and WEB-INF no longer required
- The following annotations were added in 3.0:
@HandlesTypes @HttpConstraint @HttpMethodConstraint @MultipartConfig @ServletSecurity @WebFilter @WebInitParam @WebListener @WebServlet
Section 15.5 of Servlet 3.0 specification specifies all the annotations that must be supported by the servlet container for Servlet, Filter, or various Listener classes. The following is the list for your convenience:
15.5.1 @DeclareRoles
15.5.2 @EJB Annotation
15.5.3 @EJBs Annotation
15.5.4 @Resource Annotation
15.5.5 @PersistenceContext Annotation
15.5.6 @PersistenceContexts Annotation
15.5.7 @PersistenceUnit Annotation
15.5.8 @PersistenceUnits Annotation
15.5.9 @PostConstruct Annotation
15.5.10 @PreDestroy Annotation
15.5.11 @Resources Annotation
15.5.12 @RunAs Annotation
15.5.13 @WebServiceRef Annotation
15.5.14 @WebServiceRefs Annotation
Precedence rules
- Web.xml always takes precedence over annotations.
- Web.xml always takes precedence over web-fragment.xml.
- Before processing annotations, all web-fragments are merged into web.xml.
- If web.xml specifies metadata-complete=true, then no class is parsed for annotations.
- If any web-fragment.xml specifies metadata-complete=true, only annotations specified in classes contained in that web fragment are ignored.
- Merge is always additive as long as the result does not violate any multiplicity constraint. For example, if you have an two different init-parameters defined in two places, both will be added because one can have any number of init-parameters.
- Information in Web.xml always supersedes anything else. For example, if you have the same init-parameters defined with different values in web.xml as well as a web-fragment.xml, the value specified in web.xml will be used.
- Contradictory information in two web-fragments, produces an error and application fails to deploy. For example, if you have an same init-parameters defined with different values in two different web-fragment.xml but no value in web.xml, it will cause an error.
- Differently named servlets with same url-pattern: two instances of the servlet should be created, but which instance should be used to service the url pattern is not clear. Since web.xml takes precedence, the instance created as per information in web.xml should be used
- If the url-pattern is defined in the DD it replaces the urlPatterns annotation for the particular servlet.
Basic configuration
@WebServlet("/a") public class ServletAnnotatedA extends HttpServlet {
value
It is recommended to use value when the only attribute on the annotation is the url pattern and to use the urlPatterns attribute when the other attributes are also used. It is illegal to have both value and urlPatterns attribute used together on the same annotation.
@WebServlet(value="/b") public class ServletAnnotatedB extends HttpServlet {
urlPatterns
- can take a single String or array of Strings
- cannot be used with value
- either value or urlPatterns is required with @WebServlet
@WebServlet(urlPatterns = {"/c","/c2"}) public class ServletAnnotatedC extends HttpServlet {
name
The default name of the Servlet if not specified is the fully qualified class name.
@WebServlet(name="MyServlet") public class ServletAnnotatedX extends HttpServlet {
initParams and @WebInitParam
@WebServlet(value = "/d",initParams = {@WebInitParam(name = "name", value = "Bob"), @WebInitParam(name = "age", value = "12")}) public class ServletAnnotatedInitParams extends HttpServlet {
aSync (asynchronous)
@WebServlet(urlPatterns={"/asyncservlet"}, asyncSupported=true) public class ServletAnnotatedAsync extends HttpServlet {
All options
boolean asyncSupported
Declares whether the servlet supports asynchronous operation mode.
java.lang.String description
The description of the servlet
java.lang.String displayName
The display name of the servlet
WebInitParam[] initParams
The init parameters of the servlet
java.lang.String largeIcon
The large-icon of the servlet
int loadOnStartup
The load-on-startup order of the servlet
java.lang.String name
The name of the servlet
java.lang.String smallIcon
The small-icon of the servlet
java.lang.String[] urlPatterns
The URL patterns of the servlet
java.lang.String[] value
The URL patterns of the servlet
Web fragments
New in Java EE 6. Web fragments allow you to split up web.xml in a modular fashion. See these links:
- https://blogs.oracle.com/swchan/entry/servlet_3_0_web_fragment
- http://www.oracle.com/technetwork/articles/javaee/javaee6overview-part2-136353.html
The fragment should be stored in a file called web-fragment.xml inside the META-INF directory of a jar file in WEB-INF/lib. Here is an example of a web fragment that registers a servlet and a listener:
<web-fragment> <name>MyFragment1</name> <servlet> <servlet-name>myFrameworkServlet</servlet-name> <servlet-class>myFramework.myFrameworkServlet</servlet-class> </servlet> <listener> <listener-class>myFramework.myFrameworkListener</listener-class> </listener> </web-fragment>
In web.xml, or a web-fragment.xml, you can specify metadata-complete="true" to halt processing of web fragments and annotations:
<web-app metadata-complete="true" ... <web-fragment metadata-complete="true" ...
When used on a web-fragment.xml, it is only applied to a particular jar, if inside a jar file.
Ordering can be imposed on web fragments inside the web.xml using <absolute-ordering>.
Rules:
- If <others/> is absent, no other web fragments then those specified will be added to the deployment descriptor
- <absolute-ordering> overrides any web-fragment.xml ordering.
- If <web-app metadata-complete="true">, ordering is disregarded
- The situation in which two different web fragments defines the same name of a <init-param> but with different values is as a configuration conflict. It will result in an application deploy failure.
<absolute-ordering> <name>MyFragment2</name> <name>MyFragment1</name> <others/> </absolute-ordering> <!-- another example (in a separate file, as only one of these can exist) --> <absolute-ordering> <name>WF1</name> <others/> <name>WF3</name> </absolute-ordering>
Or in the web-fragments themselves. using before, after and others. e.g. WF1, WF3, WF2
<web-fragment> <name>WF1</name> <ordering> <before><name>WF2</name></before> </ordering> </web-fragment> <web-fragment> <name>WF2</name> <ordering> <after><others/></after> </ordering> </web-fragment> <web-fragment> <name>WF3</name> <ordering> <after><name>WF1</name></after> </ordering> </web-fragment>
Programmatic registration of servlets
You can add a servlet or a filter dynamically only before the initialization of the servlet context is complete. Here, "initialization of a servlet context" means initialization of the web application. Initialization is not considered complete until contextInitialized() of all ServletContextListeners is complete. So you can register a servlet in contextInitialized() of a ServletContextListener.
Within the ServletContextListener or the ServletContainerInitializer you can:
- add servlets
- add filters
- add listeners (all but HttpSessionActivationListener, HttpSessionBindingListener)
- instantiate servlets class
- instantiate filters class
- access already registered servlets and filters (programmatically, annotations, web.xml)
- modify url patterns the servlets / filters maps to
Rules:
- When the servlet is programmatically created using the same name as previously defined (using annotations or DD), the behaviour is not specified.
The following are the methods available in ServletContext that allow you to register a servlet dynamically:
ServletRegistration.Dynamic addServlet(java.lang.String servletName, java.lang.Class<? extends Servlet> servletClass) // Adds the servlet with the given name and class type to this servlet context. ServletRegistration.Dynamic addServlet(java.lang.String servletName, Servlet servlet) // Registers the given servlet instance with this ServletContext under the given servletName. ServletRegistration.Dynamic addServlet(java.lang.String servletName, java.lang.String className) // Adds the servlet with the given name and class name to this servlet context.
And for adding a filter:
FilterRegistration.Dynamic addFilter(java.lang.String filterName, java.lang.Class<? extends Filter> filterClass) // Adds the filter with the given name and class type to this servlet context. FilterRegistration.Dynamic addFilter(java.lang.String filterName, Filter filter) // Registers the given filter instance with this ServletContext under the given filterName. FilterRegistration.Dynamic addFilter(java.lang.String filterName, java.lang.String className) // Adds the filter with the given name and class name to this servlet context.
It is good to know about the hierarchy of Registration Interfaces and the features they support.
javax.servlet.Registration : /* Allows adding init parameters using setInitParameter and setInitParameters. All Known Subinterfaces: FilterRegistration, FilterRegistration.Dynamic, Registration.Dynamic, ServletRegistration, ServletRegistration.Dynamic */ javax.servlet.ServletRegistration extends javax.servlet.Registration: // Provides addMapping and addMappings All Known Subinterfaces: ServletRegistration.Dynamic javax.servlet.Registration.Dynamic extends javax.servlet.Registration: // Provides setAsyncSupported All Known Subinterfaces: FilterRegistration.Dynamic, ServletRegistration.Dynamic javax.servlet.ServletRegistration.Dynamic extends ServletRegistration : setLoadOnStartup, setMultipartConfig, setRunAsRole(java.lang.String roleName), setServletSecurity(ServletSecurityElement constraint)
class | extends | description |
---|---|---|
Registration | n/a | Allows adding init parameters using setInitParameter and setInitParameters. |
ServletRegistration | Registration | Provides addMapping and addMappings |
Registration.Dynamic | Registration | Provides setAsyncSupported |
ServletRegistration.Dynamic | ServletRegistration | setLoadOnStartup, setMultipartConfig, setRunAsRole(java.lang.String roleName), setServletSecurity(ServletSecurityElement constraint) |
Overview 1. Servlet Intro 2. JSP Intro 3. MVC 4. Environment 5. Container facilities 6. View facilities 7. JSP pages 8. Custom tags 9. Controller facilities 10. Model options 11. Asynchronous 12. Security
Comments
If you have questions, corrections, information or examples to add, please comment below.
Post preview:
Close preview