Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

HTTP-сессия Java: Веб-технологии

Каждая HTTP-сессия определяется двумя вещами:

  • Запросом от клиента (браузера)
  • Ответом от сервера

Во фреймворках запрос и ответ обычно представляются двумя объектами — request и response.

Javalin тут пошел немного другим путем и объединил все в объекте ctx, который передается каждому обработчику. Через этот объект можно получить любую информацию из HTTP-запроса или добавить данные в HTTP-ответ. В этом уроке вы узнаете, как работать с объектом ctx и разберетесь, как устроена HTTP-сессия в этом случае.

Response

Метод ctx.result() формирует тело ответа:

app.get("/", ctx -> {
    ctx.result("Hello World");
});

По умолчанию данные отдаются с заголовком Content-Type: text/plain. Даже если мы передадим в ответе HTML, тип контента все равно не поменяется. Дело в том, что Javalin не анализирует, что мы отдаем. Поэтому нам придется поменять тип:

app.get("/", ctx -> {
    ctx.contentType("text/html");
    ctx.result("<h1>Hello Hexlet</h1>");
});

Если данные нужно отдать в виде JSON, то можно использовать метод ctx.json(). Он формирует JSON и устанавливает Content-Type со значением, равным json:

app.get("/", ctx -> {
    // Какой-то код формирования object
    ctx.json(object);
});

Кроме тела ответа, можно еще установить заголовки и поменять код ответа:

app.get("/", ctx -> {
    ctx.status(403);
    ctx.header("KEY", "value");
});

Еще мы можем выполнить редирект:

app.get("/admin", ctx -> {
    // Указываем статус вторым параметром
    ctx.redirect("/", HttpStatus.forStatus(302));
});

Request

Данные запроса можно извлечь множеством методов. Обычно такие вещи смотрят по необходимости, поэтому заучивать их смысла нет. Рассмотрим несколько самых базовых методов:

app.get("/", ctx -> {
    ctx.body(); // Тело запроса
    ctx.bodyAsClass(clazz); // Тело запроса, сконвертированное из JSON в объект
    ctx.header("Content-Type"); // Заголовок

    ctx.uploadedFile("name"); // Загруженный файл

    ctx.queryParamMap(); // Все параметры запросов
    ctx.queryParam("name"); // Параметр запроса
    ctx.formParamMap(); // Все параметры формы
    ctx.formParam("name"); // Параметр формы
});

Параметры запроса

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

Это связано с тем, что они используются для разных вспомогательных целей — например, параметр page обозначает страницу просматриваемого списка. В такой ситуации обработчик один и тот же, а вот данные — разные. Представим, что у нас есть вот такой код:

app.get("/users", ctx -> {
    // Отдаем обратно url + query params
    ctx.result(ctx.fullUrl());
});

А теперь посмотрим, что он выводит в лог в ответ на разные запросы из браузера:

/users
Request: GET [/users]
    Matching endpoint-handlers: [GET=/users]
    QueryString: null
    QueryParams: {}
Response: [200 OK], execution took 2.34 ms
    http://localhost:7070/users

/users?page=3
Request: GET [/users]
    Matching endpoint-handlers: [GET=/users]
    QueryString: page=3
    QueryParams: {page=[3]}
Response: [200 OK], execution took 0.29 ms
    http://localhost:7070/users?page=3

Во всех этих случаях фреймворк вызовет один и тот же обработчик, связанный с маршрутом /users. Фреймворк автоматически разбирает эти параметры и дает к ним удобный доступ через методы контекста:

app.get("/users", ctx -> {
    var page = ctx.queryParam("page");
});

Параметры запроса не связаны с методом HTTP. Они могут приходить как на GET-запросы, так и на все остальные:

// post
app.post("/users", ctx -> {
    var page = ctx.queryParam("page");
});

Автоматическая конвертация

В примере ниже вы видите переменную page типа строка:

app.get("/users", ctx -> {
    var page = ctx.queryParam("page");
});

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

Поэтому их нужно преобразовывать в строки. Для удобства работы Javalin предоставляет механизм для автоматической конвертации в нужный тип данных:

app.get("/users", ctx -> {
    var page = ctx.queryParamAsClass("page", Integer.class).get();
});

Но даже этого бывает мало. Для примера представим, что страница не установлена. В таком случае мы должны задать значение по умолчанию, равное единице. Javalin позволяет это сделать:

app.get("/users", ctx -> {
    var page = ctx.queryParamAsClass("page", Integer.class).getOrDefault(1);
});

Самостоятельная работа

  1. Откройте свой проект hexlet-javalin
  2. Добавьте туда обработчик, который будет обрабатывать GET-запросы по адресу /hello и выводить приветствие. Обработчик должен использовать параметр запроса name и приветствовать пользователя по имени. Например, при запросе GET /hello?name=John нужно вывести Hello, John! или Hello, World!, если параметра нет
  3. Запустите приложение и откройте страницу в браузере
  4. Поэкспериментируйте с разными значениями параметра запроса
  5. Залейте изменения на GitHub

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
Научитесь разработке веб-приложений, сайтов и программного обеспечения на языке Java, программируйте и используйте структуры данных
10 месяцев
с нуля
Старт 28 ноября

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»