Получение полного URL из HttpServletRequest в Java

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для создания полного URL на основе объекта HttpServletRequest необходимо скомбинировать схему, имя сервера, контекстный путь и URI запроса в единое целое. В случае наличия строки параметров запроса, её также следует включить. Имеет смысл проверить, потребуется ли включение номера порта: его стоит опустить при использовании стандартных портов HTTP или HTTPS. Возьмём в качестве примера следующий код:

Java
Скопировать код
HttpServletRequest request; // Предполагаем, что объект уже инициализирован

String scheme = request.getScheme(); // http или https
String serverName = request.getServerName(); // Доменное имя сервера
int serverPort = request.getServerPort(); // Номер порта на сервере
String contextPath = request.getContextPath(); // Контекстное имя веб-приложения
String servletPath = request.getServletPath(); // Путь к сервлету
String pathInfo = request.getPathInfo(); // Дополнительная информация о пути
String queryString = request.getQueryString(); // Параметры запроса после "?"

// Собираем все части URL воедино
String fullUrl = scheme + "://" + serverName +
    (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) +
    contextPath + servletPath +
    (pathInfo == null ? "" : pathInfo) +
    (queryString == null ? "" : "?" + queryString);

Данный метод динамично учитывает использование порта и наличие строки запроса для корректного составления URL.

Кинга Идем в IT: пошаговый план для смены профессии

Улучшим формирование URL с помощью StringBuilder

Применение StringBuilder в Java позволяет улучшить производительность при составлении строк, благодаря его изменяемости. Стоит подумать о использовании StringBuilder для более эффективного составления URL.

Java
Скопировать код
// Строим URL при помощи StringBuilder
StringBuilder urlBuilder = new StringBuilder();
urlBuilder.append(scheme).append("://")
        .append(serverName)
        .append(serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort)
        .append(contextPath)
        .append(servletPath)
        .append(pathInfo == null ? "" : pathInfo)
        .append(queryString == null ? "" : "?" + queryString);

// Получаем итоговый URL
String fullUrl = urlBuilder.toString();

Интригующие приёмы и скрытые опасности при формировании URL

Особенности работы с нестандартными портами

Будьте особенно внимательны при работе приложения на нестандартных портах: их следует добавлять в URL корректно.

Обработка закодированных строк запроса

Спецсимволы в строке запроса требуют особых подходов к кодированию:

Java
Скопировать код
String encodedQuery = URLEncoder.encode(request.getQueryString(), "UTF-8");
// Теперь 'encodedQuery' можно непринуждённо добавлять к URL

Возможности использования UriComponentsBuilder

Если вы работаете с фреймворком Spring, UriComponentsBuilder может стать полезным инструментом:

Java
Скопировать код
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(request.getRequestURL().toString());
if (queryString != null) {
    builder.query(queryString);
}
String fullUrl = builder.toUriString();

Данный класс автоматически обеспечивает корректность кодировки.

Взаимодействие с различными контейнерами сервлетов

Разница между контейнерами сервлетов (такими как Tomcat, Jetty и пр.) может влиять на формирование URL, поэтому необходимо провести тестирование.

Визуализация

Вот компоненты, которые нужно собрать в пазл URL:

  • Схема: request.getScheme() + "://"
  • Имя сервера: request.getServerName()
  • Порт: ":" + request.getServerPort()
  • Контекстный путь: request.getContextPath()
  • Путь сервлета: request.getServletPath()
  • Дополнительная информация пути: request.getPathInfo()
  • Строка запроса: "?" + request.getQueryString()

Примечание: Порт и строку запроса следует добавлять только при их наличии

Стандартные сценарии и профессиональные рекомендации

Работа через прокси-сервер или балансировщик нагрузки

Используйте заголовки X-Forwarded-* для точного определения реального URL:

Java
Скопировать код
String trueScheme = request.getHeader("X-Forwarded-Proto");
String trueServerName = request.getHeader("X-Forwarded-Host");

Передача идентификатора сессии в URL

Для сохранения идентификатора сессии используйте HttpServletResponse.encodeURL(fullUrl).

Безопасность

Будьте осторожны в отношении возможных уязвимостей при использовании полного URL, основанного на пользовательском вводе.

Полезные материалы

  1. Обсуждение на Stack Overflow о формировании полного URL с использованием HttpServletRequest.
  2. Официальная документация HttpServletRequest.
  3. Документация Spring – ServletRequestAttributes.
  4. Руководство DigitalOcean по извлечению параметров URL в сервлетах.
  5. Учебник от Tutorialspoint по работе с клиентскими HTTP запросами в сервлетах.