Compare commits

...

14 Commits

Author SHA1 Message Date
roma-dxunvrs c513ce326f web fix 2
deploy / Pull and Restart (push) Successful in 17s
2026-11-02 22:45:19 +03:00
roma-dxunvrs 9361978648 web fix
deploy / Pull and Restart (push) Successful in 16s
2026-11-02 22:42:10 +03:00
roma-dxunvrs 8f42d4a320 web add some tasks for 1 milestone
deploy / Pull and Restart (push) Successful in 16s
2026-11-02 17:27:14 +03:00
roma-dxunvrs c654fcd9c2 web add info for 1 milestone
deploy / Pull and Restart (push) Successful in 18s
2026-10-31 22:26:37 +03:00
roma-dxunvrs 2ec4a7e7db web add lectures for 1 milestone
deploy / Pull and Restart (push) Successful in 18s
2026-10-30 19:01:08 +03:00
roma-dxunvrs 283660b9ef web update milestone 1
deploy / Pull and Restart (push) Successful in 16s
2026-10-29 14:49:49 +03:00
roma-dxunvrs f0817da47e web update index.md
deploy / Pull and Restart (push) Successful in 17s
2026-10-29 14:37:34 +03:00
roma-dxunvrs c9bc96dafc web milestone 1
deploy / Pull and Restart (push) Successful in 16s
2026-10-29 14:35:00 +03:00
roma-dxunvrs 6538742678 Update helios guide
deploy / Pull and Restart (push) Successful in 17s
2026-10-25 22:15:31 +03:00
roma a7f8e74f3f revert 9b0c9f4b4a
deploy / Pull and Restart (push) Successful in 15s
revert Merge pull request 'Kotlin guide ready' (#5) from AK_Additions into master

Reviewed-on: #5
2026-10-20 13:43:08 +03:00
roma 9b0c9f4b4a Merge pull request 'Kotlin guide ready' (#5) from AK_Additions into master
deploy / Pull and Restart (push) Successful in 16s
Reviewed-on: #5
2026-10-20 13:38:05 +03:00
Aklivtsov b62e54bbb0 Merge branch 'master' into AK_Additions 2026-10-20 12:55:54 +03:00
Aklivtsov 6853ada348 Kotlin guide done. (20.10.26) 2026-10-20 12:54:25 +03:00
Aklivtsov da3ad9dd1a Added kotlin guide. (WIP) (15.10.26) 2026-10-15 00:24:21 +03:00
8 changed files with 556 additions and 5 deletions
+2 -1
View File
@@ -1,4 +1,5 @@
Повседневные или почти вещи Повседневные или почти вещи
- [Linux](Linux.md) - [Linux](Linux.md)
- [Полезные утилиты и сайты](Полезные%20утилиты%20и%20сайты.md) - [Полезные утилиты и сайты](Полезные%20утилиты%20и%20сайты.md)
- [VPN](VPN.md) - [VPN](VPN.md)
- [Миграция с npm на npmplus](Миграция%20с%20npm%20на%20npmplus.md)
@@ -0,0 +1,2 @@
Может меняться, актуальная информация в [ридми](https://github.com/ZoeyVid/NPMPlus#migration-from-upstreamvanilla-nginx-proxy-manager)
1.
@@ -1,3 +1,47 @@
- Все запросы могут обрабатываться одним процессом CGI-программы - Все запросы могут обрабатываться одним процессом CGI-программы
- Веб-сервер взаимодействует с процессом через UNIX Domain Sockets или TCP/IP (а не через stdin и stdout) - Веб-сервер взаимодействует с процессом через 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 = """
<html>...</html>
""";
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);
}
```
@@ -0,0 +1,306 @@
## Платформа 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("<html>");
...
out.println("</html>");
}
}
```
## Конфигурация сервлета
Конфигурирование происходит в `WEB-INF/web.xml` (есть конечно аннотации, но это слишком современно). В `WEB-INF/classes` должны лежать скомпилированные джава-классы
```xml
<!-- Регистрируем сервлет -->
<servlet>
<servlet-name>SampleServlet</servlet-name>
<servlet-class>org.itmo.sample.SampleServlet></servlet-class>
</servlet>
<!-- Маппинг -->
<servlet-mapping>
<servlet-name>SampleServlet</servlet-name>
<url-pattern>/sample</url-pattern>
</servlet-mapping>
```
Полный файл `web.xml`
```xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<!-- Регистрируем сервлет -->
<servlet>
<servlet-name>SampleServlet</servlet-name>
<servlet-class>org.itmo.sample.SampleServlet></servlet-class>
</servlet>
<!-- Маппинг -->
<servlet-mapping>
<servlet-name>SampleServlet</servlet-name>
<url-pattern>/sample</url-pattern>
</servlet-mapping>
</web-app>
```
## Жизненный цикл сервлета
- Жизненным циклом управляет веб-контейнер
- Методы, управляющие жизненным циклом, должен вызывать только веб-контейнер
### 1. Загрузка класса сервлета
Проверяются пути: `WEB-INF/classes/`, `WEB-INF/lib/*.jar`, стандартные классы Java SE и классы веб-контейнера
```xml
<servlet>
<servlet-name>SampleServlet</servlet-name>
<servlet-class>org.itmo.sample.SampleServlet></servlet-class>
<!-- Этот параметр можно получить через унаследованный метод getInitParametr(paramName); -->
<init-param>
<param-name>say-hello</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
```
### 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
<context-param>
<param-name>dname</param-name>
<param-value>org.postgresql.Driver</param-value>
</context-param>
```
## 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("<html>");
...
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("</html>");
}
}
```
## Диспетчиризация запросов сервлетами
- Сервлеты могут делегировать обработку запросов другим ресурсам (сервлетам, JSP, HTML-страницам)
- Диспетчеризация осуществляется с помощью реализаций интерфейса `javax.servlet.RequestDispatcher`
- Два способа получения `RequestDispatcher` - через `ServletRequest` (абсолютный или относительный URL) и `ServletContext` (только абсолютный URL)
- Два способа делегирования - `forward` и `include` (в обоих случаях url не меняется)
- `forward` - полностью отдает запрос другому сервлету или JSP-странице
- `include` - включает в себя обработку запроса от другого сервлета или JSP-страницы
- Полный редирект (меняется url в браузере, статус-код 302) - `response.sendRedirect(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
<web-app>
<servlet>
<servlet-name>s1</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>s1</servlet-name>
<url-pattern>/servlet1</url-pattern>
</servlet-mapping>
<filter>
<filter-name>f1</filter-name>
<filter-class>MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>f1</filter-name>
<url-pattern>/servlet1</url-pattern>
</filter-mapping>
</web-app>
```
> [!important] Порядок сверху вниз, но если использовать аннотации, то порядок недетерминирован
## Конфигурация аннотациями
Конфигурация можно писать прямо в Java коде. Tomcat сам сканирует классы и регистрирует компоненты
### Сервлеты
`@WebServlet` - замена `<servlet>` и `<servlet-mapping>`
```Java
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
@WebServlet("/api/check")
public class CheckServlet extends HttpServlet {}
```
Продвинутый вариант
```Java
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.annotation.WebInitParam;
@WebServlet(
name = "MyCheckLogic", // Аналог <servlet-name>
urlPatterns = {"/api/check", "/run"},// Можно привязать сразу несколько URL!
loadOnStartup = 1, // Запустить при старте сервера
initParams = { // Замена <init-param>
@WebInitParam(name = "adminEmail", value = "admin@itmo.ru"),
@WebInitParam(name = "maxSize", value = "5000")
}
)
public class CheckServlet extends HttpServlet { ... }
```
### Фильтры
`@WebFilter` - замена `<filter>` и `<filter-mapping>`
```Java
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.Filter;
@WebFilter(urlPatterns = "/*")
public class EncodingFilter implements Filter {}
```
## Справка по параметрам/аттрибутам
### Внешние данные от пользователя
- `getParameter()`
- Приходит от браузера/клиента по сети
- Возвращает `String` или `null`
- Находится в URL или в теле запроса
- Приоритет у первого query параметра
- `String user = request.getParameter("red");`
- Если несколько `String[] colors = request.getParameterValues("color");`
- Никакого `set` не существует
### Внутренние данные приложения
- `getAttribute()` и `setAttribute()`
- Записывается Java-кодом на сервере. Браузер ничего не знает
- Возвращает `Object` или `null`, поэтому требует явного каста
- Внутри запроса `HttpServletRequest` - живет 1 запрос
- Используется для передачи из Model в View
- `request.setAttribute("myUser", new User()); User u = (User) request.getAttribute("myUser");`
- Внутри сессии `HttpSession` - живет пока юзер на сайте
- `HttpSession session = request.getSession();`
- `session.setAttribute("role", "ADMIN")`;
- `String role = (String) session.getAttribute("role");`
- Внутри контекста `ServletContext` - живет пока работает сервер
- `ServletContext context = getServletContext();`
- `context.setAttribute()` и `context.getAttribute()`
### Метаданные HTTP
- `getHeader()`
- Приходит от браузера в служебных строках
- Возвращает `String` или `null`
- `request.getHeader("Authorization");`
### Статические настройки из файла конфигурации
- `getInitParameter()`
- Читается сервером из файла `web.xml` или аннотаций
- Возвращает `String` или `null`
- `String email = getServletConfig().getInitParameter("email");` - для сервлета
- `String dbUrl = getServletContext().getInitParameter("dbUrl");` - для всех сервлетов
@@ -7,4 +7,5 @@
## Серверная обработка ## Серверная обработка
- [Серверные сценарии](Серверные%20сценарии.md) - [Серверные сценарии](Серверные%20сценарии.md)
- [CGI](CGI.md) - [CGI](CGI.md)
- [FastCGI](FastCGI.md) - [FastCGI](FastCGI.md)
- [Java Servlets](Java%20Servlets.md)
+36 -3
View File
@@ -1,3 +1,13 @@
## Удобный вход
Когда уже есть ssh-ключ ввод пароля становится не обязательным, но порт и имя пользователя с доменом вводить приходится
Можно добавить в `.ssh/config`
```
Host helios
HostName se.ifmo.ru
User sXXXXXX
Port 2222
```
Теперь вход будет по `ssh helios`
## Смена оболочки (на zsh) ## Смена оболочки (на zsh)
Скачивать свои пакеты нельзя, но благо zsh уже скачан (в `/usr/local/bin/zsh`) Скачивать свои пакеты нельзя, но благо zsh уже скачан (в `/usr/local/bin/zsh`)
Менять оболочку нормальным способом через `chsh` тоже нельзя, поэтому используем такой костыль: создаем в домашней папке `.bash_profile` и добавляем туда: Менять оболочку нормальным способом через `chsh` тоже нельзя, поэтому используем такой костыль: создаем в домашней папке `.bash_profile` и добавляем туда:
@@ -9,9 +19,32 @@ fi
``` ```
Теперь у нас zsh Теперь у нас zsh
### oh-my-zsh ### oh-my-zsh
Чтобы настроить zsh как [тут](../Other/Linux.md), также клонируем репу с oh-my-zsh, вылетит ошибка прав, поэтому конфиг копируем сами 1. Устанавливаем oh-my-zsh
```bash
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
```
2. Скорее всего вылетит ошибка прав, поэтому дефолтный конфиг копируем сами
```bash ```bash
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
``` ```
Скачиваем плагины и тему p10k через гит, пишем их в `.zshrc` как в [гайде](../Other/Linux.md) 3. Скачиваем два базовых дополнения
Готово! ```bash
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
```
4. Скачиваем тему `powerlevel10k`
```bash
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git "${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k"
```
5. Меняем `.zshrc`
```
...
ZSH_THEME="powerlevel10k/powerlevel10k"
...
plugins=(git zsh-autosuggestions zsh-syntax-highlighting)
...
```
6. Применяем через `source .zshrc`, настраиваем тему
7. Для того чтобы заново запустить настройку темы: `p10k`
@@ -0,0 +1,163 @@
> [!hint]
> В старых рубежках может быть актуально все, кроме вопросов о PHP
> Нужно знать весь материал лекций до 3.2
- [Файл](https://docs.google.com/document/d/11ccQ3H0NNVfMtdiKW1Zxq0woOfk9o-2p0VcKhj4Bz_A/edit?tab=t.0#heading=h.5xocd8wh7ln) для подготовки (от 2025 года)
- [Разбор](https://docs.google.com/document/d/1c-9ci-rwhO1EB7cTknReMxZEzvrdazObXMiVpq9Ov3o/edit?tab=t.0) 2022 года
- [Билеты](https://docs.google.com/document/d/1EBdskbN0v1942zgW2qu_datoyJ0yoVxBx69D4sPemyk/edit?tab=t.0) 2022 года
- [Заметки](https://grove-spandex-678.notion.site/1-fe90f5db40b6477ebd439b9f3229e6ee) в notion
- [Еще](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 года
## Разбор типовых задач
### 1. Сделать слошную синюю границу 2px у текстового ввода внутри класса `auth_form` при фокусе
```CSS
.auth-form input[type="text"]:focus {
border: 2px solid blue;
}
```
### 2. Написать миксин на SCSS и использовать его в классе `user-card`, добавить вложенный стиль при наведении курсора
```SCSS
@mixin card-style($bg-color: #ffffff) {
background-color: $bg-color;
border-radius: 8px;
}
.user-card {
@include card-style;
&:hover {
opacity: 0.8;
}
}
```
### 3. Написать код на JS, который читает поле ввода, если там число, то выводит удвоенное значение в консоль, иначе сообщение об ошибке в alert
```JavaScript
const form = document.querySelector("#calcForm");
const input = document.querySelector("#numInput");
form.addEventListener("submit", (event) => {
event.preventDefault();
const text = input.value;
const number = parseFloat(text);
if (isNan(number)) {
alert("Введите число");
} else {
console.log(number*2);
}
});
```
### 4. Написать асинхронную функцию, которая делает POST запрос с координатами точки и возвращает json-ответ
```JavaScript
async function sendCoordinates(x, y) {
const url = "/api/points";
const data = {x: x, y: y};
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error();
}
const res = await response.json();
return res;
}
```
### 5. Через JQuery поменять элемент с классом `content-box` и вывести значение из поля ввода с id `statusInput`
```JavaScript
$("#toggle-btn").on("click", () => {
$(".content-box").slideUp().css("color", "red");
console.log($("#statusInput").val());
});
```
### 6. Написать FCGI-сценарий, который проверяет строку запроса, если там есть слово `ping`, то выводит `pong`. Иначе возвращает 400 ошибку
```Java
public class Main {
public static void main(String[] args) {
FCGIInterface fcgi = new FCGIInterface();
while (fcgi.accept() >= 0) {
if (FCGIInterface.request == null) {
continue;
}
String query = FCGIInterface.request.getProperty("QUERY_STRING");
if (query != null && query.contains("ping")) {
System.out.println("Content-Type: text/plain\n");
System.out.println("ping");
} else {
System.out.println("Status: 400 Bad Request");
System.out.println("Content-Type: text/plain\n");
System.out.println("Bad Request");
}
}
}
}
```
### 7. Написать сервлет, который считает количество заходов пользователя на сайт через HTTP-сессии
```Java
@WebServlet("/counter")
public class MyServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) {
HttpSession session = req.getSession();
if (session.getAttribute("visitCount") == null) {
session.setAttribute("visitCount", 0);
}
int count = (Integer) session.getAttribute("visitCount") + 1;
session.setAttribute("visitCount", count);
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
out.println("Вы посетили страницу %d раз".format(count));
}
}
```
### 8. Написать сервлет, который проверяет роль пользователя и пропускает, если он админ, иначе переадресация на сообщение об ошибке
```Java
@WebServlet("/task")
public class MyServlet extends HttpServlet {
@Override
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
String role = req.getParameter("role");
if (role == null || !role.equals("admin")) {
res.sendRedirect("/access-denied.html");
}
req.setAttribute("secretData", "TopSecret123");
RequestDispatcher disp = req.getRequestDispatcher("/admin.jsp");
disp.forward(req, res);
}
}
```
### 9. Написать фильтр, который пропускает пользователя дальше, только если в его сессии есть атрибут `user`
```Java
@WebFilter("/secure/*")
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpRes = (HttpServletResponse) res;
HttpSession session = httpReq.getSession();
if (session.getAttribute("user")==null) {
httpRes.setContentType("text/plain");
httpRes.setStatus(403);
hhtpRes.getWriter().println("Вход воспрещен");
} else {
chain.doFilter(req, res);
}
}
}
```
### 10. Реализовать функцию на JavaScript, которая будет закрывать текущее окно, если в нем открыт гугл
```JavaScript
function closeWindow() {
if (window.location.href === "https://www.google.ru") {
window.close();
}
}
```
### 11. Открытие в новом окне браузера гугла через JS
```JavaScript
window.open("http://google.com", "newwin", "width=1200,height=600");
```
@@ -9,6 +9,7 @@
Проводит практик Проводит практик
1 - конец октября 1 - конец октября
2 - декабрь 2 - декабрь
[Материалы](../Лабы/Веб/Рубежка%201.md) по первой рубежке
## Лабы ## Лабы
На сайте великого тюнита, их 4 На сайте великого тюнита, их 4
[Деплой лаб](../Лабы/Веб/Деплой%20лаб.md) - гайд на деплой лаб [Деплой лаб](../Лабы/Веб/Деплой%20лаб.md) - гайд на деплой лаб