1. Обзор
В первой статье этой серии мы рассказали об использовании библиотеки тегов формы и о том, как связать данные с контроллером.
В этой статье мы рассмотрим различные теги, которые Spring MVC предоставляет для помощи в создании и проверке форм .
2. Входной
тег
Начнем с тега input .
Этот тег отображает тег ввода
HTML , используя связанное значение и type='text'
по умолчанию:
<form:input path="name" />
Начиная с Spring 3.1 вы можете использовать другие типы, специфичные для HTML5, такие как электронная почта, дата и другие. Например , если мы хотим создать поле электронной почты , мы можем использовать type='email':
``
<form:input type="email" path="email" />
Точно так же , чтобы создать поле даты, мы можем использовать type='date'
, что отобразит средство выбора даты во многих браузерах, совместимых с HTML5:
<form:input type="date" path="dateOfBirth" />
3. Тег пароля
Этот тег отображает тег ввода
HTML с type='password',
используя связанное значение. Этот ввод HTML маскирует значение, введенное в поле:
<form:password path="password" />
4. Тег textarea
Этот тег отображает текстовое поле
HTML :
<form:textarea path="notes" rows="3" cols="20"/>
Мы можем указать количество строк и столбцов таким же образом, как и для текстовой
области HTML .
5. Флажок
и чекбоксы
Тег
Тег флажка отображает тег
ввода
HTML с type='checkbox'
. Библиотека тегов формы Spring MVC предоставляет различные подходы к тегу флажка
, которые должны удовлетворить все наши потребности в флажках
:
<form:checkbox path="receiveNewsletter" />
В приведенном выше примере генерируется классический одиночный флажок
с логическим
значением. Если мы установим для связанного значения значение true
, этот флажок будет установлен по умолчанию.
В следующем примере создается несколько флажков . В этом случае значения флажков
жестко закодированы внутри страницы JSP:
Bird watching: <form:checkbox path="hobbies" value="Bird watching"/>
Astronomy: <form:checkbox path="hobbies" value="Astronomy"/>
Snowboarding: <form:checkbox path="hobbies" value="Snowboarding"/>
Здесь связанное значение имеет тип array
или java.util.Collection
:
String[] hobbies;
Тег checkboxes
используется для отображения нескольких флажков, где значения флажков генерируются во время выполнения:
<form:checkboxes items="${favouriteLanguageItem}" path="favouriteLanguage" />
Чтобы сгенерировать значения, мы передаем массив
, список
или карту
, содержащую доступные параметры в свойстве items .
Мы можем инициализировать наши значения внутри контроллера:
List<String> favouriteLanguageItem = new ArrayList<String>();
favouriteLanguageItem.add("Java");
favouriteLanguageItem.add("C++");
favouriteLanguageItem.add("Perl");
Обычно связанное свойство представляет собой коллекцию, поэтому оно может содержать несколько значений, выбранных пользователем:
List<String> favouriteLanguage;
6. Радиокнопка
и тег radiobuttons
Этот тег отображает тег ввода
HTML с type='radio':
Male: <form:radiobutton path="sex" value="M"/>
Female: <form:radiobutton path="sex" value="F"/>
Типичный шаблон использования будет включать несколько экземпляров тегов с разными значениями, привязанными к одному и тому же свойству:
private String sex;
Как и тег checkboxes
, тег radiobuttons отображает несколько тегов
ввода
HTML с type='radio'
:
<form:radiobuttons items="${jobItem}" path="job" />
В этом случае мы можем захотеть передать доступные параметры в виде массива
, списка
или карты
, содержащей доступные параметры в свойстве items :
List<String> jobItem = new ArrayList<String>();
jobItem.add("Full time");
jobItem.add("Part time");
7. Тег выбора
Этот тег отображает элемент выбора
HTML :
<form:select path="country" items="${countryItems}" />
Чтобы сгенерировать значения, мы передаем массив
, список
или карту
, содержащую доступные параметры в свойстве items .
Еще раз , мы можем инициализировать наши значения внутри контроллера:
Map<String, String> countryItems = new LinkedHashMap<String, String>();
countryItems.put("US", "United States");
countryItems.put("IT", "Italy");
countryItems.put("UK", "United Kingdom");
countryItems.put("FR", "France");
Тег select также поддерживает использование вложенных тегов option
и options
.
В то время как тег option
отображает один параметр
HTML , тег options
отображает список тегов параметров
HTML .
Тег options
принимает массив
, список
или карту
, содержащую доступные параметры в свойстве items
, как и тег select :
<form:select path="book">
<form:option value="-" label="--Please Select--"/>
<form:options items="${books}" />
</form:select>
Когда нам нужно выбрать несколько элементов одновременно , мы можем создать множественный список . Чтобы отобразить этот тип списка, просто добавьте атрибут multiple="true"
в тег select .
<form:select path="fruit" items="${fruit}" multiple="true"/>
Здесь связанным свойством является массив
или java.util.Collection
:
List<String> fruit;
8. Скрытый
тег
Этот тег отображает тег ввода
HTML с type='hidden',
используя связанное значение:
<form:hidden path="id" value="12345" />
9. Тег ошибок
Сообщения об ошибках поля генерируются валидаторами, связанными с контроллером. Мы можем использовать тег Errors для отображения этих сообщений об ошибках поля:
<form:errors path="name" cssClass="error" />
Это отобразит ошибки для поля, указанного в свойстве пути .
Сообщения об ошибках отображаются в теге span
по умолчанию, с добавлением .errors
к значению пути в качестве
id
и, необязательно, класса CSS из свойства cssClass
, который можно использовать для стилизации вывода:
<span id="name.errors" class="error">Name is required!</span>
Чтобы заключить сообщения об ошибках в другой элемент вместо тега span
по умолчанию , мы можем указать предпочтительный элемент внутри атрибута элемента :
<form:errors path="name" cssClass="error" element="div" />
Это отображает сообщения об ошибках внутри элемента div :
<div id="name.errors" class="error">Name is required!</div>
Помимо возможности отображать ошибки для определенного элемента ввода , мы можем отображать весь список ошибок (независимо от поля) для данной страницы. Это достигается использованием подстановочного знака *
:
<form:errors path="*" />
9.1. Валидатор
Чтобы отображать ошибки для данного поля, нам нужно определить валидатор:
public class PersonValidator implements Validator {
@Override
public boolean supports(Class clazz) {
return Person.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object obj, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "required.name");
}
}
В этом случае, если имя
поля пусто, валидатор возвращает сообщение об ошибке, идентифицированное required.name
из пакета ресурсов.
Пакет ресурсов определяется в XML
- файле конфигурации Spring следующим образом:
<bean class="org.springframework.context.support.ResourceBundleMessageSource" id="messageSource">
<property name="basename" value="messages" />
</bean>
Или в чистом стиле конфигурации Java:
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("messages");
return messageSource;
}
Сообщение об ошибке определяется внутри файла messages.properties :
required.name = Name is required!
Чтобы применить эту проверку, нам нужно включить ссылку на валидатор в наш контроллер и вызвать метод проверки
в методе контроллера, который вызывается, когда пользователь отправляет форму:
@RequestMapping(value = "/addPerson", method = RequestMethod.POST)
public String submit(
@ModelAttribute("person") Person person,
BindingResult result,
ModelMap modelMap) {
validator.validate(person, result);
if (result.hasErrors()) {
return "personForm";
}
modelMap.addAttribute("person", person);
return "personView";
}
9.2. Проверка компонентов JSR 303
Начиная с Spring 3, мы можем использовать JSR 303 (через аннотацию @Valid
) для проверки бина. Для этого нам нужна структура валидатора JSR303 на пути к классам. Мы будем использовать Hibernate Validator (эталонная реализация). Ниже приведена зависимость, которую нам нужно включить в POM:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.1.Final</version>
</dependency>
Чтобы Spring MVC поддерживал проверку JSR 303 с помощью аннотации @Valid
, нам нужно включить следующее в нашем файле конфигурации Spring:
<mvc:annotation-driven/>
Или используйте соответствующую аннотацию @EnableWebMvc
в конфигурации Java:
@EnableWebMvc
@Configuration
public class ClientWebConfigJava implements WebMvcConfigurer {
// All web configuration will go here
}
Затем нам нужно аннотировать метод контроллера, который мы хотим проверить , с помощью аннотации @Valid
:
@RequestMapping(value = "/addPerson", method = RequestMethod.POST)
public String submit(
@Valid @ModelAttribute("person") Person person,
BindingResult result,
ModelMap modelMap) {
if(result.hasErrors()) {
return "personForm";
}
modelMap.addAttribute("person", person);
return "personView";
}
Теперь мы можем аннотировать свойство объекта, чтобы проверить его с помощью аннотации валидатора Hibernate:
@NotEmpty
private String password;
По умолчанию эта аннотация будет отображать «не может быть пустым»
, если мы оставим поле ввода пароля пустым.
Мы можем переопределить сообщение об ошибке по умолчанию, создав свойство в пакете ресурсов, определенном в примере с валидатором. Ключ сообщения следует правилу AnnotationName.entity.fieldname
:
NotEmpty.person.password = Password is required!
10. Заключение
В этом руководстве мы рассмотрели различные теги, которые Spring предоставляет для работы с формами.
Мы также рассмотрели тег для отображения ошибок проверки и конфигурацию, необходимую для отображения пользовательских сообщений об ошибках.
Все приведенные выше примеры можно найти в проекте GitHub . Это проект на основе Eclipse, поэтому его легко импортировать и запускать как есть.
Когда проект выполняется локально, пример формы доступен по адресу: