Этот туториал покажет, как обрабатывать отправку форм в Spring MVC. Мы определим контроллер для обработки загрузки страницы и отправки формы. Вы можете получить код на GitHub .
Предпосылки:
У вас должно быть рабочее Spring MVC Application. Если у вас еще нет настроенного рабочего приложения Spring MVC, следуйте этому руководству . Для этого урока мы создадим простую форму для подписки на рассылку. Форма будет иметь следующие поля:
- имя — поле ввода
- возраст — поле ввода
- электронная почта — поле ввода
- пол — выберите раскрывающийся список
- receiveNewsletter — флажок
- newsletterFrequency — выберите раскрывающийся список
Требования:
-
receiveNewsletterсписокreceiveNewsletterдолжен быть активным, только еслиreceiveNewsletterфлажокreceiveNewsletter - Мы не будем выполнять никаких проверок в этом примере (следите за обновлениями для будущего урока)
- Когда пользователь отправит форму, та же страница перезагрузится
- На перезагруженной странице должно отображаться сообщение о том, что отправка прошла успешно, и отображаются сохраненные значения
Когда мы закончим, у нас будет страница, которая выглядит следующим образом:
Во-первых, давайте настроим объект, который мы будем использовать для хранения информации подписчика. Создайте класс Subscriber в пакете com.codetutr.form . Это базовый Java-бин. Обратите внимание, что мы используем перечисления для хранения полей пола и частоты рассылки. Для простоты я определил перечисления в одном классе. Также обратите внимание, что мы определяем toString . Это просто, чтобы мы могли легко получить значения для печати после отправки.
Subscriber.java
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
package com.codetutr.form;public class Subscriber { private String name; private String email; private Integer age; private Gender gender; private Frequency newsletterFrequency; private Boolean receiveNewsletter; public enum Frequency { HOURLY, DAILY, WEEKLY, MONTHLY, ANNUALLY } public enum Gender { MALE, FEMALE } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Gender getGender() { return gender; } public void setGender(Gender gender) { this.gender = gender; } public Frequency getNewsletterFrequency() { return newsletterFrequency; } public void setNewsletterFrequency(Frequency newsletterFrequency) { this.newsletterFrequency = newsletterFrequency; } public Boolean getReceiveNewsletter() { return receiveNewsletter; } public void setReceiveNewsletter(Boolean receiveNewsletter) { this.receiveNewsletter = receiveNewsletter; } @Override public String toString() { return "Subscriber [name=" + name + ", age=" + age + ", gender=" + gender + ", newsletterFrequency=" + newsletterFrequency + ", receiveNewsletter=" + receiveNewsletter + "]"; }} |
Теперь давайте создадим контроллер. Создайте класс FormController в пакете com.codetutr.controller :
FormController.java
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package com.codetutr.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import com.codetutr.form.Subscriber;import com.codetutr.form.Subscriber.Frequency;@Controllerpublic class FormController { @ModelAttribute("frequencies") public Frequency[] frequencies() { return Frequency.values(); } @RequestMapping(value="form", method=RequestMethod.GET) public String loadFormPage(Model m) { m.addAttribute("subscriber", new Subscriber()); return "formPage"; } @RequestMapping(value="form", method=RequestMethod.POST) public String submitForm(@ModelAttribute Subscriber subscriber, Model m) { m.addAttribute("message", "Successfully saved person: " + subscriber.toString()); return "formPage"; }} |
Давайте посмотрим на несколько вещей в коде выше. Во-первых, обратите внимание, что оба обработчика запросов (методы, аннотированные @RequestMapping ) отображаются на один и тот же URL — «форму». Единственное отличие в сопоставлении состоит в том, что один обрабатывает HTTP-запрос GET, а другой — POST. Первый обработчик (для запроса GET) будет вызван, когда пользователь перейдет на страницу «формы», потому что он получит доступ к странице с помощью запроса GET. Обработчик POST вызывается при отправке формы (поскольку она будет отправлена через HTTP POST на URL-адрес «формы»). Конечно, вы можете отправить свою форму по любому URL-адресу, используя любой метод HTTP — просто убедитесь, что ваш обработчик соответствующим образом сопоставлен здесь.
Давайте посмотрим на обработчик GET. Требуется Model , которую мы заполняем пустым объектом Subscriber . Этот объект — то, что мы будем использовать для заполнения нашей формы. Здесь мы не устанавливаем никаких значений, но если мы хотим, скажем, установить по умолчанию флажок receiveNewsletter на true и установить частоту рассылки по умолчанию на почасовую, мы можем сделать:
|
1
2
3
4
|
Subscriber subscriber = new Subscriber();subscriber.setReceiveNewsletter(true);subscriber.setNewsletterFrequency(Frequency.HOURLY);m.addAttribute("subscriber", subscriber); |
Также обратите внимание, что если мы не добавим объект с именем «подписчик» в модель, Spring будет жаловаться, когда мы пытаемся получить доступ к JSP, потому что мы настроим JSP для привязки формы к атрибуту модели «подписчик». Вы увидите ошибку JSP: «Ни BindingResult, ни простой целевой объект для имени компонента« подписчик »недоступны в качестве атрибута запроса», и JSP не будет отображаться.
Последнее, на что нужно обратить внимание в коде контроллера, — это метод @ModelAttribute . Когда метод аннотируется с помощью @ModelAttribute , Spring запускает его перед каждым методом-обработчиком и добавляет возвращаемое значение в модель. Мы указали в аннотации, чтобы добавить значения частоты в модель как «частоты». Этот объект будет использоваться для заполнения раскрывающегося списка частоты рассылки в форме JSP. Вместо использования метода @ModelAttribute мы могли бы добавить следующую строку в каждый из обработчиков запросов:
|
1
|
m.addAttribute("frequencies", Frequency.values()) |
Наконец, давайте настроим JSP. Создайте файл с именем formPage.jsp в WEB-INF/view (или там, где вы настроили JSP):
formPage.jsp
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %><!DOCTYPE HTML><html> <head> <title>Sample Form</title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <style> body { background-color: #eee; font: helvetica; } #container { width: 500px; background-color: #fff; margin: 30px auto; padding: 30px; border-radius: 5px; box-shadow: 5px; } .green { font-weight: bold; color: green; } .message { margin-bottom: 10px; } label {width:70px; display:inline-block;} form {line-height: 160%; } .hide { display: none; } </style> </head> <body> <div id="container"> <h2>Subscribe to The Newsletter!</h2> <c:if test="${not empty message}"><div class="message green">${message}</div></c:if> <form:form modelAttribute="subscriber"> <label for="nameInput">Name: </label> <form:input path="name" id="nameInput" /> <br/> <label for="ageInput">Age: </label> <form:input path="age" id="ageInput" /> <br/> <label for="emailInput">Email: </label> <form:input path="email" id="emailInput" /> <br/> <label for="genderOptions">Gender: </label> <form:select path="gender" id="genderOptions"> <form:option value="">Select Gender</form:option> <form:option value="MALE">Male</form:option> <form:option value="FEMALE">Female</form:option> </form:select> <br/> <label for="newsletterCheckbox">Newsletter? </label> <form:checkbox path="receiveNewsletter" id="newsletterCheckbox" /> <br/> <label for="frequencySelect">Freq:</label> <form:select path="newsletterFrequency" id="frequencySelect"> <form:option value="">Select Newsletter Frequency: </form:option> <c:forEach items="${frequencies}" var="frequency"> <form:option value="${frequency}">${frequency}</form:option> </c:forEach> </form:select> <br/> <br/> <input type="submit" value="Submit" /> </form:form> </div> <script type="text/javascript"> $(document).ready(function() { toggleFrequencySelectBox(); // show/hide box on page load $('#newsletterCheckbox').change(function() { toggleFrequencySelectBox(); }) }); function toggleFrequencySelectBox() { if(!$('#newsletterCheckbox').is(':checked')) { $('#frequencySelect').val(''); $('#frequencySelect').prop('disabled', true); } else { $('#frequencySelect').prop('disabled', false); } } </script> </body></html> |
Давайте пройдемся по тегам формы, которые мы используем. Обратите внимание на строку в верхней части страницы: <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> . Это импортирует теги Spring Form, которые мы будем использовать. Когда мы открываем форму с <form:form> , обратите внимание, что мы указываем атрибут модели. Это говорит Spring, чтобы искать атрибут в модели и связать его с формой. Атрибуты action и method также могут быть указаны. Если не указано (как в этом примере), они по умолчанию используют текущий URL и «POST» соответственно (как обычные формы HTML).
Обратите внимание, что каждое из наших полей ввода использует тег taglib Spring Form (form: prefix). Каждое из этих полей также указывает атрибут path . Это должно соответствовать получателю или установщику атрибута модели (в нашем случае, класса Subscriber) в соответствии со стандартным соглашением Java-бина (get / is, установить префикс с именем поля с заглавной буквой). Когда страница загружена, поля ввода заполняются Spring, который вызывает метод получения каждого поля, связанного с полем ввода. Когда форма отправляется, вызыватели вызывают для сохранения значений формы в объекте.
Теги <form:input> довольно понятны. Обратите внимание на два случая использования <form:select> . В первом раскрывающемся списке выбора для поля пола обратите внимание, что мы вручную перечисляем все параметры. В выпадающем меню выбора частоты в новостном бюллетене мы, однако, перебираем атрибут модели frequencies (помните, что мы добавили его в модель с помощью метода @ModelAttribute -annotated в контроллере) и добавляем каждый элемент в качестве параметра в раскрывающемся списке. Spring будет автоматически связывать значения формы с перечислениями при отправке формы, если значение выбранной опции является допустимым именем перечисления.
Когда форма отправлена, вызывается обработчик POST в контроллере. Форма автоматически связывается с аргументом подписчика, который мы передали. Аннотация @ModelAttribute здесь на самом деле не нужна. Я напишу больше об этом в другом посте.
Вот оно! Я настоятельно рекомендую вам скачать исходный код и запустить код. Оставляйте любые вопросы в комментариях ниже.
Полный исходный код : ZIP , GitHub Чтобы запустить код из этого урока: необходимо установить Gradle . Загрузите ZIP. Extract. Откройте командную строку для извлеченного местоположения. Запустите gradle jettyRunWar. Перейдите в браузере по адресу http: // localhost: 8080 / form.
