Методы расширения - это только статические методы. Единственное отличие заключается в таких инструментах, как редактор Visual Studio, который выставляет их для функции автоматического завершения (intellisense). Вы можете найти подробное объяснение здесь: C # Методы расширения: синтаксический сахар или полезный инструмент?
Когда запускается контейнер сервлетов (например, Apache Tomcat), он развертывает и загружает все свои веб-приложения. Когда веб-приложение загружено, контейнер сервлетов создает ServletContext
один раз и сохраняет его в памяти сервера. web.xml
веб-приложения и все включенные web-fragment. xml
, и каждый <сервлет>
, <фильтр>
и <слушатель>
найден (или каждый класс, аннотированный @WebServlet
, @WebFilter
и @WebListener
соответственно) инстанцируется один раз и также хранится в памяти сервера. Для каждого инстанцированного фильтра вызывается его метод init()
с новым FilterConfig
.
Когда сервлет
имеет
или @WebServlet(loadOnStartup)
значение больше 0
, то его init()
метод также вызывается во время запуска с новым ServletConfig
. Эти сервлеты инициализируются в том же порядке, который указан этим значением (1
- первый, 2
- второй и т.д.). Если одно и то же значение указано для более чем одного сервлета, то каждый из этих сервлетов загружается в том же порядке, в каком они появляются в web.xml
, web-fragment.xml
или @WebServlet
classloading. Если значение "load-on-startup" отсутствует, метод init()
будет вызываться каждый раз, когда HTTP-запрос впервые попадает на этот сервлет.
Когда контейнер сервлетов закончит все описанные выше шаги инициализации, будет вызван ServletContextListener#contextInitialized()
метод.
Когда контейнер сервлетов выключается, он выгружает все веб-приложения, вызывает метод destroy()
всех своих инициализированных сервлетов и фильтров, и все ServletContext
, Servlet
, Filter
и Listener
экземпляры уничтожаются. Наконец, будет вызван ServletContextListener#contextDestroyed()
.
Контейнер сервлетов подключен к веб-серверу, который прослушивает HTTP-запросы на определенном номере порта (обычно используется порт 8080 во время разработки и порт 80 в производстве). Когда клиент (например, пользователь с помощью веб-браузера или программно с помощью URLConnection
) отправляет HTTP-запрос, контейнер сервлетов создает новые объекты HttpServletRequest
и HttpServletResponse
и пропускает их через любой определенный Filter
в цепочке и, в конечном итоге, через экземпляр Servlet
.
В случае фильтров вызывается метод doFilter()
. Когда код контейнера сервлетов вызывает chain.doFilter(request, response)
, запрос и ответ переходят к следующему фильтру, или поражают сервлет, если не осталось ни одного фильтра.
В случае сервлетов вызывается метод service()
. По умолчанию этот метод определяет, какой из методов doXxx()
вызвать на основе request.getMethod()
. Если определенный метод отсутствует в сервлете, то в ответ возвращается ошибка HTTP 405.
Объект request предоставляет доступ ко всей информации о HTTP-запросе, такой как его URL, заголовки, строка запроса и тело. Объект response предоставляет возможность контролировать и отправлять HTTP-ответ так, как вы хотите, например, позволяя вам устанавливать заголовки и тело (обычно сгенерированное HTML-содержимое из JSP-файла). Когда HTTP-ответ зафиксирован и завершен, объекты запроса и ответа перерабатываются и становятся доступными для повторного использования.
Когда клиент впервые посещает webapp и/или HttpSession
впервые получен через request. getSession()
, контейнер сервлетов создает новый объект HttpSession
, генерирует длинный и уникальный ID (который можно получить по session.getId()
) и сохраняет его в памяти сервера. Контейнер сервлетов также устанавливает Cookie
в заголовке Set-Cookie
HTTP-ответа с JSESSIONID
в качестве имени и уникальным идентификатором сессии в качестве значения.
Согласно спецификации HTTP cookie (договор, которого должны придерживаться любой приличный веб-браузер и веб-сервер), клиент (веб-браузер) должен отправлять этот cookie обратно при последующих запросах в заголовке Cookie
до тех пор, пока cookie действителен (т.е. уникальный ID должен относиться к неистекшей сессии, а домен и путь должны быть правильными). Используя встроенный в браузер монитор HTTP-трафика, вы можете убедиться, что cookie действителен (нажмите F12 в Chrome / Firefox 23+ / IE9+ и проверьте вкладку Net/Network). Контейнер сервлетов будет проверять заголовок Cookie
каждого входящего HTTP-запроса на наличие cookie с именем JSESSIONID
и использовать его значение (идентификатор сессии) для получения связанной с ним HttpSession
из памяти сервера.
Сессия HttpSession
остается живой до тех пор, пока она не будет простаивать (т.е. не будет использоваться в запросе) дольше, чем значение таймаута, указанное в
, параметре в web.xml
. Значение тайм-аута по умолчанию равно 30 минутам. Поэтому, когда клиент не посещает веб-приложение дольше указанного времени, контейнер сервлетов уничтожает сессию. Каждый последующий запрос, даже с указанным cookie, больше не будет иметь доступа к той же сессии; контейнер сервлетов создаст новую сессию.
На стороне клиента файл cookie сессии остается живым до тех пор, пока работает экземпляр браузера. Поэтому, если клиент закрывает экземпляр браузера (все вкладки/окна), то сессия на стороне клиента уничтожается. В новом экземпляре браузера cookie, связанный с сессией, не будет существовать, поэтому он больше не будет отправлен. Это приводит к созданию совершенно новой HttpSession
, с использованием совершенно новой куки сессии.
ServletContext
живет до тех пор, пока живет веб-приложение. Он разделяется между всеми запросами в всех сессиях. HttpSession
живет до тех пор, пока клиент взаимодействует с веб-приложением с помощью одного и того же экземпляра браузера, и сессия не завершилась на стороне сервера. Она разделяется между всеми запросами в одной сессии. HttpServletRequest
и HttpServletResponse
живут с момента получения сервлетом HTTP-запроса от клиента до получения полного ответа (веб-страницы). Он не разделяется в других местах. сервлета
, фильтра
и слушателя
живут до тех пор, пока живет веб-приложение. Они разделяются между всеми запросами в всех сессиях. атрибут
, определенный в ServletContext
, HttpServletRequest
и HttpSession
, будет жить до тех пор, пока живет данный объект. Сам объект представляет собой "область видимости" во фреймворках управления бобами, таких как JSF, CDI, Spring и т.д.. Эти фреймворки хранят свои scoped beans как атрибут
ближайшего подходящего scope. Учитывая это, ваша основная проблема, возможно, заключается в безопасности потоков. Теперь вы должны знать, что сервлеты и фильтры разделяются между всеми запросами. Это хорошая вещь в Java, она многопоточна, и разные потоки (читай: HTTP-запросы) могут использовать один и тот же экземпляр. Иначе было бы слишком дорого воссоздавать, инициировать()
и уничтожать()
их для каждого отдельного запроса.
Вы также должны понимать, что вы должны никогда не назначать любые данные, относящиеся к запросу или сессии, в качестве экземпляра переменной сервлета или фильтра. Они будут совместно использоваться всеми другими запросами в других сессиях. Это не потокобезопасно! Пример ниже иллюстрирует это:
public class ExampleServlet extends HttpServlet {
private Object thisIsNOTThreadSafe;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object thisIsThreadSafe;
thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
}
}
Sessions - то, что сказал Крис Томпсон.
Instantiation - сервлет инстанцируется, когда контейнер получает первый запрос, сопоставленный с сервлетом (если только сервлет не настроен на загрузку при запуске с помощью элемента
в web.xml
). Этот же экземпляр используется для обслуживания последующих запросов.
Сессия в сервлетах Java - это то же самое, что и сессия в других языках, таких как PHP. Она уникальна для пользователя. Сервер может отслеживать его различными способами, такими как cookies, переписывание url и т.д. Эта Java doc статья объясняет это в контексте сервлетов Java и указывает, что то, как именно поддерживается сессия, является деталью реализации, оставленной на усмотрение разработчиков сервера. В спецификации только указано, что он должен сохраняться уникальным для пользователя при нескольких соединениях с сервером. Посмотрите эту статью от Oracle для получения дополнительной информации по обоим вашим вопросам.
Редактировать Есть отличный учебник здесь о том, как работать с сессией внутри сервлетов. А здесь - глава от Sun о Java Servlets, что это такое и как их использовать. Между этими двумя статьями вы сможете ответить на все свои вопросы.