diff --git a/Веб/Клиент-сервер/FastCGI.md b/Веб/Клиент-сервер/FastCGI.md
index 5b9e064..a7a5344 100644
--- a/Веб/Клиент-сервер/FastCGI.md
+++ b/Веб/Клиент-сервер/FastCGI.md
@@ -1,3 +1,47 @@
- Все запросы могут обрабатываться одним процессом CGI-программы
- Веб-сервер взаимодействует с процессом через UNIX Domain Sockets или TCP/IP (а не через stdin и stdout)
- Для общения используется бинарный протокол, обеспечивающий передачу любых текстовых данных
+## FastCGI на Java
+Пример
+```Java
+public static void main(String[] args) {
+ FCGIInterface fcgiInterface = new FCGiInterface();
+ while (fcgiInterface.FCGIAccept() >= 0) {
+ String content = """
+ ...
+ """;
+ String response = """
+ HTTP /1.1 200 OK
+ Content-Type: text/html
+ Content-Length: %d
+
+
+ %s
+ """.formatted(content.getBytes(StandardCharsets.UTF_8).length, content);
+ }
+}
+```
+- `FCGIInterface` - реализует магию по перенаправлению `System.in`, `System.out` и `System.err` в потоки TCP сокета. Поля для запросов и сокета - статические
+- `FCGIInterface.request.params` - объект `Properties`, через который можно узнать список параметров, переданных веб-сервером
+- Наиболее значимые параметры:
+ - `REQUEST_METHOD` - Get, Post и тд
+ - `QUERY_STRING` - параметры запроса после `?`
+ - `CONTENT_TYPE` - значение заголовка запроса
+ - `CONTENT_LENGTH` - значение заголовка запроса
+Еще пример
+```Java
+private static String readRequestBody() throws IOException {
+ FCGIInterface.request.inStream.fill();
+
+ var contentLength = FCGIInterface.request.inStream.available();
+ var buffer = ByteBuffer.allocate(contentLength);
+ var readBytes = FCGIInterface.request.inStream.read(buffer.array(), 0, contentLength);
+
+ var requestBodyRaw = new byte[readBytes];
+ buffer.get(requestBodyRaw);
+ buffer.clear();
+
+ return new String(requestBodyRaw, StandardCharsets.UTF_8);
+}
+```
+
diff --git a/Веб/Клиент-сервер/Java Servlets.md b/Веб/Клиент-сервер/Java Servlets.md
new file mode 100644
index 0000000..ef4e8f0
--- /dev/null
+++ b/Веб/Клиент-сервер/Java Servlets.md
@@ -0,0 +1,234 @@
+## Платформа Java EE
+- Набор стандартов и спецификаций для создания корпоративных приложений на Java
+- Спецификации Java EE реализуются серверами приложений
+ - Apache Tomcat
+ - Sun/Oracle GlassFish
+ - BEA/Oracle WebLogic
+ - IBM WebSphere
+ - RedHat JBoss
+## Сервлеты
+- [Серверные сценарии](Серверные%20сценарии.md) написанные на Java
+- Жизненным циклов сервлетов управляет веб-контейнер (он же контейнер сервлетов)
+- В отличие от [CGI](CGI.md) запросы обрабатываются в отдельных потоках (а не процессах) на веб-контейнере
+## Преимущества
+- Выполняются быстрее, чем CGI-сценарии
+- Хорошая масштабируемость
+- Надежность и безопасность
+- Платформенно-независимы
+- Множество инструментов мониторинга и отладки
+## Недостатки
+- Слабое разделение уровня представления и бизнес-логики
+- Возможны конфликты при параллельной обработке запросов
+## Обработка HTTP-запроса
+1. Браузер формирует [HTTP](../Сеть%20и%20API/HTTP.md)-запрос и отправляет его на сервер
+2. Веб-контейнер создает объекты `HttpServletRequest` и `HttpServletResponse`
+3. Веб-контейнер вызывает метод `service` у сервлета
+4. Сервлет формирует ответ и записывает его в поток вывода `HttpServletResponse`
+## Пример сервлета
+```Java
+package sample.servlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+public class SampleServlet extends HttpServlet {
+ @Override
+ public void doGet(HttpServletRequest request,
+ HttpServletResponse response)
+ throws IOException {
+ String pageTitle = "Пример сервлета";
+ response.setContentType("text/html");
+ PrintWriter out = response.getWriter();
+ out.println("");
+ ...
+ out.println("");
+ }
+}
+```
+## Конфигурация сервлета
+Конфигурирование происходит в `WEB-INF/web.xml` (есть конечно аннотации, но это слишком современно). В `WEB-INF/classes` должны лежать скомпилированные джава-классы
+```xml
+
+
+ SampleServlet
+ org.itmo.sample.SampleServlet>
+
+
+
+
+ SampleServlet
+ /sample
+
+```
+Полный файл `web.xml`
+```xml
+
+
+
+
+
+ SampleServlet
+ org.itmo.sample.SampleServlet>
+
+
+
+
+ SampleServlet
+ /sample
+
+
+
+```
+## Жизненный цикл сервлета
+- Жизненным циклом управляет веб-контейнер
+- Методы, управляющие жизненным циклом, должен вызывать только веб-контейнер
+### 1. Загрузка класса сервлета
+Проверяются пути: `WEB-INF/classes/`, `WEB-INF/lib/*.jar`, стандартные классы Java SE и классы веб-контейнера
+```xml
+
+ SampleServlet
+ org.itmo.sample.SampleServlet>
+
+
+
+ say-hello
+ true
+
+
+```
+### 2. Создание экземпляра сервлета
+Создание через конструктор `new SampleServlet()`
+### 3. Вызов метода init()
+`init(config)` - принимает `config`
+### 4. Обработка HTTP-запросов
+На каждый запрос в новом потоке (на самом деле там пул потоков) вызывается метод `service()`
+### 5. Уничтожение сервлета
+Вызов метода `destroy()`
+## Контекст сервлетов
+- API, с помощью которого сервлет может взаимодействовать со своим контейнером
+- Доступ к методам осуществляется через интерфейс `javax.servlet.ServletContext`
+- У всех сервлетов внутри приложения общий контекст
+- В контекст можно помещать общую для всех сервлетов информацию (методы `getAttribute` и `setAttribute`)
+- Если приложение - распределенное, то на каждом экземпляре JVM контейнером создается свой контекст
+```Java
+import java.io.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+public class DemoServlet extends HttpServlet {
+ @Override
+ public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
+ res.setContentType("text/html");
+ PrintWriter pw = res.getWriter();
+
+ ServletContext context = getServletContext();
+ String driverName = context.getInitParameter("dname");
+ pw.println("driver name: " + driverName);
+ pw.close();
+ }
+}
+```
+В `web.xml` до сервлетов
+```xml
+
+ dname
+ org.postgresql.Driver
+
+```
+## HTTP-сессии
+- Напомним, что HTTP - stateless
+- `javax.servlet.HttpSession` - интерфейс, позволяющий идентифицировать конкретного клиента (браузер) при обработке множества HTTP-запросов от него
+- Экземпляр `HttpSession` создается при первом обращении клиента к предложению и сохраняется некоторое (настраиваемое) время после последнего обращения
+- Идентификатор сессии либо помещается в `cookie`, либо добавляется к URL. Если удалить этот идентификатор, то сервер создаст новую сессию
+- В экземпляр `HttpSession` можно помещать общую для этой сессии информацию (`getAttribute` и `setAttribute`)
+- Сессия привязана к конкретному приложению, у разных приложений - разные сессии
+- В распределенном окружении обеспечивается сохранение целостности данных в HTTP-сессии
+```Java
+public class SimpleSession extends HttpServlet {
+ @Override
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ response.setContentType("text/html");
+ PrintWriter out = response.getWriter();
+ HttpSession session = request.getSession();
+
+ out.println("");
+ ...
+ out.println("session id: " + session.getId());
+ out.println("session timeout: " + session.getMaxInactiveInterval());
+ session.setMaxInactiveInterval(20*60);
+ out.println("new session timeout: " + session.getMaxInactiveInterval());
+ ...
+ out.println("");
+ }
+}
+```
+## Диспетчиризация запросов сервлетами
+- Сервлеты могут делегировать обработку запросов другим ресурсам (сервлетам, JSP, HTML-страницам)
+- Диспетчеризация осуществляется с помощью реализаций интерфейса `javax.servlet.RequestDispatcher`
+- Два способа получения `RequestDispatcher` - через `ServletRequest` (абсолютный или относительный URL) и `ServletContext` (только абсолютный URL)
+- Два способа делегирования - `forward` и `include`
+ - `forward` - используется `RequestDispatcher`, сервер передает запрос другому сервлету или JSP-странице внутри себя, не говоря об этом браузеру
+ - `include` - используется `response.sendRedirect()`, сервер не передает запрос внутри себя, а говорит браузеру куда сходить (статус-код: 302), url в браузере меняется
+```Java
+public class MyServlet extends HttpServlet {
+ @Override
+ public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
+ RequestDispatcher dispatcher = request.getRequestDispatcher("index.jsp");
+ dispatcher.forward(request, response);
+ }
+}
+```
+## Фильтры запросов
+- Фильтры позволяют осуществлять пред- и постобработку запросов до и после передачи их ресурсу (сервлету, JSP или HTML-странице)
+- Пример предобработки - допуск только авторизованных пользователей
+- Пример постобработки - запись в лог времени обработки запроса
+- Реализуют интерфейс `javax.servlet.Filter`
+- Ключевой метод `doFilter`
+- Метод `doFilter` класса `FilterChain` передает управление следующему фильтру или целевому ресурсу, таким образом возможна реализация последовательностей фильтров
+```Java
+public class MyFilter implements Filter {
+ @Override
+ public void init(FilterConfig arg0) throws ServletException {}
+
+ @Override
+ public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
+ PrintWrite out = resp.getWriter();
+ out.print("filter is invoked before");
+
+ chain.doFilter(req, resp); // sends to next resource
+
+ out.print("filter is invoked after);
+ }
+
+ @Override
+ public void destroy() {}
+}
+```
+Конфигурация похожа на конфигурацию сервлетов
+```xml
+
+
+ s1
+ HelloServlet
+
+
+
+ s1
+ /servlet1
+
+
+
+ f1
+ MyFilter
+
+
+
+ f1
+ /servlet1
+
+
+
+```
+> [!important] Порядок сверху вниз, но если использовать аннотации, то порядок недетерминирован
diff --git a/Веб/Клиент-сервер/Клиент-серверное взаимодействие.md b/Веб/Клиент-сервер/Клиент-серверное взаимодействие.md
index 7d1d62a..7016473 100644
--- a/Веб/Клиент-сервер/Клиент-серверное взаимодействие.md
+++ b/Веб/Клиент-сервер/Клиент-серверное взаимодействие.md
@@ -7,4 +7,5 @@
## Серверная обработка
- [Серверные сценарии](Серверные%20сценарии.md)
- [CGI](CGI.md)
-- [FastCGI](FastCGI.md)
\ No newline at end of file
+- [FastCGI](FastCGI.md)
+- [Java Servlets](Java%20Servlets.md)
\ No newline at end of file
diff --git a/Итмо/Лабы/Веб/Рубежка 1.md b/Итмо/Лабы/Веб/Рубежка 1.md
index 81d3027..94a5dd8 100644
--- a/Итмо/Лабы/Веб/Рубежка 1.md
+++ b/Итмо/Лабы/Веб/Рубежка 1.md
@@ -8,4 +8,4 @@
- [Еще](https://github.com/AppLoidx/Web-Development-Cheats/blob/master/itmo-university/module%20tests/ModuleTest1Questions.md) 2022 год
- [Задания](https://github.com/AppLoidx/Web-Development-Cheats/blob/master/itmo-university/module%20tests/ModuleTest1.md) на код 2022 года
- Прошлогодняя [рубежка](https://github.com/sub-myitmo/web-rubezhka1)
-- [Еще](https://invited-digit-866.notion.site/2022-53c853d396364002b29a1331dfc78bba#80cee9d88a03495ea134ec05a365d43c) заметки в notion от 2022 года
\ No newline at end of file
+- [Еще](https://invited-digit-866.notion.site/2022-53c853d396364002b29a1331dfc78bba#80cee9d88a03495ea134ec05a365d43c) заметки в notion от 2022 годар
\ No newline at end of file