Подтвердить что ты не робот

Как инициализировать сервлет во время запуска с параметрами?

Можно ли написать конструктор аргументов в Servlet? Если да, как вы можете позвонить?

4b9b3361

Ответ 1

Можно ли написать конструктор аргументов в Servlet?

Да, вы можете, но это бесполезно, поскольку контейнер сервлета не будет вызывать его.

Правильный способ сделать это - использовать метод init():

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

В этом примере getInitParameter("foo") возвращает значение <init-param> конкретной записи <servlet> в web.xml и getServletContext().getInitParameter("bar") возвращает значение независимого <context-param> в web.xml.

Ответ 2

Проблема может быть более общей:

"Согласно сервлетам (2.3) спецификации, сервлеты созданный механизмом сервлета вызывая конструктор no-arg. Как я могу правильно инициализировать сервлет что правильная инициализация зависит от центральный/глобальный/уникальный/приложение конфигурация?"

Собственно, вы можете использовать serlvets с конструктором и/или инициализировать их по своему усмотрению. Однако для этого требуется немного сантехники.

Предполагая, что у вас есть сервлет с конструктором с аргументами:

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

Первое, что вам нужно - это уникальный сервлет в вашем приложении, позвольте ему вызвать InitializationServlet, чтобы создать все необходимые экземпляры. Затем эти экземпляры должны быть экспортированы в контексте сервлета, который будет извлекаться другим сервлетом (объясняется позже). ИнициализацияServlet может выглядеть следующим образом:

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(). Этот сервлет не обслуживает HTTP-запрос. Его единственная цель - хранить сервлет в ServletContext. Обратите внимание, что вы также можете использовать этот сервлет для загрузки конфигурации вашего приложения. Таким образом, это может действовать как точка входа в веб-приложение, например, метод main(String[] args) программы. Это может напоминать вам о ContextLoaderServlet из SpringSource.

Последний фрагмент - это DelegateServlet, который будет эффективно создаваться контейнером сервлета, только этот сервлет переадресует все вызовы соответствующего метода на экземпляр завернутого сервлета:

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.

Web.xml для такого приложения может выглядеть так:

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

  <display-name>Example</display-name>
  <description>Example web showing handling of servlets w/ constructors.</description>


  <servlet>
    <servlet-name>Initialization</servlet-name>
    <servlet-class>org.gawi.example.servlets.InitializationServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet>
    <servlet-name>A</servlet-name>
    <servlet-class>org.gawi.example.servlets.DelegateHttpServlet</servlet-class>

    <init-param>
      <param-name>servletContextKey</param-name>
      <param-value>servletA</param-value>
    </init-param>

    <load-on-startup>2</load-on-startup>
  </servlet>

  <servlet>
    <servlet-name>B</servlet-name>
    <servlet-class>org.gawi.example.servlets.DelegateHttpServlet</servlet-class>

    <init-param>
      <param-name>servletContextKey</param-name>
      <param-value>servletB</param-value>
    </init-param>

    <load-on-startup>3</load-on-startup>
  </servlet>

  <servlet>
    <servlet-name>C</servlet-name>
    <servlet-class>org.gawi.example.servlets.DelegateHttpServlet</servlet-class>

    <init-param>
      <param-name>servletContextKey</param-name>
      <param-value>servletC</param-value>
    </init-param>

    <load-on-startup>4</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>A</servlet-name>
    <url-pattern>/servlet/a</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>B</servlet-name>
    <url-pattern>/servlet/b</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>C</servlet-name>
    <url-pattern>/servlet/c</url-pattern>
  </servlet-mapping>

  <session-config>
    <session-timeout>5</session-timeout>
  </session-config>
</web-app>

Обязательно сначала загрузите InitializationServlet, используя низкое значение <load-on-startup>.

Преимущество этого подхода состоит в том, что объекты HttpServlet могут обрабатываться как любой другой обычный объект Java или bean. Следовательно, он обеспечивает лучший контроль за инициализацией: больше нечего делать в методе init() или бесполезной обработке init-arg сервлета.

Ответ 3

Конструкторы - это объекты, управляемые сервером приложений.

Для инициализации см. метод init().

Update:

Можно ли использовать конструктор в моем сервлете?

A: Сервлет - обычный класс Java, поэтому, когда нет пользовательских конструкторов, существует неявное конструктор по умолчанию без аргументов. Контейнеры сервлетов обычно используют Метод Class.newInstance() для загрузки сервлеты, поэтому вы должны быть осторожны добавить явный конструктор по умолчанию, если вы добавляете нестандартные конструкторы.

источник: http://www.codestyle.org/java/servlets/FAQ.shtml

Ответ 4

Вы не можете. Сервлет создается рефлексивно контейнером. Если спецификация сервлета допускает аргументы в конструкторе, вам придется иметь сложный дескриптор развертывания, например,

<servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>MyServlet</servlet-class>
    <servlet-argument id="1" type="string">Test<servlet-argument>
    <servlet-argument id="2" type="int">10</servlet-argument>
    <load-on-startup>1</load-on-startup>
</servlet>

Думаю, никто этого не хочет.