Как работают сервлеты? Создание экземпляров, сеансы, общие переменные и многопоточность
Предположим, у меня есть веб-сервер, который содержит множество сервлетов. Для передачи информации между этими сервлетами я устанавливаю переменные сеанса и экземпляра.
теперь, если 2 или более пользователей отправляют запрос на этот сервер, что происходит с переменными сеанса? Будут ли они общими для всех пользователей или они будут отличаться для каждого пользователя. Если они разные, то как сервер мог различать разных пользователей?
еще один подобный вопрос, если есть n пользователи, обращающиеся к определенному сервлету, затем этот сервлет создается только при первом обращении к нему первого пользователя или он создается для всех пользователей отдельно? Другими словами, что происходит с переменными экземпляра?
7 ответов:
ServletContext
когда контейнер сервлета (например Apache Tomcat) запускается, он будет развертывать и загружать все свои веб-приложения. При загрузке веб-приложения контейнер сервлетов создает
ServletContextраз и сохраняет его в памяти сервера. Веб-приложениеweb.xmlфайл разбирается, и каждый<servlet>,<filter>и<listener>найдено (или каждый класс с аннотацией@WebServlet,@WebFilterи@WebListenerсоответственно) создается один раз и хранится в памяти сервера, а также. Для каждого экземпляра фильтра, егоinit()метод вызывается с новойFilterConfig.когда контейнер сервлета завершает работу, он выгружает все веб-приложения, вызывает
destroy()метод всех его инициализации сервлетов и фильтров, и всеServletContext,Servlet,FilterиListenerэкземпляры будут разрушены.Когда a
Servletесть<servlet><load-on-startup>или@WebServlet(loadOnStartup)значение больше0, егоinit()метод также вызывается при запуске с новымServletConfig. Эти сервлеты инициализируются в том же порядке, указанном этим значением (1 -> 1-й, 2 - > 2-й и т. д.). Если одно и то же значение указано для нескольких сервлетов, то каждый из этих сервлетов загружается в том порядке, в котором они отображаются вweb.xmlили@WebServletклассов. Если значение "load-on-startup" отсутствует, тоinit()метод будет вызываться всякий раз, когда HTTP-запрос попадает в этот сервлет в первый раз.HttpServletRequest и HttpServletResponse
контейнер сервлета прикреплен к веб-серверу, который прослушивает HTTP-запросы на определенный номер порта (порт 8080 обычно используется во время разработки и порт 80 в производстве). Когда клиент (пользователь с веб-браузером) отправляет HTTP-запрос, контейнер сервлета создает новый
HttpServletRequestиHttpServletResponseобъекты и передает их через какой-либо определенной
сеансы
короче говоря: веб-сервер выдает уникальный идентификатор каждый посетитель на первый визит. Посетитель должен вернуть это удостоверение, чтобы его узнали в следующий раз. Этот идентификатор также позволяет серверу правильно разделять объекты, принадлежащие одному сеансу, и объекты, принадлежащие другому сеансу.
Экземпляр Сервлета
Если load-on-startup is ложные:
Если load-on-startup и правда:
Как только он находится в режиме обслуживания и на канавке, то же самое сервлет будет работать на запросы от других клиентов.
почему это не хорошая идея, чтобы иметь один экземпляр каждого клиента? Подумайте об этом: вы наймете одного парня пиццы для каждого заказа, который пришел? Сделайте это, и вы будете вне бизнеса в кратчайшие сроки.
Он поставляется с небольшим риском, хотя. Помните: этот единственный парень держит всю информацию о заказе в кармане: так что если вы не осторожны потокобезопасность на сервлетах, он может в конечном итоге дать неправильный заказ определенного клиента.
сеанс в сервлетах Java - это то же самое, что и сеанс в других языках, таких как PHP. Он уникален для пользователя. Сервер может отслеживать его различными способами, такими как куки, переписывание url и т. д. Это документации статья объясняет это в контексте Java-сервлетов и указывает, что именно то, как поддерживается сеанс, является детализацией реализации, оставленной разработчикам сервера. Спецификация только оговаривает, что она должна поддерживаться как уникальная для пользователя по всему миру несколько подключений к серверу. Проверьте эта статья от Oracle для получения дополнительной информации по обоим вашим вопросам.
Edit есть отличный учебник здесь о том, как работать с сессией внутри сервлетов. И здесь это глава из Sun о Java-Сервлетах, что они такое и как их использовать. Между этими двумя статьями, вы должны быть в состоянии ответить на все ваши вопросы.
когда servletcontainer (например, Apache Tomcat) запускается, он будет читать из интернета.xml-файл (только один для каждого приложения) если что-то пойдет не так или появится ошибка на боковой консоли контейнера, в противном случае он будет развертывать и загружать все веб-приложения с помощью web.xml (так называется его дескриптор развертывания).
во время фазы создания экземпляра сервлета servletInstance готов, но он не может обслуживать запрос клиента, потому что он отсутствует с двумя частями информации:
1:контекст информация
2: начальная информация о конфигурацииServlet engine создает объект интерфейса servletConfig, инкапсулирующий в него вышеуказанную недостающую информацию servlet engine вызывает init () сервлета, подавая ссылки на объект servletConfig в качестве аргумента. После того, как init() будет полностью выполнен сервлет готов к серверу запроса клиента.
Q )во время жизни сервлета сколько раз происходит инстанцирование и инициализация??
A)только один раз (для каждого запроса клиента создается новый поток) только один экземпляр сервлета обслуживает любое количество клиентских запросов т. е. после обслуживания одного клиентского запроса сервер не умирает. Он ждет других запросов клиента т. е. то, что CGI (для каждого запроса клиента создается новый процесс) ограничение преодолевается с помощью сервлета (внутренне servlet engine создает поток).
Q) Как работает концепция сеанса?
A) всякий раз, когда getSession () вызывается на HttpServletRequest объекта
Шаг 1: объект запроса evalauated для идентификатора входящего сеанса.
Шаг 2: если ID не доступен, создается новый объект HttpSession и генерируется соответствующий идентификатор сеанса (т. е. HashTable) идентификатор сеанса сохраняется в объекте ответа httpservlet, а ссылка объекта HttpSession возвращается в сервлет (doGet/doPost).
Шаг 3:если ID доступный новый объект сеанса не создан идентификатор сеанса выбирается из объекта запроса поиск производится в коллекции сеансов с помощью идентификатора сеанса в качестве ключа.
после успешного поиска идентификатор сеанса сохраняется в HttpServletResponse, а ссылки на существующие объекты сеанса возвращаются в doGet() или doPost() UserDefineservlet.
Примечание:
1)когда управление уходит от кода сервлета к клиенту не забывайте, что объект сеанса удерживается servletcontainer ie, servletengine
2)многопоточность остается для сервлетов devlopers людей для реализации ie., обрабатывать множественный запрос клиента ничего не беспокоиться о многопоточном коде
Inshort форма:
сервлет создается при запуске приложения (он развертывается в контейнере сервлетов) или при первом обращении к нему (в зависимости от параметра загрузка при запуске) при создании экземпляра сервлета вызывается метод init () сервлета затем сервлет (его один и только экземпляр) обрабатывает все запросы (его метод service () вызывается несколькими потоками). Вот почему не рекомендуется иметь какую-либо синхронизацию в нем, и вы должны избегать переменных экземпляра сервлета когда приложение не развертывается (контейнер сервлета останавливается), вызывается метод destroy ().
сеансы - что сказал Крис Томпсон.
экземпляров - сервлет создается, когда контейнер получает первый запрос, сопоставленный с сервлетом (если сервлет не настроен для загрузки при запуске с
<load-on-startup>элементweb.xml). Этот же экземпляр используется для обслуживания последующих запросов.
Спецификация Servlet JSR-315 четко определяет поведение веб-контейнера в службе (и doGet, doPost, doPut и т. д.) методы (2.3.3.1 проблемы многопоточности, стр. 9):
контейнер сервлетов может отправлять параллельные запросы через службу метод сервлета. Для обработки запросов разработчик сервлетов должны быть предусмотрены адекватные условия для одновременной обработки с несколькими потоки в методе службы.
хотя это не рекомендуется, альтернативой для разработчика является реализуйте интерфейс SingleThreadModel, для которого требуется контейнер чтобы гарантировать, что есть только один поток запроса за один раз в метод службы. Контейнер сервлета может удовлетворять этому требованию путем сериализация запросов на сервлете или поддержание пула сервлетов экземпляры. Если сервлет является частью веб-приложения, которое было помеченный как распространяемый, контейнер может поддерживать пул из сервлета экземпляры в каждой JVM, через которую распространяется приложение.
для сервлетов, не реализующих интерфейс SingleThreadModel, если метод обслуживания (или методы, такие как doGet или doPost, которые являются передается в метод службе он полностью реализует интерфейс абстрактного класса) был определен с помощью ключевого слова synchronized, контейнер сервлетов нельзя использовать подход пула экземпляров, но необходимо сериализовать запросы через него. Настоятельно рекомендуется Разработчики не синхронизируются метод службы (или методы, отправленные ему) в этих обстоятельства из-за пагубного влияния на производительность
нет. сервлеты являются не потокобезопасными
is позволяет получить доступ к нескольким потокам одновременно
если вы хотите сделать его сервлет как потокобезопасный . Вы можете пойти на
Implement SingleThreadInterface(i)который является пустым интерфейсом нетметоды
или мы можем пойти для синхронизации методов
мы можем сделать весь метод обслуживания как синхронизированный путем использование синхронизированного
keword перед методом
пример:
public Synchronized class service(ServletRequest request,ServletResponse response)throws ServletException,IOExceptionили мы можем поместить блок кода в синхронизированный блок
пример:
Synchronized(Object) { ----Instructions----- }Я чувствую, что синхронизированный блок лучше, чем сделать весь метод
синхронизироваться







Comments