Работа с формами в Spring MVC

Пожалуй ни одно web приложение не обходится без форм для отправки данных на сервер. Рассмотрим как работает механизм web форм в Spring MVC.

Простая форма

Для начала рассмотрим обработку простой формы. Пусть эта форма, в качестве примера, отправляет на сервер имя человека, которое тот будет вводить в специальное поле. Это типовая задача, которая встречается повсеместно (регистрация пользователя в системе, покупателя в интернет магазине и т. д.). Обычно помимо имени вводят и другие сведения. Но в нашем примере мы пока ограничимся только именем.

В начале создадим класс, с которым будут сопоставляться данные формы. По сути, это будет её модель.

Создадим саму форму для отправки данных. Форму мы будем создавать при помощи библиотеки тегов форм Spring. Как и все библиотеки серверных тегов она подключается сразу после тега page с помощью оператора taglib.

Теги из библиотек вызываются с помощью специального префикса. По традиции, для библиотеки тегов форм Spring задаётся префикс form.

Для создания формы нам потребуется тег form. В его атрибуте method укажем метод POST, а в modelAttribute название созданного нами класса с маленькой буквы.

Имя будем вводить при помощи серверного тега input, указав в атрибуте path имя поля, в котором хранится имя. Это очень важно, так как в противном случае Spring не сможет связать данные формы с моделью.

Как всё это выглядит в коде можно увидеть на приведённом ниже примере.

Теперь, когда у нас есть модель и представление с формой которая отправляет данные на сервер, нам необходимо на стороне сервера эти данные получить и обработать.

Для этого нам необходим соответствующий контроллер.

Приведённый контроллер содержит два метода. Первый (addMan) отрабатывает при GET запросе и выводит созданную ранее страницу с формой. Второй же (addManPost) получает данные поступившие на сервер от формы и выполняет их обработку.

Данные формы принимаются методом addManPost в виде параметра mansForm.

Из поступивших данных, в качестве примера, в локальную переменную manNamer извлекается введённое имя. Вместо этого можно выполнить и более сложные действия. Например, валидацию (будет рассматриваться в отдельной статье) или сохранение в базе данных.

После завершения всех операций метод просто выполняет перенаправление (редирект) на страницу с исходной формой.

Мы изучили работу простых форм на примере единичного текстового поля. Но, даже если форма содержит другие поля (пароль, дата и т. д.), работа с ними полностью аналогична с поправкой на имена конкретных полей и типы данных.

Однако вышесказанное не относится к процедуре загрузки файлов на сервер.

Если форма содержит поля тип file их следует обрабатывать особым способом, который будет описан далее.

Форма с загрузкой файлов

Если форма предназначена для загрузки файлов, это затрагивает не только неё, но и на всё web приложение в целом.

Дело в том, что загруженные файлы необходимо где-то хранить. Загружать их в БД чаще всего не оправдано. Поэтому в качестве хранилища используется специальная папка, но о её существовании приложение ещё должно каким-то образом узнать.
Также для загрузки файлов необходимо подключить специальный компонент, который будет позволяет приложению обрабатывать такие формы.

Так что перед тем, как приступить непосредственно к реализации загрузки, нам нужно выполнить три подготовительных шага.

Первый — создание папки для хранения загружаемых файлов и назначение для неё необходимых прав (обычно всё это делается стандартными средствами операционной системы). Второй — описание этой папки в приложении, чтобы он смогло её найти и загружать туда файлы. Третий — подключение недостающего компонента.

Последнее можно сделать либо с помощью базы данных (например, хранить соответствующий путь в таблице настроек) либо с помощью JNDI.

В случае JNDI в папке META-INF создаётся файл context.xml, в котором путь к папке прописывается в директиве Environment, как это показано ниже.

Атрибут name состоит из двух частей. Первая часть (fileStorage), говорит на о том, что данный параметр определяет папку, а второй, это собственно имя параметра.

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

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

Для этого добавим следующую зависимость для Maven:

А, в файле dispatcher-servlet.xml добавим следующий компонент:

Доработаем форму и её модель таким образом, чтобы с их помощью можно было передавать файлы на сервер.

В качестве примера, пусть у пользователя появится возможность загрузить свой аватар.

В Spring MVC загружаемые файлы представлены классом MultipartFile. Добавим в модель соответствующее поле для хранения файла аватара.

Отредактируем форму.

У тега form добавим атрибут enctype, чтобы обеспечить поддержку передачи файлов. А, внутри формы создадим новый тег input, который будет иметь тип file. В атрибуте path этого тега укажем имя поля модели, в котором будет сохранён файл аватара для передачи на сервер.

Код страницы с доработанной формой приведён ниже.

В результате мы уже можем отправлять файлы на сервер. Но, нам ещё нужно их получить и сохранить в нашу папку, которую мы создали в самом начале.

Для того чтобы в контроллере получить путь папке для сохранения файлов достаточно объявить в нём строковое поле с аннотацией @Resource, указав в качестве параметра имя mappedName имя ранее созданного параметра JNDI.

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

Последнюю можно выполнить всего в одной строке кода при промощи метода transferTo класса MultipartFile, который переместит загруженный файл из временной папки в целевую.

Разумеется, что при сохранении в постоянной папке файл должен иметь соответствующее имя. Для этого к пути папки для сохранения, добавим его исходное имя, которое можно получить с помощью метода getOriginalFilename класса MultipartFile.

Ниже приведён код контроллера после всех доработок.

Стоит обратить внимание на то, что при работе с загруженным файлом нам не требуется ничего знать о его местоположении в временной папке и пр. Файл доступен сразу посредство соответствующих методов классов MultipartFile и модели формы.

После сохранения файла с ним можно, как вариант, сохранить путь к нему в базе данных, чтобы впоследствии отображать аватар рядом с именем пользователя на web странице.

Примеры, рассмотренные в этой статье выполнены с использованием Spring 5, но они вполне могут быть совместимы и с другими версиями Spring.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *