Инициатива веб-грамотности Java

Java
Инициатива веб-грамотности Java

предисловие

На этот раз я поделюсь базовыми знаниями, связанными с Java Web, в основномservletчасть знаний. Задействовано много очков знаний.Если учащиеся опоздали, чтобы прочитать его, они могут сначала сохранить его, а затем медленно смотреть, когда у вас есть время! Теперь давайте перейдем к делу.

1. HTTP-протокол

  • 协议Это набор согласованных правил. Пока мы следуем правилам, мы можем хорошо общаться и сотрудничать.HTTPТо же самое относится и к протоколу.Протокол HTTP строго определяет формат данных HTTP-запроса и HTTP-ответа.Пока данные, которыми обмениваются HTTP-сервер и клиентская программа, соответствуют протоколу HTTP, обе стороны могут понять отправленные данные. другой стороной и общаться гладко.
  • HTTPСоглашение находится на应用层,УчредилTCP/IPна основании договора. Протокол HTTP использует надежныйTCPсоединение, порт по умолчанию80порт.

1.1 Формат ответа HTTP

Ответ HTTP также состоит из 3 частей:

  1. Версия, код состояния и описание протокола HTTP.
  2. Заголовок ответа.
  3. Содержание ответа.

Вот некоторые распространенные коды состояния:

  • 200:Указывает, что сервер успешно обработал запрос от клиента.
  • 400: Bad Request, клиент отправил неверный HTTP-запрос.
  • 404:файл не существует.
  • 405: сервер не поддерживает метод запроса клиента.
  • 500: Внутренняя ошибка сервера.

1.2 MIME-типы частей тела

Часть тела HTTP-запроса и ответа может быть данными в любом формате.Как убедиться, что получатель может понять данные, отправленные отправителем正文数据Шерстяная ткань? Протокол HTTP использует протокол MIME для стандартизации формата данных тела.

Типы данных, которые соответствуют протоколу MIME, вместе называются типами MIME. как в заголовках HTTP-запросов, так и в заголовках HTTP-ответовContent-Typeпункт для указания请求正文部分или响应正文Часть типа MIME. Нижние индексы перечисляют соответствие между распространенными типами MIME и расширениями файлов.

расширение файла MIME-тип
Неизвестный тип данных или нераспознанное расширение content/unknown
.bin, .exe, .o, .a, .z application/octet-stream
.pdf application/pdf
.zip application/zip
.tar application/x-tar
.gif image/gif
.jpg, .jpeg image/jpeg
.htm ,html text/html
.text .c .h .txt .java text/plain
.mpg .mpeg video/mpeg
.xml application/xml

2. Веб-сервер

Что такое веб-сервер?Web服务器Он создан разработчиками специализированных серверов для публикации и запуска веб-приложений. Как веб-сервер может динамически выполнять программный код в веб-приложении, созданном третьей стороной? Итак, нам нужен中介方формулироватьWeb应用а такжеWeb 服务器стандартный интерфейс для совместной работы,ServletЭто один из самых важных интерфейсов. Посредник оговаривает:

  • Веб-сервер может получить доступ к любому классу в веб-приложении, реализующем интерфейс сервлета.
  • Программный код, используемый в веб-приложении для динамического вызова веб-сервером, находится в классе реализации интерфейса сервлета.

3B49D892-27A6-4C31-AA06-066C45CF2BA3

Спецификация сервлета дает возможность публиковать и запускатьJavaWebПрименяемыйWeb服务器называетсяServlet 容器, его главная особенность — динамическое выполнение программного кода в классе реализации JavaWeb. Распространенными контейнерами сервлетов являются Tomcat, Jetty, WebLogic, WebSphere, JBoss и т. д.

2.1 Сервер Tomcat

Базовая функциональность Tomcat как контейнера сервлетовКак показано ниже,TomcatОсновные функции контейнера для запуска сервлетов:负责接收和解析来自客户的请求, и одновременно передать запрос клиента в соответствующийServletи поместите сервлет响应结果возвращен клиенту.

B5915359-62D4-4A78-AC89-C6DEBA70980D

Процесс доступа контейнера сервлетов к определенному сервлету в ответ на запрос клиента выглядит следующим образом:

  1. Клиент отправляет запрос на доступ к определенному сервлету.
  2. Контейнер сервлета получает запрос клиента и анализирует его.
  3. Контейнер сервлета создает объект ServletRequest, который содержит информацию о клиентском запросе и другую информацию о клиенте, такую ​​как заголовки запроса, тело запроса и IP-адрес клиента.
  4. Контейнер сервлета создает объект ServletResponse.
  5. Контейнер сервлета вызывает сервисный метод service() сервлета, запрошенного клиентом, и передает объект ServletRequest и объект ServletResponse в качестве параметров сервисному методу.
  6. Сервлет может получить информацию о запросе клиента из объекта ServletRequest.
  7. Сервлеты используют объект ServletResponse для генерации результатов ответа.
  8. Контейнер сервлета отправляет ответ, сгенерированный сервлетом, клиенту.
    C566E1C3-8F21-48F2-95AC-5E811A2AA3DF

3. Веб-приложение Java

Для того чтобы контейнер сервлетов мог беспрепятственно находить различные компоненты в приложении JavaWeb, спецификация сервлета предусматривает, что приложение JavaWeb должно иметь фиксированную структуру каталогов. Спецификация сервлета также предусматривает, что информация о конфигурации веб-приложений Java хранится в файле WEB-INF/web.xml, а контейнер сервлета считывает информацию о конфигурации из этого файла.

3.1 Структура каталогов веб-приложений Java

Предполагая, что разработано веб-приложение Java с именем helloapp, сначала необходимо создать структуру каталогов этого веб-приложения, как показано в следующей таблице:

содержание описывать
/helloapp Корневой каталог веб-приложения.
/helloapp/WEB-INF Файл конфигурации web.xml, в котором хранится веб-приложение.
/helloapp/WEB-INF/classes Храните различные файлы .class, и файлы .class классов сервлетов также размещаются в этом каталоге.
/helloapp/WEB-INF/lib Хранит различные файлы JAR, необходимые веб-приложениям. Например, файл JAR для драйвера JDBC.

Видно, что контейнеру сервлета все равно, где находится ваш исходный код, он заботится только о файле .class, потому что для загрузки класса нужно использовать только файл .class. Файлы классов Java можно хранить в подкаталогах классов и lib каталога WEB-INF. Во время выполнения загрузчик классов контейнера сервлета сначала загружает классы в каталог классов, а затем загружает классы в файл JAR (упакованный файл библиотеки классов Java) в каталог lib. Поэтому, если класс с одинаковым именем существует в двух каталогах, класс в каталоге классов имеет приоритет.

4. Технология сервлетов

Большой парень, наконец, вышел, все аплодировали! В этом разделе в основном представлены "артефакты", которые часто используются в сервлетах.

4.1 Общие объекты сервлета

  • 请求对象(ServletRequest и HttpServletRequest): сервлет получает информацию запроса от клиента из этого объекта.
  • 响应对象(ServletResponse и HttpServletResponse): сервлет использует этот объект для генерации результата ответа.
  • Servlet配置对象(ServletConfig): Когда контейнер инициализирует объект Servlet, он предоставляет сервлету объект ServletConfig, через который сервлет получает информацию о параметрах инициализации и объект ServletContext.
  • Servlet上下文对象(ServletContext): сервлет использует этот объект для доступа к различным ресурсам, предоставляемым контейнером для текущего веб-приложения.

4.2 Servlet API

API Servlet в основном состоит из двух пакетов Java:javax.servletа такжеjavax.servlet.http.

  • javax.servlet: интерфейс сервлета и связанные с ним общие интерфейсы и классы определены в пакете;
  • javax.servlet.httpПакет в основном определяет класс HTTPServlet, интерфейс HTTPServletRequest и интерфейс HTTPServletResponse, связанные с протоколом HTTP.

4.3 Интерфейс сервлета

Ядром API сервлетов являетсяjavax.servlet.Servletинтерфейс, который должны реализовать все классы сервлетов. В интерфейсе сервлета определены пять методов, три из которых вызываются контейнером сервлета, и контейнер будет вызывать определенные методы на разных этапах жизненного цикла сервлета.

  • init(ServletConfig config): отвечает за инициализацию объекта сервлета. Этот метод вызывается после того, как контейнер создал объект сервлета.
  • service(ServletRequest req, ServletResponse res): отвечает за реагирование на запросы клиентов и предоставление соответствующих услуг клиентам. Когда контейнер получает запрос клиента на доступ к определенному объекту сервлета, вызывается метод service() этого объекта сервлета.
  • destroy(): Отвечает за освобождение ресурсов, занятых объектом Servlet. Контейнер вызывает этот метод, когда объект сервлета завершает свой жизненный цикл.

Интерфейс сервлета также определяет следующие два метода, которые возвращают информацию о сервлете. Программный код в веб-приложении Java может получить доступ к этим двум методам сервлета для получения информации о конфигурации и другой связанной информации о сервлете.

  • getServletConfig(): возвращает объект ServletConfig, который содержит информацию о параметрах инициализации сервлета.
  • getServletInfo(): возвращает строку, содержащую такую ​​информацию, как создатель, версия и авторские права сервлета.

В API сервлетовjava.servlet.GenericServletАбстрактный класс реализует интерфейс сервлета, аjavax.servlet.http.HttpServletабстрактный классGenericServletПодкласс класса. Когда пользователи разрабатывают свои собственные классы сервлетов, они могут расширитьGenericServletкласс илиHTTPServletДобрый.

4.4 Абстрактный класс GenericServlet

GenericServletАбстрактный класс обеспечивает общую реализацию интерфейса Servlet, которая совместима с любым网络应用层协议无关. В дополнение к реализации интерфейса Servlet класс GenericServlet также реализует интерфейс ServletConfig и интерфейс Serializable.

Как видно из исходного кода класса GenericServlet, класс GenericServlet реализует интерфейс Servletinit(ServletConfig config)метод инициализации.GenericServletкласс имеетServletConfig 类型的私有实例变量config,когдаSevlet容器перечислитьGenericServletизinit(ServletConfig config)метод, метод создает приватную переменную экземпляраconfigЦитируется容器传入ServletConfig, то есть для связывания объекта GenericServlet с объектом ServletConfig.

public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }

Класс GenericServlet также настраивает метод init() без параметров,init(ServletConfig config)метод вызывает этот метод. Для подклассов класса GenericServlet, если вы хотите переопределить поведение инициализации родительского класса, есть два способа:

  1. Переопределите метод init() родительского класса без аргументов:
public void init(){ 
// 子类具体的初始化行为 
} 
  1. Переопределить параметризованный родительский классinit(ServletConfig config)метод. Если вы хотите, чтобы текущий объект Servlet был связан с объектом ServletConfig, вы должны теперь вызвать метод super.init(config) в этом методе:
public void init(ServletConfig config){ 
  // 调用父类的init(config)方法 
  super.init(config);
  // 子类具体的初始化行为 
} 

Класс GenericServlet не реализует метод service() в интерфейсе Servlet. Метод service() является единственным абстрактным методом в классе GenericServlet, и конкретные подклассы класса GenericServlet должны реализовывать этот метод, чтобы предоставлять определенные услуги для конкретных клиентских запросов.

Кроме того, класс GenericServlet реализует все методы интерфейса ServletConfig. Следовательно, подклассы класса GenericServlet могут напрямую вызывать методы getServletContext(), getInitParameter() и getInitParameterNames(), определенные в интерфейсе ServletConfig.

Класс GenericServlet реализует интерфейс Servlet и интерфейс ServletConfig. Первичным идентификатором класса GenericServlet является сервлет, кроме того, он использует装饰设计模式, который присоединяется к декорированному идентификатору ServletConfig. В конкретной реализации класс GenericServlet является оболочкой для экземпляра интерфейса ServletConfig, через который реализуются методы интерфейса ServletConfig.

4.5 Абстрактный класс HttpServlet

Класс HttpServlet является подклассом класса GenericServlet. Класс HttpServlet предоставляет интерфейс сервлета сHTTP协议Соответствующая общая реализация, то есть объект HttpServlet, подходит для работы в контейнере сервлетов или на веб-сервере, где клиент взаимодействует с использованием протокола HTTP. При разработке веб-приложений Java пользовательские классы сервлетов обычно расширяют класс HttpServlet.

Протокол HTTP делит клиентские запросы на методы GET, POST, PUT и DELETE. Класс HttpServlet предоставляет соответствующие служебные методы для каждого метода запроса, такие как doGet(), doPost(), doPut и doDelete().

Как видно из исходного кода HttpServlet, класс HttpServlet реализует метод service(ServletRequest req,ServletResponse res) в интерфейсе Servlet, который фактически вызывает свой перегруженный метод:

service(HttpServletRequest req, HttpServletResponse resp)

В приведенном выше перегруженном методе service() сначала вызовите параметр req типа HttpServletRequest.getMethod()чтобы получить метод запроса клиента, а затем вызвать соответствующий метод службы в соответствии с методом запроса. Если это метод GET, вызовите метод doGet(); если это метод POST, вызовите метод doPost() и так далее.

4.6 Интерфейс запроса сервлета

в интерфейсе сервлетаservice(ServletRequest req, ServletResponse res)Метод имеет параметр типа ServletRequest. Класс ServletRequest представляет запрос от клиента. Когда контейнер сервлета получает запрос клиента на доступ к определенному сервлету,容器先解析客户端的原始请求数据,把它包装成一个ServletRequest 对象. Когда контейнер вызывает метод service() объекта сервлета, он может передать объект ServletRequest в качестве параметра методу service().

Интерфейс ServletRequest предоставляет ряд методов для чтения данных запроса клиента:

  • getContentLength(): возвращает длину тела запроса. Возвращает -1, если длина тела запроса неизвестна.

  • getContentType(): получить MIME-тип тела запроса. Возвращает null, если тип тела запроса неизвестен.

  • getInputStream(): возвращает входной поток, используемый для чтения тела запроса.

  • getParameter(String name): возвращает соответствующее значение параметра запроса из запроса клиента на основе заданного имени параметра запроса.

  • getReader(): возвращает объект BufferedReader для чтения тела запроса в виде строки. так далее

Кроме того, в интерфейсе ServletRequest определен набор методов для доступа к общим данным в рамках запроса:

  • getAttribute(String name,Object object): Сохраните атрибут в области запроса, имя параметра указывает имя атрибута, а объект параметра указывает значение атрибута.

  • getAttribute(String name): возвращает соответствующее значение атрибута в области запроса в соответствии с именем атрибута, заданным параметром имени.

  • removeAttribute(String name): удаляет атрибут из области запроса.

4.7 Интерфейс HttpServletRequest

Интерфейс HttpServletRequest является подинтерфейсом интерфейса ServletRequest. Перегруженный метод service() класса HttpServlet и такие методы, как doGet() и doPost(), имеют параметр типа HttpServletRequest.

Интерфейс HttpServletRequest предоставляет методы для чтения соответствующей информации в HTTP-запросе:

  • getContextPath(): возвращает запись URL-адреса веб-приложения, запрошенного клиентом. Например, URL-адрес, к которому обращается клиент,http://localhost:8080/helloapp/info, то метод возвращает "/helloapp"

  • getCookies(): возвращает все файлы cookie в HTTP-запросе.

  • getHeader(String name): возвращает определенный элемент в заголовке HTTP-запроса.

  • getHeaderNames(): возвращает объект Enumeration, содержащий все имена элементов в заголовке HTTP-запроса.

  • getMethod(): возвращает метод HTTP-запроса.

  • getRequestURI(): возвращает URI в первой строке заголовка HTTP-запроса.

  • getQueryString(): возвращает строку запроса в HTTP-запросе, т.е. в URL-адресе?содержание позади.

4.8 Интерфейс ServletResponse

в интерфейсе сервлетаservice(ServletRequest req, ServletResponse res)Метод имеет параметр типа ServletResponse. Сервлеты генерируют результаты ответа через объект ServletResponse. Когда контейнер сервлета получает запрос клиента на доступ к определенному сервлету, контейнер создает объект ServletResponse и передает его в качестве параметра методу service() сервлета.

Ряд методов, связанных с генерацией результата ответа, определен в интерфейсе ServletResponse.

  • getOutputStream(): возвращает объект ServletOutputStream, который сервлет использует для вывода двоичных текстовых данных.

  • getWriter(): возвращает объект PrintWriter, который сервлет использует для вывода текстовых данных, таких как строки.

ServletResponseТип MIME по умолчанию для тела ответа вtext/plain, который является обычным текстовым типом. а такжеHttpServletResponseТип MIME по умолчанию для тела ответа вtext/html, тип документа HTML.

Чтобы повысить эффективность вывода данных, ServletOutputStream и PrintWriter сначала записывают данные в буфер. Когда данные в буфере передаются клиенту, метод isCommitted() ServletResponse возвращает значение true. В следующих случаях данные в буфере будут переданы клиенту, то есть данные будут отправлены клиенту:

  • Когда данные в буфере已满, ServletOutputStream или PrintWriter автоматически отправит данные из буфера клиенту и очистит буфер.

  • Вызов сервлетаServletResponseобъектflushBuffer()метод.

  • Вызов сервлетаServletOutputStreamилиPrintWriterобъектflush()метод илиclose()метод.

Чтобы гарантировать, что все данные, выводимые ServletOutputStream или PrintWriter, будут отправлены клиенту, безопаснее вызывать ServletOutputStream или PrintWriter после вывода всех данных.close()метод.

В реализации Tomcat, если метод service() сервлета не вызывает метод ServletOutputStream или метод close() PrintWriter, тогдаTomcatПосле вызова метода service() сервлета будет关闭ServletOutputStream или PrintWriter, что обеспечивает отправку клиенту всех данных, выводимых сервлетом.

Стоит отметить, что если вы хотите установить тип MIME и кодировку символов тела ответа, вы должны先调用Объект ServletResponsesetContentType()а такжеsetCharacterEncoding()метод, то再调用Метод ServletResponse getOutputStream() или getWriter() или отправьте данные тела в буфер. Настройки могут вступить в силу только при соблюдении этой последовательности операций.

4.9 Интерфейс HttpServletResponse

Интерфейс HttpServletResponse является подинтерфейсом ServletResponse.Перегруженный метод service() класса HttpServlet и такие методы, как doGet и doPost(), имеют параметр типа HttpServletResponse.

Интерфейс HttpServletResponse предоставляет некоторые методы, связанные с протоколом HTTP, с помощью которых сервлеты могут устанавливать заголовки ответа HTTP или записывать файлы cookie для клиентов.

  • addHeader(String name,String value): Добавляет элемент в заголовок ответа HTTP.

  • setHeader(String name,String msg): устанавливает элемент в заголовке ответа HTTP. Если это содержимое уже существует в заголовке ответа, исходная настройка будет перезаписана.

  • sendError(int sc): отправляет клиенту код состояния ответа HTTP, представляющий конкретную ошибку.

  • sendError(int sc,String msg): отправляет клиенту код состояния ответа HTTP, представляющий конкретную ошибку, вместе с конкретным сообщением об ошибке.

  • setStatus(int sc): Установите код состояния ответа HTTP.

  • addCookie(Cookie cookie): добавить файл cookie в ответ HTTP.

Следующие три способа могут установить тип MIME и кодировку символов тела ответа HTTP:

// 方式一 
response.setContentType(“text/html;charset=utf-8”); 
// 方式二 
response.setContentType(“text/html”); 
response.setCharacterEncoding(“utf-8”); 
// 方式三 
response.setHeader(“Content-type”,”text/html;charset=utf-8”); 

4.10 Интерфейс ServletConfig

Интерфейс сервлетаinit(ServletConfig congfig)Метод имеет параметр типа ServletConfig. Когда контейнер сервлета инициализирует объект сервлета, он создает объект ServletConfig для объекта сервлета. существуетServletConfigОбъект содержит сервлет初始化参数信息, кроме того, объект ServletConfig также связан с объектом ServletContext текущего веб-приложения.

Следующие методы определены в интерфейсе ServletConfig.

  • getInitParameter(String name): возвращает соответствующее значение параметра инициализации в соответствии с заданным именем параметра инициализации.

  • getInitParameterNames(): возвращает объект Enumeration, содержащий все имена параметров инициализации.

  • getServletContext(): возвращает объект ServletContext.

Каждый параметр инициализации состоит из пары имени параметра и значения параметра. При настройке сервлета в файле web.xml можно задать параметры инициализации через элемент. Дочерние элементы элемента задают имя параметра, а дочерние элементы задают значение параметра.

Класс HttpServlet наследует класс GenericServlet, а GenericServlet реализует интерфейс ServletConfig, поэтому методы интерфейса ServletConfig можно вызывать непосредственно в классе HttpServlet или GenericServlet и его подклассах.

4.11 Интерфейс ServletContext

ServletContextдаServletа такжеServlet 容器между直接通信Интерфейс. Когда контейнер сервлета запускает веб-приложение, он создает для него объект ServletContext. Каждое веб-приложение имеет唯一Объект ServletContext вы можете поместитьServletContextОбъект отчетливо понимается как генеральный менеджер веб-приложения,同一个Web应用中的所有Servlet对象都共享一个总管家(Стучите по доске, все объекты сервлетов имеют общий объект ServletContext), объекты сервлетов могут получать доступ к различным ресурсам в контейнере через этот менеджер.

Контейнер сервлета находится в启动一个Web应用时, создаст для него唯一объект ServletContext. Когда контейнер сервлета завершает работу веб-приложения, он уничтожает его объект ServletContext. Видно, что объект ServletContext и веб-приложение имеют相同的生命周期.

Ниже показано несколько методов, часто используемых интерфейсом ServletContext:

  1. используется дляWeb应用范围内доступ共享数据Методы.

    • setAttribute(String name,Object object): связывает объект Java с именем атрибута и сохраняет его в ServletContext.

    • getAttribute(String name): возвращает объект типа Object в соответствии с именем атрибута, заданным параметром, который представляет значение атрибута, совпадающее с именем атрибута в ServletContext.

    • getAttributeNames(): возвращает объект перечисления, содержащий все имена атрибутов, хранящиеся в ServletContext.

    • removeAttribute(String name): Удаляет соответствующий атрибут из ServletContext в соответствии с именем атрибута, указанным в параметре.

  2. Доступ к ресурсам текущего веб-приложения.

    • getContextPath(): возвращает запись URL-адреса текущего веб-приложения.

    • getInitParameter(String name): возвращает соответствующее значение параметра инициализации в рамках веб-приложения в соответствии с заданным именем параметра. В файле web.xml элементы, определенные непосредственно под корневым элементом, представляют собой параметры инициализации всего приложения.

    • getInitParameterNames(): возвращает объект перечисления, содержащий имена всех параметров инициализации в рамках веб-приложения.

    • getServletContextName(): возвращает имя веб-приложения, которое является значением элемента в файле web.xml.

    • getRequestDispatcher(String path): возвращает объект RequestDispatcher, который используется для пересылки запросов другим веб-компонентам.

Метод getServletContext() определен в интерфейсе ServletConfig. Класс HttpServlet наследует класс GenericServlet, а класс GenericServlet реализует интерфейс ServletConfig, поэтому метод getServletContext() можно вызывать непосредственно в классе HttpServlet или классе GenericServlet и его подклассах для получения объекта ServletContext текущего веб-приложения.

5. Жизненный цикл веб-приложения Java

Жизненный цикл веб-приложения Java контролируется контейнером сервлетов. Подводя итог, жизненный цикл веб-приложения Java состоит из 3 фаз.

  • Фаза запуска: загрузите соответствующие данные веб-приложения, создайте объект ServletContext и инициализируйте фильтр и некоторые сервлеты.

  • Этап выполнения: обслуживание клиентов.

  • Фаза завершения: освободить различные ресурсы, занятые веб-приложением.

5.1 Фаза запуска

Когда контейнер сервлета запускает веб-приложение Java, он делает следующее:

  1. Пучокweb.xmlДанные в файле загружаются в память.

  2. Создайте веб-приложение JavaServletContextобъект.

  3. всеFilterдля инициализации.

  4. Для тех, кому необходимо использовать веб-приложение启动时就被初始化изServletдля инициализации.

5.2 Этап выполнения

Это самый важный этап жизни веб-приложения Java. На данном этапе все его сервлеты находятся в режиме ожидания, готовые реагировать на конкретные запросы клиентов и предоставлять соответствующие услуги. Сервлет, добавленный в клиентский запрос, еще не существует, контейнер сервлетов сначала инициализирует сервлет, а затем вызывает его службу service().

5.3 Фаза завершения

Когда контейнер сервлета завершает работу веб-приложения Java, он делает следующее:

  1. Уничтожает все сервлеты в состоянии выполнения в веб-приложении Java.

  2. Уничтожает все фильтры в состоянии выполнения в веб-приложении Java.

  3. Уничтожьте все объекты, связанные с веб-приложением Java, такие как объект ServletContext и т. д., и освободите соответствующие ресурсы, занятые веб-приложением.

6. Жизненный цикл сервлета

Жизненный цикл веб-приложения Java контролируется контейнером сервлетов, и, как основной компонент веб-приложения Java, жизненный цикл сервлета также контролируется контейнером сервлетов. Жизненный цикл сервлета можно разделить на три фазы: фаза инициализации, фаза выполнения и фаза уничтожения. В интерфейсе javax.servlet.servlet определены три метода: init(), service() и destroy(), которые будут вызываться контейнером сервлета на разных этапах сервлета.

6.1 Фаза инициализации

Фаза инициализации сервлета состоит из 4 шагов:

  1. Контейнер сервлета загружает класс сервлета и считывает данные из его файла .class в память.

  2. Контейнер сервлета создает объект ServletConfig.ServletConfigобъект содержит特定Сервлет初始化配置信息, такие как параметры инициализации сервлета. Кроме того, контейнер сервлета создаст объект ServletConfig и текущее веб-приложение.ServletContextобъект关联.

  3. Контейнер сервлета создает объекты сервлета.

  4. Контейнер сервлета вызывает метод init(ServletConfig config) объекта сервлета.

Приведенные выше шаги инициализации создают объект Servlet и объект ServletConfig, а объект Servlet связывается с объектом ServletConfig, который, в свою очередь, связывается с объектом ServletContext текущего веб-приложения. После того, как контейнер сервлета завершит инициализацию сервлета, объект сервлета может получить объект servletContext текущего веб-приложения только с помощью метода getServletContext().

В одной из следующих ситуаций сервлет войдет в фазу инициализации.

  1. Текущее веб-приложение находится в стадии выполнения, и клиент обращается к определенному сервлету впервые. В этом случае большинство сервлетов будет инициализировано контейнером сервлетов.

  2. Если элемент установлен для сервлета в файле web.xml, сервлет будет инициализирован, когда контейнер сервлета запустит веб-приложение, которому принадлежит сервлет. Если значения Servlet1 и Servlet2 равны 1 и 2 соответственно, поэтому, когда контейнер сервлета запускает текущее веб-приложение, Servlet1 инициализируется первым, а Servlet2 инициализируется вторым. Сервлет без элемента конфигурации не будет инициализирован, когда контейнер сервлета запустит текущее веб-приложение, он будет инициализирован только тогда, когда клиент запрашивает доступ к сервлету в первый раз.

  3. При перезапуске веб-приложения все сервлеты в веб-приложении будут повторно инициализированы в определенное время.

6.2 Этап выполнения

Это самая важная фаза в цикле объявления сервлета. На этом этапе сервлет может в любой момент ответить на запрос клиента. Когда контейнер сервлета получает запрос клиента на доступ к определенному сервлету, контейнер сервлета создает объект ServletRequest и объект ServletResponse для запроса, а затем вызывает метод service() соответствующего объекта сервлета. Метод service() получает информацию о клиентском запросе из объекта ServletRequest, обрабатывает запрос и генерирует результат ответа через объект ServletResponse.

Когда контейнер сервлета помещает сгенерированный сервлет响应结果发送предоставленный клиенту, контейнер сервлета будет销毁Объект ServletRequest и объект ServletResponse.

6.3 Фаза разрушения

当Web应用被终止时, контейнер сервлета сначала вызовет веб-приложение所有Servletобъектdestroy()метод, то再销毁Эти объекты сервлета. При реализации метода destroy() ресурсы, занятые сервлетом, могут быть освобождены.

Кроме того, контейнер также разрушаетServletConfigобъект.

7. Использование слушателя ServletContextListener

В Servlet API естьServletContextListenerИнтерфейс, который может отслеживать жизненный цикл объекта ServletContext, на самом деле отслеживает жизненный цикл веб-приложения.

Когда контейнер сервлета запускает или завершает работу веб-приложения, он может прослушивать событие ServletContextEvent, которое обрабатывается ServletContextListener. В интерфейсе ServletContextListener определены два метода обработки событий ServletContextEvent.

  • contextInitialized(ServletContextEvent sec): когда контейнер сервлета启动Этот метод вызывается при использовании веб-приложения. После вызова этого метода之后, контейнер повторно выравниваетсяFilter初始化и инициализировать те сервлеты, которые необходимо инициализировать при запуске веб-приложения.

  • contextDestroyed(ServletContextEvent sec): когда контейнер сервлета终止Веб-приложение вызывает этот метод. вызов этого метода之前, сначала контейнер销毁всеServletа такжеFilterфильтр.

Можно видеть, что в жизненном цикле веб-приложения объект ServletContext создается в самом начале и уничтожается в самое позднее.

Определяемый пользователем прослушиватель ServletContextListener должен быть сначала зарегистрирован в контейнере сервлета, и контейнер сервлета будет вызывать соответствующие методы прослушивателя при запуске или завершении веб-приложения. В файле web.xml этот элемент используется для регистрации слушателя в контейнере.

<listener> 
<listener-class>LinstnerClass</listener-class>
</listener> 

8. Cookie

Первоначальное значение Cookie на английском языке — «дим-сам», то есть когда клиент обращается к веб-серверу,服务器существует客户端硬盘上存放的信息. когда клиент首次При доступе к серверу сервер теперь сохраняет файл cookie, содержащий соответствующую информацию о клиенте на стороне клиента.В будущем каждый раз, когда клиент запрашивает доступ к серверу, файл cookie будет включаться в данные HTTP-запроса.Сервер анализирует cookie в HTTP-запросе для получения информации о пользователе.

Механизм работы файлов cookie определяется протоколом HTTP, и большинство веб-серверов и браузеров поддерживают файлы cookie. Для поддержки файлов cookie веб-сервер должен иметь следующие функции.

  • Добавьте данные cookie в результат ответа HTTP.

  • Анализировать данные cookie в HTTP-запросах.

Для поддержки файлов cookie браузеры должны иметь следующие функции.

  • Проанализируйте данные cookie в результате ответа HTTP.

  • Сохраните данные cookie на локальный жесткий диск. Прочитайте данные cookie на локальном жестком диске и добавьте их в HTTP-запрос.

Как веб-сервер, Tomcat обеспечивает хорошую поддержку файлов cookie. Итак, как сервлет, работающий в Tomcat, получает доступ к файлам cookie? Java Servlet API предоставляет простой и удобный интерфейс для доступа сервлетов к файлам cookie.javax.servlet.http.CookieКласс для представления, каждый объект Cookie содержит имя файла cookie и значение файла cookie.

Следующий код создает объект Cookie, а затем вызывает функцию HttpServletResponse.addCookie()метод добавления файла cookie в результат ответа HTTP:

Cookie theCookie = new Cookie(“username”,”Tom”); 
response.addCookie(theCookie); 

Если сервлет хочет прочитать файлы cookie от клиента, он может получить все файлы cookie из HTTP-запроса следующим образом:

Cookie[] cookies = request.getCookies(); 

Для каждого объекта Cookie, вызываемогоgetName()метод, чтобы получить имя файла cookie, вызовитеgetValue()метод для получения значения файла cookie.

Когда сервлет записывает файл cookie клиенту, он также может использовать класс Cookie.setMaxAge(int expiry)метод для установки даты истечения срока действия файла cookie. Срок действия параметра указывается в секундах и имеет следующие значения:

  • Если срок действия больше нуля, он указывает браузеру сохранить файл cookie на жестком диске клиента в течение нескольких секунд.В течение срока действия другие браузеры также могут получить доступ к файлу cookie.

  • Если срок действия равен нулю, браузер получает указание удалить текущий файл cookie.

  • Если срок действия меньше нуля, указывает браузеру не сохранять файл cookie на жестком диске клиента. Файлы cookie существуют только в текущем процессе браузера. Когда процесс браузера закрывается, файл cookie исчезает.

Срок действия файлов cookie по умолчанию составляет -1.

Сервер считывает и записывает операции с файлами cookie для клиента, что создает угрозу безопасности для клиента. Сервер может отправлять клиенту данные cookie, содержащие вредоносный код, кроме того, сервер может украсть конфиденциальную информацию пользователя на основе файла cookie клиента. Поэтому из соображений безопасности большинство браузеров могут разрешить или запретить использование файлов cookie.

9. Session

Когда клиент обращается к веб-приложению, во многих случаях веб-сервер должен иметь возможность отслеживать состояние клиента.

Обычно веб-сервер может отслеживать статус пользователя четырьмя способами:

  • Включите скрытые поля в HTML-формы, содержащие данные, используемые для отслеживания статуса пользователя.

  • Перепишите URL-адрес, чтобы включить данные, используемые для отслеживания статуса клиента.

  • Файлы cookie используются для передачи данных, используемых для отслеживания статуса клиента.

  • Используйте механизм сеанса (Session).

9.1 Введение в сессию

HTTP — это протокол без сохранения состояния. В мире веб-разработки механизм сеанса является распространенным решением для отслеживания состояния клиента. Сеанс относится к серии связанных взаимодействий между одним клиентом и веб-приложением в течение определенного периода времени. В сеансе клиент может запросить доступ к одной и той же веб-странице веб-приложения несколько раз, а также может запросить доступ к нескольким веб-страницам в одном и том же веб-приложении.

Спецификация сервлета определяет конкретный механизм работы сеансов на основе Java. Определенный в Servlet API представляет сеансjavax.servlet.http.HttpSessionинтерфейс, контейнер сервлета должен реализовать этот интерфейс. Когда сеанс начинается, контейнер сервлета создает объект HttpSession, в котором может храниться информация, представляющая состояние клиента. Контейнер сервлета присваивает каждому объекту HttpSession уникальный идентификатор, знаковый битSession ID.

key: клиентский файл cookie отвечает только за хранение идентификатора сеанса, а объект сеанса хранится на сервере.

Ниже в качестве примера используется приложение с именем bookstore, чтобы представить процесс работы сеанса:

  1. В первый раз, когда браузер обрабатывает запрос на посещение любой веб-страницы в приложении книжного магазина, которое поддерживает сеансы, контейнер сервлета пытается найти файл cookie, представляющий идентификатор сеанса в HTTP-запросе.Поскольку такого файла cookie еще нет, считается, что новый сеанс запущен. , затем создайте объект HttpSession, назначьте ему уникальный идентификатор сеанса, а затем добавьте идентификатор сеанса в виде файла cookie к результату ответа HTTP. Когда браузер получает ответ HTTP, он сохраняет файл cookie, представляющий идентификатор сеанса на клиенте.

  2. Процесс браузера продолжает запрашивать доступ к любой веб-странице в приложении книжного магазина, которое поддерживает сеансы, и этот HTTP-запрос будет включать файл cookie, представляющий идентификатор сеанса. Контейнер сервлета пытается найти файл cookie, представляющий идентификатор сеанса в HTTP-запросе, поскольку такой файл cookie доступен. Поэтому считается, что этот запрос уже находится в сеансе, и сервлет-контейнер уже не создает новый объект HttpSession, а получает Session ID из файла cookie, а затем находит соответствующий объект HttpSession в памяти по Session ID.

  3. Процесс браузера повторяет шаг 2 до тех пор, пока текущий сеанс не будет уничтожен, а объект HttpSession завершит свой жизненный цикл.

Срок действия файла cookie, представляющего идентификатор сеанса, равен -1, что означает, что файл cookie исчезнет, ​​а сеанс завершится. Значение явного идентификатора сеанса различается в двух процессах браузера, поскольку два процесса браузера соответствуют разным сеансам, а каждый сеанс имеет уникальный идентификатор сеанса.

9.2 Жизненный цикл HttpSession и область действия сеанса

Область сеанса относится к процессу сеанса между браузером и веб-приложением. С точки зрения конкретной реализации область сеанса соответствует жизненному циклу объекта HttpSession. Таким образом, веб-компоненты могут совместно использовать общие данные на уровне сеанса, если они совместно используют один и тот же объект HttpSession.

Методы интерфейса HttpSession описаны в следующей таблице, и компоненты JSP или Servlet в веб-приложении могут получить доступ к сеансу с помощью этих методов.

метод описывать
getId() Возвращает идентификатор сеанса.
invalidate() Уничтожив текущую сессию, контейнер сервлета освободит ресурсы, занятые объектом HttpSession.
setAttribute(String name, Object value) Сохраните пару свойств имя/значение в объекте HttpSession.
getAttribute(String name) Возвращает значение атрибута, хранящееся в объекте HttpSession, в соответствии с параметром имени.
getAttributeNames() Возвращает все имена свойств в объекте HttpSession в виде массива.
removeAttribute(String name) Удаляет указанное свойство параметра имени из объекта HttpSession.
isNew() Определите, является ли это вновь созданным сеансом
setMaxInactiveInterval(int interval) Устанавливает максимальное время в секундах, в течение которого сеанс может быть неактивным. Если это время превышено, контейнер сервлета автоматически уничтожит сеанс. Если для параметра interval задано отрицательное число, это означает, что время неактивности сессии не ограничено, то есть сессия никогда не истечет. Tomcat устанавливает максимальный период бездействия по умолчанию в 1800 секунд для сеанса.
getMaxInactiveInterval() Прочитайте максимальное время, в течение которого текущий сеанс может быть неактивным.

Новый сеанс запускается, когда контейнер сервлета создает новый объект HttpSession:

  • Процесс браузера сначала обращается к любой веб-странице в веб-приложении, которое поддерживает сеанс.

  • После того, как сеанс между процессом браузера и веб-приложением был уничтожен, процесс браузера снова обращается к любой веб-странице в веб-приложении, которое поддерживает сеанс.

Сеанс уничтожается, когда контейнер сервлета завершает жизненный цикл объекта HttpSession, и общие данные, хранящиеся в области сеанса, также уничтожаются:

  • Процесс браузера завершен.

  • На стороне сервера выполняется метод invalidate() объекта HttpSession.

  • Срок действия сеанса истек.

Когда веб-приложение в Tomcat завершается, его сеансы не уничтожаются, а сохраняются в постоянном хранилище Tomcat.При перезапуске веб-приложения Tomcat перезагружает эти сеансы.

Когда начинается сеанс, если процесс браузера внезапно закрывается, сторона контейнера сервлета не может сразу узнать, что процесс браузера был закрыт, поэтому объект HttpSession на стороне контейнера сервлета не завершит свой жизненный цикл немедленно. Однако, когда процесс браузера закрывается, сеанс переходит в неактивное состояние и ожидает болееsetMaxInactiveInterval(int interval)Время, установленное методом, сессия будет уничтожена контейнером сервлета из-за истечения срока действия.

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

9.3 Получить сеанс

Объект HttpSession можно получить через объект HttpServletRequest.

В интерфейсе HttpServletRequest предусмотрено два метода, связанных с сеансом:

  • getSession(): Да, текущий HttpServlet поддерживает сеансы. Если сеанс уже существует, верните соответствующий объект HttpSession, в противном случае создайте новый сеанс и верните только что созданный объект HttpSession. Этот метод эквивалентен вызову HttpServletRequest.getSession(true)метод.

  • getSession(boolean create): если параметр createtrue, что эквивалентно вызову метода getSession() HttpServletRequest; если параметр create имеет значение false , то, если сеанс уже существует, он возвращает объект HttpSession ответа, в противном случае он возвращает null.

key: распространенное заблуждение состоит в том, что сеанс создается, когда к нему обращается клиент, но на самом деле он не создается до тех пор, пока серверная программа не вызовет такой оператор, как HttpServletRequest.getSession(true).

10. Разница между сеансом и файлом cookie

  1. Данные cookie хранятся в браузере клиента, а данные сеанса хранятся на сервере.

  2. Файлы cookie не очень безопасны. Другие могут анализировать файлы cookie, хранящиеся локально, и выполнять подделку файлов cookie. Учитывая безопасность, следует использовать сеанс.

  3. Сессия будет сохранена на сервере в течение определенного периода времени. Когда количество посещений увеличится, это поднимет производительность вашего сервера.Чтобы снизить производительность сервера, вы должны использовать файлы cookie.

  4. Данные, сохраняемые одним файлом cookie, не могут превышать 4 КБ, и многие браузеры ограничивают сайт сохранением не более 20 файлов cookie.

11. Переадресация запроса

Переадресация может пересылать запросы компонентам того же веб-приложения.

// 把请求转发给OutputServlet 
ServletContext context = getServletContext(); 
RequestDispatcher dispatcher = context.getRequestDispatcher("/OutputServlet");// ok 
// RequestDispatcher dispatcher = context.getRequestDispatcher("outputServlet");//worng 
// RequestDispatcher dispatcher = req.getRequestDispatcher("outputServlet");//ok 
PrintWriter out = res.getWriter(); 
out.println("Output from CheckServlet before forwading request."); 
System.out.println("Output from CheckServlet before forwading request."); 
// throw IllegalArgumentException:Cannot forward after response has been committed 
//out.close();
dispatcher.forward(req, res); 
out.println("Output from CheckServlet after forwading request."); 
System.out.println("Output from CheckServlet after forwading request."); 
public class OutputServlet extends GenericServlet { 

@Override 
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { 
// 读取CheckServlet存放在请求范围内的消息 
String message = (String) req.getAttribute("msg"); 
PrintWriter out = res.getWriter(); 
out.println(message); 
out.close(); 
} 
} 

Консоль выводит результат:

Output from CheckServlet before forwading request.

Output from CheckServlet after forwading request.

надdispatcher.forward(request,response)Последовательность обработки метода выглядит следующим образом:

  1. Очистите буфер, используемый для хранения данных тела ответа.

  2. Если целевой компонент является сервлетом или JSP, вызовите их метод service() и отправьте результат ответа, сгенерированный методом, клиенту; если целевой компонент является статическим HTML-документом в файловой системе, прочитайте данные в документе и отправить его клиенту Он отправляется клиенту.

отdispatcher.forward(request,response)Поток обработки метода можно увидеть, что переадресация запроса имеет следующие характеристики:

  • Поскольку метод forward() сначала очищает буфер для хранения данных тела ответа, результат ответа, сгенерированный исходным компонентом сервлета, не будет отправлен клиенту, клиенту будет отправлен только результат ответа, сгенерированный целевым компонентом.

  • Если исходный компонент пересылает запрос之前, результат ответа был отправлен (например, вызов метода flushBuffer() ServletResponse или вызов метода close() выходного потока, связанного с ServletResponse), то метод forward() выдастlllegalStateException. Чтобы избежать этого исключения, результат ответа не должен отправляться в исходном компоненте.

  • Вызывается в исходном компоненте сервлетаdispatcher.forward(request,response)Код после метода также выполняется. Точно так же будет выполнен код после вызова out.close(). Просто код после out.close() больше не будет возвращаться клиенту через ответ.

12. Содержит

Следующий код включает содержимое header.html, содержимое ответа, сгенерированное GreetServlet, и содержимое foot.html в собственный результат ответа. Другими словами, HTML-документ, возвращаемый клиенту следующим сервлетом, генерируется им самим, header.htm, GreetServlet и foot.htm.

ServletContext context = getServletContext(); 
RequestDispatcher headDispatcher = context.getRequestDispatcher("/header.htm"); 
RequestDispatcher greetDispatcher = context.getRequestDispatcher("/greet"); 
RequestDispatcher footDispatcher = context.getRequestDispatcher("/footer.htm"); 

headDispatcher.include(request, response); 
greetDispatcher.include(request, response); 
footDispatcher.include(request, response); 

Поток обработки метода include() объекта RequestDispatcher выглядит следующим образом.

  1. Если целевой компонент является сервлетом или JSP, вызовите соответствующий метод service() и добавьте тело ответа, сгенерированное этим методом, к результату ответа исходного компонента; если целевой компонент является документом HTML, непосредственно добавьте содержимое документ в результат ответа исходного компонента.

  2. Вернитесь к сервисному методу исходного компонента, чтобы продолжить выполнение последующих блоков кода.

По сравнению с переадресацией запроса включение имеет следующие характеристики:

  • К ответу будут добавлены выходные данные как исходного компонента, так и включенного целевого компонента.

  • Изменения кодов состояния ответов или заголовков ответов в целевом компоненте игнорируются.

Когда исходный компонент и целевой компонент находятся в отношениях пересылки запросов или отношениях сдерживания, для каждого клиентского запроса они совместно используют один и тот же объект ServletRequest и объект ServletResponse, поэтому исходный компонент и целевой компонент могут совместно использовать общие данные в пределах области действия. запроса.

13. Перенаправление

Протокол HTTP определяет механизм перенаправления, и рабочий процесс перенаправления выглядит следующим образом:

  1. Пользователь вводит определенный URL-адрес в браузере, чтобы запросить доступ к компоненту на стороне сервера.

  2. Компонент на стороне сервера возвращает результат ответа с кодом состояния 302. Значение результата ответа: позволить стороне браузера запросить доступ к другому веб-компоненту. URL-адрес другого веб-компонента предоставляется в результате ответа. Другой веб-компонент может находиться или не находиться на том же веб-сервере.

  3. Когда сторона браузера получает такой ответ, она немедленно автоматически запрашивает доступ к другому веб-компоненту.

  4. Сторона браузера получает результат ответа от другого веб-компонента.

В Java Servlet API интерфейс HttpServletResponsesendRedirect(String location)способ переадресации.

После перенаправления URL-адрес панели навигации становится URL-адресом целевого компонента.response.sendRedirect(String location)Метод имеет следующие характеристики:

  • Результат ответа, сгенерированный исходным компонентом сервлета, не отправляется клиенту.response.sendRedirect(String location)Метод всегда возвращает результат ответа с кодом состояния 302. После того, как браузер получит этот результат ответа, он немедленно автоматически запрашивает доступ к перенаправленному целевому веб-компоненту, и клиент, наконец, получает результат ответа целевого веб-компонента.

  • Метод sendRedirect() генерирует исключение, если исходный компонент уже отправил ответ до перенаправления. Чтобы избежать этого исключения, результат ответа не должен отправляться в исходном компоненте.

  • Вызывается в исходном компоненте сервлетаresponse.sendRedirect(String location)Код после метода также выполняется.

  • Исходный и целевой компоненты не используют один и тот же объект ServletRequest и, следовательно, не используют общие данные в области запроса.

  • дляresponse.sendRedirect(String location)Расположение параметра в методе, если оно начинается с «/», указывает URL-адрес относительно корневого пути текущего сервера, а если оно начинается с «http://», оно указывает полный URL-адрес.

  • Целевой компонент не обязательно должен быть компонентом того же веб-приложения на том же сервере, это может быть любая допустимая веб-страница в Интернете.

Метод sendRedirect() определен в интерфейсе HttpServletResponse, а в интерфейсе ServletResponse нет метода sendRedirect(), поскольку механизм перенаправления определяется протоколом HTTP.

14. Разница между переадресацией и переадресацией

  1. Метод переадресации может пересылать ресурсы только на один и тот же веб-сайт, а метод sendRedirect может также нацеливаться на другие приложения на том же веб-сайте.

  2. После переадресации URL-адрес браузера остается неизменным, а после перенаправления sendRedirect URL-адрес браузера становится URL-адресом назначения.

  3. В процессе пересылки сервлет вызывает метод service() другого сервлета того же веб-приложения, поэтому он по-прежнему принадлежит ответу на запрос. sendRedirect, браузер сначала отправляет запрос целевому сервлету, сервлет видит sendRedirect и возвращает целевой URL-адрес браузеру, затем браузер запрашивает целевой URL-адрес, и целевой URL-адрес возвращает браузеру ответ. Браузер и сервер дважды запрашивают ответ.

  4. Запрос и ответ совместно используются вызывающим и вызываемым методом пересылки. Метод sendRedirect имеет два запроса и ответа из-за двух запросов сервера браузера.

15. Фильтры

в каждом веб-компоненте相同操作можно положить в过滤器Это уменьшит повторяющееся кодирование. Фильтр может предварительно обработать часть запроса клиента, а затем перенаправить запрос отвечающему веб-компоненту.После того, как веб-компонент выдаст результат ответа, фильтр также может проверить и изменить результат ответа, а затем изменить измененный ответ. результат отправляется клиенту.

Веб-компоненты, за фильтрацию которых отвечает фильтр, могут быть файлами Servlet, JSP или HTML Процесс фильтрации фильтра показан на следующем рисунке.

1

15.1 Создание фильтров

Все пользовательские фильтры должны реализовыватьjavax.servlet.FilterИнтерфейс, этот интерфейс содержит следующие 3 метода, которые необходимо реализовать.

  • init(FilterConfig filterConfig): это метод инициализации фильтра. существуетWeb 应用启动时, контейнер сервлета сначала создаетFilterConfigобъект, затем создайтеFilterобъект, затем вызовите объект фильтраinit(FilterConfig filterConfig)метод, в котором вы можете пройтиconfigпараметры для чтенияweb.xmlПараметры инициализации настроены для фильтра в файле.

  • doFilter(ServletRequest request, ServletResponse response,FilterChain chain): этот метод выполняет фактическую операцию фильтрации. Когда URL-адрес, запрошенный клиентом, совпадает с URL-адресом, сопоставленным для фильтра, контейнер сервлета сначала вызывает фильтр.doFilter()метод.FilterChainпараметры используются для доступа后续过滤器илиWeb组件.

  • destroy(): Контейнер сервлета вызывает этот метод перед уничтожением объекта фильтра.В этом методе ресурсы, занятые фильтром, могут быть освобождены.

15.2 Метод doFilter() в Filter

doFilter() является наиболее важным методом во всем фильтре. Контейнер сервлета вызывает этот метод для завершения фактической операции фильтрации.

  • Этот метод получает два параметра, а именно параметры запроса и ответа, поэтому мы можем выполнить некоторую предварительную обработку запроса, а затем продолжить его передачу, или мы можем выполнить некоторые дополнительные операции с возвращенным результатом ответа, а затем вернуть его клиенту ( при условии, что ответ не закрыт).

  • существуетFilter.doFilter()Метод не может напрямую вызывать сервлетserviceметод, но вызовFilterChain.doFilterметод для активации целевого сервлетаserviceметод, передаваемый, когда объект FilterChainFilter.doFilterПередаются параметры метода.

  • можно зарегистрировать в веб-приложении多个 Filterпрограмма, если их несколькоFilterпрограмма можетServletПроцесс доступа к программе перехватывается, когдаServletПри поступлении запроса на доступ веб-контейнерFilterПрограммы объединены в однуFilterцепочка (также называемая цепочкой фильтров).

  • Порядок перехвата каждого фильтра в цепочке фильтров соответствует их порядку сопоставления в файле web.xml.Вызов метода FilterChain.doFilter в предыдущем методе Filter.doFilter активирует метод doFilter следующего фильтра, а в последнем Метод Filter.doFilter Вызванный метод FilterChain.doFilter активирует метод службы целевого сервлета.

  • Пока какой-либо фильтр в цепочке фильтров не вызывает метод FilterChain.doFilter, метод службы целевого сервлета не будет выполняться.

15.3 Примеры

Ниже показано основное использование фильтра на простом примере.

определить фильтр

Основная функция этого фильтра — вывести параметры инициализации перед запросом, а затем склеить возвращаемые результаты после запроса:

public class LogFilter implements Filter { 

private String ip; 

public void init(FilterConfig filterConfig) throws ServletException { 
System.out.println("执行LogFilter初始化方法"); 
// 获取Filter初始化参数 
this.ip = filterConfig.getInitParameter("ip"); 
} 

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 

throws IOException, ServletException { 
System.out.println("正在执行 LogFilter.doFilter()方法,LogFilter初始化参数ip=" + ip); 
System.out.println("调用LogFilter中的chain.doFilter()之前"); 
chain.doFilter(request, response); 
System.out.println("调用LogFilter chain.doFilter()之后"); 
PrintWriter out = response.getWriter(); 

// 拼接返回结果 
out.println("This msg is from LogFilter"); 
out.flush(); 

} 

public void destroy() { 
System.out.println("正在执行 LogFilter 的销毁方法"); 
} 

} 

TestFilter servlet

public class TestFilter extends HttpServlet { 

protected void doGet(HttpServletRequest request, HttpServletResponse response) 

throws ServletException, IOException { 
System.out.println("正在执行 TestFilter 的 doGet() 方法"); 
PrintWriter out = response.getWriter(); 
out.println("This msg is from HelloServlet doGet()"); 
// 如果执行 close 操作,后续过滤器中对 response 的操作 将无法返回到客户端 
// out.close(); 
out.flush(); 
} 
} 

Настройка фильтров в web.xml

<filter> 
<filter-name>LogFilter</filter-name> 
<filter-class>controller.LogFilter</filter-class> 
<init-param> 
<param-name>ip</param-name> 
<param-value>127.0.0.1</param-value> 
</init-param> 
</filter> 

<filter-mapping> 
<filter-name>LogFilter</filter-name> 
<url-pattern>/testFilter</url-pattern> 
</filter-mapping> 

Консоль выводит результат следующим образом:

Выполняется метод LogFilter.doFilter(), параметр инициализации LogFilter ip=127.0.0.1

Перед вызовом chain.doFilter() в LogFilter

Выполняется метод DoGet() TestFilter

После вызова LogFilter chain.doFilter()

Тело ответа http выглядит следующим образом:

This msg is from HelloServlet doGet()

This msg is from LogFilter

15.4 Линейные фильтры

Несколько фильтров могут быть объединены в цепочку для совместной работы, и контейнер сервлета будет вызывать их метод doFilter() по одному в соответствии с порядком, в котором они определены в web.xml. Предположим, что есть два последовательных фильтра, и оба их метода doFilter() имеют следующую структуру:

Code1; //表示chain.doFilter()前的代码 
chain.doFilter(); 
Code2; //表示chain.doFilter()后的代码 

Предполагается, что оба фильтра будут предварительно обрабатывать клиентские запросы для одного и того же сервлета. Когда клиент запрашивает доступ к этому сервлету, рабочий процесс этих двух фильтров и сервлета показан на рисунке ниже.

681945C9-9ACE-4542-8621-5D10C988A858

Из-за нехватки места использование последовательных фильтров здесь не показано.Заинтересованные студенты могут написать небольшую демонстрацию, чтобы опробовать ее. Вам нужно только создать новый фильтр самостоятельно, а затем добавить некоторые связанные конфигурации в файл web.xml.

16. Разумно определите тип области действия переменных, определенных в сервлетах.

В языке Java локальные переменные и переменные экземпляра имеют разные области видимости, и их отличия заключаются в следующем: локальные переменные определяются в методе, и каждый поток имеет свои собственные локальные переменные. Переменные экземпляра определяются в классе. Каждый экземпляр класса имеет свои собственные переменные экземпляра.Если экземпляр завершает свой жизненный цикл, его переменные экземпляра также заканчивают свой жизненный цикл. Если несколько потоков одновременно выполняют метод экземпляра, и этот метод обращается к переменной экземпляра, то эти потоки обращаются к одной и той же переменной экземпляра.

наконец

Если вы считаете, что это полезно для вас, пожалуйста, прокомментируйте, перешлите и поставьте лайк!

Использованная литература: