Перейти к основному содержимому

Изучение библиотеки тегов формы SpringMVC

· 7 мин. чтения

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, поэтому его легко импортировать и запускать как есть.

Когда проект выполняется локально, пример формы доступен по адресу:

http://локальный:8080/весна-mvc-xml/человек