«1. Обзор

В этой статье мы обсудим формы Spring и привязку данных к контроллеру. Кроме того, мы рассмотрим одну из основных аннотаций в Spring MVC, то есть @ModelAttribute.

Конечно, Spring MVC — это сложная тема, и вам нужно понять множество вещей, чтобы использовать ее в полной мере, поэтому обязательно углубитесь в фреймворк здесь.

2. Модель

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

public class Employee {
    private String name;
    private long id;
    private String contactNumber;

    // standard getters and setters
}

Это будет наш объект поддержки формы.

3. Представление

Далее – давайте определим фактическую форму и, конечно же, HTML-файл, который ее содержит. Мы собираемся использовать страницу, на которой создается/регистрируется новый сотрудник:

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
    <head>
    </head>
    <body>
        <h3>Welcome, Enter The Employee Details</h3>
        <form:form method="POST" 
          action="/spring-mvc-xml/addEmployee" modelAttribute="employee">
             <table>
                <tr>
                    <td><form:label path="name">Name</form:label></td>
                    <td><form:input path="name"/></td>
                </tr>
                <tr>
                    <td><form:label path="id">Id</form:label></td>
                    <td><form:input path="id"/></td>
                </tr>
                <tr>
                    <td><form:label path="contactNumber">
                      Contact Number</form:label></td>
                    <td><form:input path="contactNumber"/></td>
                </tr>
                <tr>
                    <td><input type="submit" value="Submit"/></td>
                </tr>
            </table>
        </form:form>
    </body>
</html>

Во-первых, обратите внимание, что мы включаем библиотеку тегов в нашу JSP-страницу – форму taglib – чтобы помочь с определением нашей формы.

Далее – тег \u003cform:form\u003e играет здесь важную роль; он очень похож на обычный HTLM-тег \u003cform\u003e, но атрибут modelAttribute является ключом, указывающим имя объекта модели, который поддерживает эту форму:

<form:form method="POST" 
  action="/SpringMVCFormExample/addEmployee" modelAttribute="employee">

Это будет соответствовать @ModelAttribute позже в контроллер.

Далее — каждое поле ввода использует еще один полезный тег из библиотеки тегов Spring Form — form: prefix. Каждое из этих полей указывает атрибут пути — он должен соответствовать получателю/установщику атрибута модели (в данном случае классу Employee). Когда страница загружается, поля ввода заполняются Spring, который вызывает геттер каждого поля, привязанного к полю ввода. При отправке формы вызываются сеттеры для сохранения значений формы в объект.

Наконец, когда форма отправляется, вызывается обработчик POST в контроллере, и форма автоматически привязывается к аргументу сотрудника, который мы передали.

4. Контроллер

Теперь , давайте посмотрим на контроллер, который будет обрабатывать серверную часть:

Контроллер определяет две простые операции — GET для отображения данных в форме и POST для операции создания через отправку формы.

@Controller
public class EmployeeController {

    @RequestMapping(value = "/employee", method = RequestMethod.GET)
    public ModelAndView showForm() {
        return new ModelAndView("employeeHome", "employee", new Employee());
    }

    @RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
    public String submit(@Valid @ModelAttribute("employee")Employee employee, 
      BindingResult result, ModelMap model) {
        if (result.hasErrors()) {
            return "error";
        }
        model.addAttribute("name", employee.getName());
        model.addAttribute("contactNumber", employee.getContactNumber());
        model.addAttribute("id", employee.getId());
        return "employeeView";
    }
}

Также обратите внимание, что если объект с именем «employee» не добавлен в модель, Spring будет жаловаться, когда мы попытаемся получить доступ к JSP, потому что JSP будет настроен на привязку формы к атрибуту модели «employee». :

Чтобы получить доступ к нашему объекту поддержки формы, нам нужно внедрить его через аннотацию @ModelAttribute.

java.lang.IllegalStateException: 
  Neither BindingResult nor plain target object 
    for bean name 'employee' available as request attribute
  at o.s.w.s.s.BindStatus.<init>(BindStatus.java:141)

\u003cem\u003e@ModelAttribute \u003c/em\u003e в аргументе метода указывает, что аргумент будет извлечен из модели. Если аргумент отсутствует в модели, сначала будет создан экземпляр аргумента, а затем добавлен в модель.

5. Обработка ошибок привязки

По умолчанию Spring MVC генерирует исключение, когда во время привязки запроса возникают ошибки. Обычно это не то, что мы хотим, вместо этого мы должны представлять эти ошибки пользователю. Мы собираемся использовать BindingResult, добавив его в качестве аргумента в наш метод контроллера:

Аргумент BindingResult должен располагаться сразу после нашего объекта поддержки формы — это один из редких случаев, когда порядок аргументов метода имеет значение. В противном случае мы столкнемся со следующим исключением:

public String submit(
  @Valid @ModelAttribute("employee") Employee employee,
  BindingResult result,
  ModelMap model)

Теперь — исключение больше не выбрасывается; вместо этого ошибки будут регистрироваться в BindingResult, который передается методу отправки. На этом этапе мы можем обрабатывать эти ошибки различными способами — например, операцию можно отменить:

java.lang.IllegalStateException: 
  Errors/BindingResult argument declared without preceding model attribute. 
    Check your handler method signature!

Обратите внимание, что в случае, если результат содержит ошибки, мы возвращаем другое представление в пользователя, чтобы правильно отображать эти ошибки. Давайте взглянем на это представление — error.jsp:

@RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
public String submit(@Valid @ModelAttribute("employee")Employee employee, 
  BindingResult result,  ModelMap model) {
    if (result.hasErrors()) {
        return "error";
    }
    
    //Do Something
    return "employeeView";
}

6. Отображение сотрудника

<html>
    <head>
    </head>

    <body>
        <h3>Please enter the correct details</h3>
        <table>
            <tr>
                <td><a href="employee">Retry</a></td>
            </tr>
        </table>
    </body>

</html>

Наконец, помимо создания нового сотрудника, мы также можем просто отобразить его — вот код быстрого просмотра для этого:

Страница JSP просто использует выражения EL для отображения значений свойств объекта Employee в модели.

<body>
    <h2>Submitted Employee Information</h2>
    <table>
        <tr>
            <td>Name :</td>
            <td>${name}</td>
        </tr>
        <tr>
            <td>ID :</td>
            <td>${id}</td>
        </tr>
        <tr>
            <td>Contact Number :</td>
            <td>${contactNumber}</td>
        </tr>
    </table>
</body>

7. Тестирование приложения

Простое приложение можно развернуть, например, на сервере Tomcat, с локальным доступом:

http://localhost:8080/spring-mvc-xml/ сотрудник

«Это представление, содержащее основную форму — до операции отправки:

После отправки отображаются данные:

Spring MVC Form example - Submit

Spring MVC Form example – Submit

И все — рабочий пример простой формы с Spring MVC, с проверкой .

Spring MVC Form example - View

Spring MVC Form example – View

Реализацию этого руководства по Spring MVC можно найти в проекте GitHub — это проект на основе Maven, поэтому его легко импортировать и запускать как есть.

Наконец, как я уже говорил в самом начале статьи, вам определенно следует поглубже покопаться в Spring MVC.

«