Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The problem can be state more generically: </p> <blockquote> <p>"According to the servlets (2.3) specification, the servlets are instantiated by the servlet engine by invoking the no-arg constructor. How can I initialize a servlet properly given that correct initialization depends on the central/global/unique/application configuration?"</p> </blockquote> <p>Actually, you can use serlvets with constructor and/or initialize them as you like. However, it requires a little bit of plumbing.</p> <p>Assuming you have a servlet with a constructor having arguments:</p> <pre><code>package org.gawi.example.servlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class SampleServlet extends HttpServlet { private final String mMessage; public SampleServlet(String message) { mMessage = message; } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/plain"); response.getWriter().write(mMessage); } } </code></pre> <p>The first thing you need is a unique servlet whithin your application, let's call it InitializationServlet, to create all the required instances. Those instances must then be exported in the servlet context to be retrieve by another servlet (explained later). The InitializationServlet may look like this:</p> <pre><code>package org.gawi.example.servlets; import javax.servlet.*; import javax.servlet.http.*; public class InitializationServlet extends HttpServlet { public void init() throws ServletException { SampleServlet servletA = new SampleServlet("this is servlet A"); SampleServlet servletB = new SampleServlet("this is servlet B"); SampleServlet servletC = new SampleServlet("this is servlet C"); getServletContext().setAttribute("servletA", servletA); getServletContext().setAttribute("servletB", servletB); getServletContext().setAttribute("servletC", servletC); } } </code></pre> <p>You see that only the <code>init()</code> method has been provided. This servlet is not servicing any HTTP request. Its only purpose is to store the servlet in the ServletContext. Note that you could have also use this servlet to load your application configuration. So this can act as the web-application entry point, like the <code>main(String[] args)</code> method of a program. This might remind you of the ContextLoaderServlet of SpringSource.</p> <p>The last piece is the DelegateServlet that will effectively be instantiated by the servlet container, only this servlet will forward all the pertinent method calls to the wrapped servlet instance:</p> <pre><code>package org.gawi.example.servlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class DelegateHttpServlet extends HttpServlet { private static final String SERVLET_CONTEXT_KEY_INIT_PARAMETER = "servletContextKey"; private HttpServlet mServlet; public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); locateServlet(servletConfig); mServlet.init(servletConfig); } private void locateServlet(ServletConfig servletConfig) throws ServletException { String servletContextAttributeName = servletConfig.getInitParameter(SERVLET_CONTEXT_KEY_INIT_PARAMETER); if (servletContextAttributeName == null) { throw new ServletException("Unable to find init parameter '" + SERVLET_CONTEXT_KEY_INIT_PARAMETER + "'"); } Object object = servletConfig.getServletContext().getAttribute(servletContextAttributeName); if (object == null) { throw new ServletException("Unable to find " + servletContextAttributeName + " in servlet context."); } if (!(object instanceof HttpServlet)) { throw new ServletException("Object is not an instance of" + HttpServlet.class.getName() + ". Class is " + object.getClass().getName() + "."); } mServlet = (HttpServlet) object; } public void destroy() { mServlet.destroy(); } public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { mServlet.service(req, res); } } </code></pre> <p>During its initialization, the DelegateServlet will look-up the target servlet in the servlet context using the <code>servletContextKey</code> servlet initial argument.</p> <p>The web.xml for such an application might look like that:</p> <pre><code>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt; &lt;!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"&gt; &lt;web-app&gt; &lt;display-name&gt;Example&lt;/display-name&gt; &lt;description&gt;Example web showing handling of servlets w/ constructors.&lt;/description&gt; &lt;servlet&gt; &lt;servlet-name&gt;Initialization&lt;/servlet-name&gt; &lt;servlet-class&gt;org.gawi.example.servlets.InitializationServlet&lt;/servlet-class&gt; &lt;load-on-startup&gt;1&lt;/load-on-startup&gt; &lt;/servlet&gt; &lt;servlet&gt; &lt;servlet-name&gt;A&lt;/servlet-name&gt; &lt;servlet-class&gt;org.gawi.example.servlets.DelegateHttpServlet&lt;/servlet-class&gt; &lt;init-param&gt; &lt;param-name&gt;servletContextKey&lt;/param-name&gt; &lt;param-value&gt;servletA&lt;/param-value&gt; &lt;/init-param&gt; &lt;load-on-startup&gt;2&lt;/load-on-startup&gt; &lt;/servlet&gt; &lt;servlet&gt; &lt;servlet-name&gt;B&lt;/servlet-name&gt; &lt;servlet-class&gt;org.gawi.example.servlets.DelegateHttpServlet&lt;/servlet-class&gt; &lt;init-param&gt; &lt;param-name&gt;servletContextKey&lt;/param-name&gt; &lt;param-value&gt;servletB&lt;/param-value&gt; &lt;/init-param&gt; &lt;load-on-startup&gt;3&lt;/load-on-startup&gt; &lt;/servlet&gt; &lt;servlet&gt; &lt;servlet-name&gt;C&lt;/servlet-name&gt; &lt;servlet-class&gt;org.gawi.example.servlets.DelegateHttpServlet&lt;/servlet-class&gt; &lt;init-param&gt; &lt;param-name&gt;servletContextKey&lt;/param-name&gt; &lt;param-value&gt;servletC&lt;/param-value&gt; &lt;/init-param&gt; &lt;load-on-startup&gt;4&lt;/load-on-startup&gt; &lt;/servlet&gt; &lt;servlet-mapping&gt; &lt;servlet-name&gt;A&lt;/servlet-name&gt; &lt;url-pattern&gt;/servlet/a&lt;/url-pattern&gt; &lt;/servlet-mapping&gt; &lt;servlet-mapping&gt; &lt;servlet-name&gt;B&lt;/servlet-name&gt; &lt;url-pattern&gt;/servlet/b&lt;/url-pattern&gt; &lt;/servlet-mapping&gt; &lt;servlet-mapping&gt; &lt;servlet-name&gt;C&lt;/servlet-name&gt; &lt;url-pattern&gt;/servlet/c&lt;/url-pattern&gt; &lt;/servlet-mapping&gt; &lt;session-config&gt; &lt;session-timeout&gt;5&lt;/session-timeout&gt; &lt;/session-config&gt; &lt;/web-app&gt; </code></pre> <p>Be sure to load the InitializationServlet first, using a low <code>&lt;load-on-startup&gt;</code> value.</p> <p>The benefit of this approach is that <code>HttpServlet</code> objects can be handled like any other regular Java object or bean. Hence, it provides a better control over initialization: no more tricky stuff to do in the <code>init()</code> method, nor messy servlet init-arg handling.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload