如何使用参数在启动期间初始化Servlet?

我们可以在Servlet中编写参数构造函数吗? 如果是的话,你怎么打电话?

我们可以在Servlet中编写参数构造函数吗?

是的,你可以,但它没用,因为servlet容器不会调用它。

正确的方法是使用init()方法:

 @Override public void init() throws ServletException { String foo = getInitParameter("foo"); String bar = getServletContext().getInitParameter("bar"); // ... } 

在此示例中, getInitParameter("foo")返回web.xml特定条目的的值, getServletContext().getInitParameter("bar")返回独立的值 web.xml

问题可能是更普遍的状态:

“根据servlets(2.3)规范,servlet通过调用no-arg构造函数来实例化servlet。如果正确初始化取决于中心/全局/唯一/应用程序配置,我如何正确初始化servlet?”

实际上,您可以将serlvets与构造函数一起使用和/或根据需要对其进行初始化。 但是,它需要一点管道。

假设你有一个带有参数的构造函数的servlet:

 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); } } 

您需要的第一件事是在您的应用程序中使用一个独特的servlet,我们称之为InitializationServlet,以创建所有必需的实例。 然后必须将这些实例导出到servlet上下文中,以便由另一个servlet检索(稍后解释)。 InitializationServlet可能如下所示:

 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); } } 

您会看到只提供了init()方法。 此servlet不为任何HTTP请求提供服务。 它的唯一目的是将servlet存储在ServletContext中。 请注意,您也可以使用此servlet加载应用程序配置。 所以这可以充当web应用程序入口点,就像程序的main(String[] args)方法一样。 这可能会提醒您SpringSource的ContextLoaderServlet。

最后一部分是DelegateServlet,它将由servlet容器实际实例化,只有这个servlet会将所有相关的方法调用转发给包装的servlet实例:

 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); } } 

在初始化期间,DelegateServlet将使用servletContextKey servlet初始参数在servlet上下文中查找目标servlet。

此类应用程序的web.xml可能如下所示:

    Example Example web showing handling of servlets w/ constructors.  Initialization org.gawi.example.servlets.InitializationServlet 1   A org.gawi.example.servlets.DelegateHttpServlet  servletContextKey servletA  2   B org.gawi.example.servlets.DelegateHttpServlet  servletContextKey servletB  3   C org.gawi.example.servlets.DelegateHttpServlet  servletContextKey servletC  4   A /servlet/a   B /servlet/b   C /servlet/c   5   

确保首先使用低值加载InitializationServlet。

这种方法的好处是HttpServlet对象可以像任何其他常规Java对象或bean一样处理。 因此,它提供了对初始化的更好控制:在init()方法中没有更多棘手的事情要做,也没有凌乱的servlet init-arg处理。

你不能。 Servlet通过容器reflection实例化。 如果servlet规范允许构造函数中的参数,则必须有一些复杂的部署描述符,如

  MyServlet MyServlet Test 10 1  

我想没有人想要那个。

构造函数是由应用程序服务器管理的对象。

有关初始化,请参阅init()方法。

更新:

我可以在servlet中使用构造函数吗?

答:servlet是一个普通的Java类,所以当没有自定义构造函数时,就会有一个没有参数的隐式默认构造函数。 Servlet容器通常使用Class.newInstance()方法来加载servlet,因此如果添加非默认构造函数,则必须小心添加显式默认构造函数。

来源: http : //www.codestyle.org/java/servlets/FAQ.shtml