Веб-ядро — сервлет

Java задняя часть Spring API

Сервлет на самом деле является ServerApplet — небольшой служебной программой или служебным коннектором, серверной программой, написанной на Java, основная функция которой заключается в интерактивном просмотре и изменении данных, а также в создании динамического веб-контента. Подобно общепринятым протоколам, таким как DNS, TCP/IP и HTTP, Servlet существует как набор спецификаций; в то же время, как часть стандарта J2EE, он определяет стандарт для разработки javaweb. Сервлет разработал ряд стандартов для java для обработки WEB-запросов, нам нужно только сделать это в соответствии со стандартами.
На самом деле, будь то FilterDispatcher из Struts2 или DispatcherServlet из SpringMvc, нижний уровень реализован путем реализации расширения типа Sevlet или Servlet [например: GenericServlet].

1. Интерфейс сервлета

На следующем рисунке показана структурная схема в Servlet3.1:


Поскольку сервлет существует стандартным образом, он фактически определяет ряд стандартных интерфейсов. Интерфейс сервлета в основном включает следующие интерфейсы:

1) Метод init вызывается контейнером при запуске контейнера, и он будет вызван только один раз;
2) метод getServletConfig используется для получения ServletConfig;
3) Сервисный метод используется для обработки конкретного запроса
4) Метод getServletInfo используется для получения информации, связанной с сервлетом: авторские права и т. д.
5) Метод destroy используется для уничтожения сервлета.Как и init, он вызывается только один раз и обычно используется для высвобождения некоторых ресурсов при выключении сервера.

Когда вызывается метод init, он принимает параметр типа ServletConfig, который используется для инициализации сервлета, передаваемого контейнером. ServletConfig, как следует из названия, содержит информацию о конфигурации для Serlvet. Обычно, когда мы определяем Serlvet в файле web.xml, мы настраиваем параметры через тег init-param. В конфигурации Springmvc параметры обычно настраиваются следующими способами:

2. Интерфейс ServletConfig


1) getServletName используется для получения имени сервлета, которое является именем сервлета, которое мы определили в web.xml.
2) getServletContext возвращает ServletContext, представляющий само наше текущее приложение
3) getInitParameter используется для получения параметров, настроенных init-param
4) getInitParameterNames используется для получения коллекции всех имен конфигурации параметров инициализации.
Чаще всего ServletContext и ServletConfig используются для передачи параметров инициализации. Давайте посмотрим на конфигурацию параметров contextConfigServlet весной.

ContextConfigLocation, настроенный через context-param, настраивается в ServletContext, а затем настраивается в ServletConfig через contextConfigLocation, настроенный через init-param в сервлете, и конкретная информация может быть получена с помощью метода getInitParameter в сервлете.

3.GenericServlet

GenericServlet — это реализация Servlet по умолчанию, код выглядит следующим образом:


package javax.servlet;
import java.io.IOException;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.ResourceBundle;
public abstract class GenericServlet
  implements Servlet, ServletConfig, Serializable
{
  private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
  private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.LocalStrings");
  private transient ServletConfig config;
  public void destroy()
  {
  }
  public String getInitParameter(String name)
  {
    ServletConfig sc = getServletConfig();
    if (sc == null) {
      throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
    }
    return sc.getInitParameter(name);
  }
  public Enumeration getInitParameterNames()
  {
    ServletConfig sc = getServletConfig();
    if (sc == null) {
      throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
    }
    return sc.getInitParameterNames();
  }
  public ServletConfig getServletConfig()
  {
    return this.config;
  }
  public ServletContext getServletContext()
  {
    ServletConfig sc = getServletConfig();
    if (sc == null) {
      throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
    }
    return sc.getServletContext();
  }
  public String getServletInfo()
  {
    return "";
  }
  public void init(ServletConfig config)
    throws ServletException
  {
    this.config = config;
    init();
  }
  public void init()
    throws ServletException
  {
  }
  public void log(String msg)
  {
    getServletContext().log(getServletName() + ": " + msg);
  }
  public void log(String message, Throwable t)
  {
    getServletContext().log(getServletName() + ": " + message, t);
  }
  public abstract void service(ServletRequest paramServletRequest, ServletResponse paramServletResponse)
    throws ServletException, IOException;
  public String getServletName()
  {
    ServletConfig sc = getServletConfig();
    if (sc == null) {
      throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
    }
    return sc.getServletName();
  }
}

Из отношения наследования и реализации GenericServlet в основном делает три вещи:
1. Реализовать интерфейс ServletConfig, чтобы мы могли напрямую вызывать методы в ServletConfig;
GenericServlet реализует ServletConfig и может напрямую вызывать методы в ServletConfig, когда это необходимо, без предварительного получения объекта ServletConfig; например, при получении ServletContext вы можете напрямую вызвать getServletContext, не вызывая getServletConfig(). внутренняя реализация по-прежнему вызывает getServletConfig().getServletContext() внутри.


2. Предоставляет метод инициализации без параметров
GenericServlet реализует метод инициализации сервлета (конфигурация ServletConfig), задает для параметра config его внутреннюю переменную config, а затем вызывает метод инициализации без параметров; этот метод может быть переопределен в подклассах для завершения инициализации.

К преимуществам такого подхода можно отнести следующее:
a.config устанавливается как внутренний атрибут, так что соответствующий метод Config может быть напрямую вызван в интерфейсном методе ServletConfig для выполнения;
б) Когда мы пишем Serlvet, нам больше не нужно заботиться о конфигурации, нам нужно только выполнить нашу собственную логику инициализации.
в) При переопределении метода инициализации нет необходимости вызывать super.init(config).
3. Предоставляет метод журнала
GenericServlet предоставляет два метода журнала: один для регистрации и один для регистрации исключений. Его конкретная реализация достигается через журнал, передаваемый в ServletConfig.
GenericServlet не зависит от протокола.

4.HttpServlet

HttpServlet — это базовый класс сервлета, основанный на протоколе Http.При написании сервлета вы можете напрямую наследовать HttpServlet без повторной реализации интерфейса сервлета.DispatcherServlet в SpringMvc является подклассом HttpServlet. HttpServlet связан с протоколом Http.HttpServlet обрабатывает запросы, в основном, переписывая метод службы родительского класса для выполнения конкретной обработки запроса. В сервисном методе ServletRequest и ServletResponse сначала преобразуются в HttpServletRequest и HttpServletResponse, а затем направляются в разные процессы обработки в соответствии с разными запросами [метод обработки — наш общий метод doXXX. Наиболее распространенными являются doGet и doPost]