1. Обзор

В этой быстрой статье мы рассмотрим встроенные утилиты веб-запросов в Spring MVC — WebUtils, ServletRequestUtils.

2. WebUtils и ServletRequestUtils

Почти во всех приложениях мы сталкиваемся с ситуациями, когда нам нужно получить некоторые параметры из входящего HTTP-запроса.

Для этого нам пришлось создать несколько очень сложных сегментов кода, таких как:

Используя WebUtils и ServletRequestUtils, мы можем сделать это всего одной строкой кода.

HttpSession session = request.getSession(false);
if (session != null) {
    String foo = session.getAttribute("parameter");
}

String name = request.getParameter("parameter");
if (name == null) {
    name = "DEFAULT";
}

Чтобы увидеть, как работают эти утилиты, давайте создадим простое веб-приложение.

3. Примеры страниц

Нам необходимо создать образцы страниц, чтобы можно было связать URL-адреса. Мы будем использовать Spring Boot и Thymeleaf в качестве нашего механизма шаблонов. Нам нужно добавить необходимые зависимости для них.

Создадим страницу с простой формой:

Как видим, мы создаем форму для инициирования POST-запроса.

<form action="setParam" method="POST">
    <h3>Set Parameter:  </h3>
    <p th:text="${parameter}" class="param"/>
    <input type="text" name="param" id="param"/>
    <input type="submit" value="SET"/>
</form>
<br/>
<a href="other">Another Page</a>

Также есть одна ссылка, которая перенаправит пользователей на следующую страницу, где мы покажем отправленный параметр из атрибута сеанса.

И давайте создадим вторую страницу:

4. Использование

Parameter set by you: <p th:text="${parameter}" class="param"/>

Теперь, когда мы закончили создание представлений, давайте создадим наш контроллер и воспользуемся ServletRequestUtils и получим параметр запроса:

~~ ~ Обратите внимание, как мы используем API getStringParameter в ServletRequestUtils для получения имени параметра запроса param; параметру запроса будет присвоено значение по умолчанию, если в контроллер не поступает никакого значения.

@PostMapping("/setParam")
public String post(HttpServletRequest request, Model model) {
    String param 
      = ServletRequestUtils.getStringParameter(
        request, "param", "DEFAULT");

    WebUtils.setSessionAttribute(request, "parameter", param);

    model.addAttribute("parameter", "You set: " + (String) WebUtils
      .getSessionAttribute(request, "parameter"));

    return "utils";
}

И, конечно же, обратите внимание на setSessionAttribute API из WebUtils, используемый для установки значения атрибута сеанса. Нам не нужно явно проверять, существует ли сеанс или ссылка в ванильном сервлете. Spring настроит его на лету.

Таким же образом создадим другой обработчик, который будет показывать следующий атрибут сессии:

Это все, что нам нужно для создания нашего приложения.

@GetMapping("/other")
public String other(HttpServletRequest request, Model model) {
    
    String param = (String) WebUtils.getSessionAttribute(
      request, "parameter");
    
    model.addAttribute("parameter", param);
    
    return "other";
}

Здесь следует отметить, что ServletRequestUtils имеет несколько замечательных встроенных функций, которые автоматически преобразуют тип параметра запроса в зависимости от наших потребностей.

Вот как мы можем преобразовать параметр запроса в Long:

Точно так же мы можем преобразовать параметр запроса в другие типы:

Long param = ServletRequestUtils.getLongParameter(request, "param", 1L);

Еще один момент, который следует отметить, это то, что ServletRequestUtils имеет другой метод getRequiredStringParameter( Запрос ServletRequest, имя строки) для получения параметра запроса. Разница в том, что если параметр не найден во входящем запросе, будет выброшено исключение ServletRequestBindingException. Это может быть полезно, когда нам нужно поиграть с критическими данными.

boolean param = ServletRequestUtils.getBooleanParameter(
  request, "param", true);

double param = ServletRequestUtils.getDoubleParameter(
  request, "param", 1000);

float param = ServletRequestUtils.getFloatParameter(
  request, "param", (float) 1.00);

int param = ServletRequestUtils.getIntParameter(
  request, "param", 100);

Ниже приведен пример фрагмента кода:

Мы также можем создать один простой тестовый пример JUnit для тестирования приложения:

try {
    ServletRequestUtils.getRequiredStringParameter(request, "param");
} catch (ServletRequestBindingException e) {
    e.printStackTrace();
}

5. Заключение

@Test
public void givenParameter_setRequestParam_andSetSessionAttribute() 
  throws Exception {
      String param = "testparam";
 
      this.mockMvc.perform(
        post("/setParam")
          .param("param", param)
          .sessionAttr("parameter", param))
          .andExpect(status().isOk());
  }

В этой статье мы видим, что использование WebUtils и ServletRequestUtils могут значительно уменьшить количество накладных расходов на стандартное кодирование. Однако, с другой стороны, это, безусловно, увеличивает зависимость от среды Spring, о чем следует помнить, если это вас беспокоит.

Как всегда, исходный код доступен на GitHub.

«