Изучение библиотеки тегов форм SpringMVC
1. обзор
Вfirst article этой серии мы рассказали об использовании библиотеки тегов формы и о том, как привязать данные к контроллеру.
В этой статье мы рассмотрим различные теги, которые Spring MVC предоставляет, чтобы помочь намcreate and validate forms.
2. Тегinput
Начнем с тегаinput. Этот тег отображает HTML-тегinput с использованием связанного значения иtype='text' по умолчанию:
Начиная с Spring 3.1, вы можете использовать другие специфичные для HTML5 типы, такие как электронная почта, дата и другие. [.hps]#For example,if we wanted tocreate an emailfield,we can используйте type='email': #
[.hps]#Similarly,to createa date field, [#result_box]#we can use type='date', which will render a date picker in many browsers compatible with HTML5: ##
3. Тегpassword
Этот тег отображает тег HTMLinput сtype='password', используя связанное значение. Этот HTML-ввод маскирует значение, введенное в поле:
4. Тегtextarea
Этот тег отображает HTMLtextarea:
Мы можем указать количествоrows иcolumns таким же образом, как и HTMLtextarea.
5. Тегcheckbox иcheckboxes
Тегcheckbox отображает тег HTMLinput сtype='checkbox'. Библиотека тегов формы Spring MVC предоставляет различные подходы к тегуcheckbox, которые должны удовлетворить все наши потребностиcheckbox:
В приведенном выше примере создается классический одиночныйcheckbox со значениемboolean. Если мы установим связанное значение наtrue, этот флажок будет установлен по умолчанию.
В следующем примере создается несколько флажков.. В этом случае значенияcheckbox жестко запрограммированы внутри страницы JSP:
Bird watching:
Astronomy:
Snowboarding:
Здесь граничное значение имеет типarray илиjava.util.Collection:
String[] hobbies;
Тегcheckboxes используется для отображения нескольких флажков, где значения флажков генерируются во время выполнения:
Для генерации значений мы передаемArray,List илиMap, содержащие доступные параметры в свойствеitems. Мы можем инициализировать наши значения внутри контроллера:
List favouriteLanguageItem = new ArrayList();
favouriteLanguageItem.add("Java");
favouriteLanguageItem.add("C++");
favouriteLanguageItem.add("Perl");
Обычно связанное свойство является коллекцией, поэтому оно может содержать несколько значений, выбранных пользователем:
List favouriteLanguage;
6. Тегradiobutton иradiobuttons
Этот тег отображает тег HTMLinput сtype='radio':
Male:
Female:
Типичный шаблон использования будет включать несколько экземпляров тега с различными значениями, привязанными к одному и тому же свойству:
private String sex;
Как и тегcheckboxes, тегradiobuttons отображает несколько тегов HTMLinput сtype='radio':
В этом случае мы можем захотеть передать доступные параметры какArray, aList илиMap, содержащие доступные параметры в свойствеitems:
List jobItem = new ArrayList();
jobItem.add("Full time");
jobItem.add("Part time");
7. Тегselect
Этот тег отображает элемент HTMLselect:
Для генерации значений мы передаемArray,List илиMap, содержащие доступные параметры в свойствеitems. [.hps]#Once again #, мы можем инициализировать наши значения внутри контроллера:
Map countryItems = new LinkedHashMap();
countryItems.put("US", "United States");
countryItems.put("IT", "Italy");
countryItems.put("UK", "United Kingdom");
countryItems.put("FR", "France");
Тег select также поддерживает использование вложенных теговoption иoptions.
В то время как тегoption отображает один HTMLoption, тегoptions отображает список тегов HTMLoption.
Тегoptions принимаетArray,List илиMap, содержащие доступные параметры в свойствеitems, как и тегselect :
[.hps]#Whenwe have theneedto selectseveral items at once, мы можемcreate amultiple listbox. # Для рендеринга этого типа list, просто добавьте атрибутmultiple=”true” в тегselect.
Здесь связанное свойство - этоarray илиjava.util.Collection:
List fruit;
8. Тегhidden
Этот тег отображает тег HTMLinput сtype='hidden' с использованием связанного значения:
9. ТегErrors
Полевые сообщения об ошибках генерируются валидаторами, связанными с контроллером. Мы можем использовать тег Errors для отображения этих сообщений об ошибках:
Это отобразит ошибки для поля, указанного в свойствеpath. Сообщения об ошибках по умолчанию отображаются в тегеspan, причем.errors добавляется к значениюpath какid, и, возможно, класс CSS изcssClass свойство, которое можно использовать для стилизации вывода:
Name is required!
Чтобы заключить сообщения об ошибках с другим элементом вместо тега по умолчаниюspan, мы можем указать предпочтительный элемент внутри атрибутаelement:
Это отображает сообщения об ошибках в элементеdiv:
Name is required!
In addition to having [.hps] возможность отображать ошибки[.hps] для a specific input element, мы можем отображать весь список ошибок (независимо от поля) для данной страницы. Это достигается за счет использования подстановочного знака*:
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");
}
}
В этом случае, если полеname пусто, валидатор возвращает сообщение об ошибке, идентифицированноеrequired.name из пакета ресурсов.
Пакет ресурсов определяется в файле конфигурации SpringXML следующим образом:
Или в чистом стиле конфигурации Java:
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("messages");
return messageSource;
}
Сообщение об ошибке определено внутри файлаmessages.properties:
required.name = Name is required!
Чтобы применить эту проверку, нам нужно включить ссылку на валидатор в нашем контроллере и вызвать методvalidate в методе контроллера, который вызывается, когда пользователь отправляет форму:
@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) для проверки bean-компонента. Для этого нам понадобитсяJSR303 validator framework в пути к классам. Мы будем использоватьHibernate Validator (эталонная реализация). Ниже приведена зависимость, которую мы должны включить в POM:
org.hibernate
hibernate-validator
5.1.1.Final
Чтобы Spring MVC поддерживал проверку JSR 303 с помощью аннотации@Valid, нам необходимо включить следующее в нашем файле конфигурации Spring:
Или используйте соответствующую аннотацию@EnableWebMvc в конфигурации Java:
@EnableWebMvc
@Configuration
public class ClientWebConfigJava implements WebMvcConfigurer {
// All web configuration will go here
}
Затем нам нужно аннотировать метод контроллера[.hps]#thatwe want tovalidate # аннотацией@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;
По умолчанию в этой аннотации будет отображаться“may not be empty”, если мы оставим поле ввода пароля пустым.
Мы можем переопределить сообщение об ошибке по умолчанию, создав свойство в комплекте ресурсов, определенном в примере валидатора. Ключ сообщения соответствует правилуAnnotationName.entity.fieldname:
NotEmpty.person.password = Password is required!
10. Заключение
В этом уроке мы рассмотрели различные теги, которые Spring предоставляет для работы с формами.
Мы также взглянули на тег для отображения ошибок проверки и конфигурацию, необходимую для отображения пользовательских сообщений об ошибках.
Все приведенные выше примеры можно найти вGitHub project. Это проект на основе Eclipse, поэтому его легко импортировать и запускать как есть.
Когда проект выполняется локально, к образцу формы можно обратиться по адресу: