Spring MVC — Hello World, пример приложения. Передача параметров формы
Рассмотрим простой пример приложения Spring MVC с возможностью передачи параметров из формы. В статье будут рассмотрены базовые настройки, дано объяснение как происходит переход между представлениями и как можно сохранить введенную информацию в форме в объект POJO.
Используемые технологии:
- Spring MVC 4.1.5
- JSP
- Maven 3.2.5
- IntelliJ IDEA 14.1.4
- JDK 1.8
1. Структура проекта
В проекте два представления index.jsp и secondPage.jsp. Имеется один контроллер, а так же модель User.
2. Создаем проект maven
Просто жмем Next
файл pom.xml
1 2 3 4 5 6 7 8 9 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 |
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>ru.javastudy</groupId> <artifactId>SpringMVC_JSPHelloWorld</artifactId> <version>1.0-SNAPSHOT</version> <properties> <spring-framework-version>4.1.5.RELEASE</spring-framework-version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring-framework-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring-framework-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring-framework-version}</version> </dependency> <!--JSF (include "jsf-api" and "jsf-impl")--> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.faces</artifactId> <version>2.2.10</version> </dependency> </dependencies> </project> |
3. Добавляем поддержку фреймворков Spring MVC
Если в maven все зависимости загрузились успешно, то IDEA предложит использовать библиотеки maven для Spring.
4. Настраиваем web.xml
1 2 3 4 5 6 7 8 9 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 |
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <!-- Add Support for Spring --> <!-- Создает Spring Container, доступный всем сервлетам и фильтрам --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Обрабатывает все запросы. Центральное понятие--> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.form</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> |
Комментарии в коде поясняют значения настроек.
Файл application-context.xml, созданный по умолчанию, оставляем пустым. Для первоначального запуска его можно не настраивать.
dispatcher-servlet.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --> <!-- Enables the Spring MVC @Controller programming model --> <mvc:annotation-driven /> <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --> <mvc:resources mapping="/resources/**" location="/resources/" /> <context:component-scan base-package="ru.javastudy" /> <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> </bean> </beans> |
5. Контроллер Spring
1 2 3 4 5 6 7 8 9 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 |
package ru.javastudy.springMVC.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; import ru.javastudy.springMVC.model.User; @Controller public class MainController { /*First method on start application*/ /*Попадаем сюда на старте приложения (см. параметры аннотации и настройки пути после деплоя) */ @RequestMapping(value = "/", method = RequestMethod.GET) public ModelAndView main() { ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("userJSP", new User()); modelAndView.setViewName("index"); return modelAndView; } /*как только на index.jsp подтвердится форма <spring:form method="post" modelAttribute="userJSP" action="check-user">, то попадем вот сюда */ @RequestMapping(value = "/check-user") public ModelAndView checkUser(@ModelAttribute("userJSP") User user) { ModelAndView modelAndView = new ModelAndView(); //имя представления, куда нужно будет перейти modelAndView.setViewName("secondPage"); //записываем в атрибут userJSP (используется на странице *.jsp объект user modelAndView.addObject("userJSP", user); return modelAndView; //после уйдем на представление, указанное чуть выше, если оно будет найдено. } } |
При запуске приложения мы попадем в метод main(), т.к. у него стоит параметр в @RequestMapping value = «/» и метод GET. Т.к. мы не указывали какой-либо другой путь при деплое приложения, то будет использоваться путь по умолчанию /.
Теперь нам необходимо записать в модель атрибут, а так же объект, который будет соответствовать этому атрибуту. Здесь используется имя userJSP, который ссылается на модель POJO класса User.class. Здесь специально разделил названия атрибута и модели, т.к. во многих примерах всегда используется model=user, object=user, name=user и т.п.. А потом нельзя понять куда что пишется и на что ссылается..
Далее записываем имя представления index. После return будет обращение в dispatcherServlet.xml вот к этой части:
1 2 3 4 5 |
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> </bean> |
Этот бин будет искать представление index в пакетах с соответствующим prefix и suffix. Т.е. в нашем случае в /WEB-INF/views/index.jsp.
6. Модель
Создан простенький класс, хранящий имя и пароль:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package ru.javastudy.springMVC.model; import org.springframework.stereotype.Component; @Component public class User { private String name; private String password; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } |
6. Представление
index.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<!-- обратите внимание на spring тэги --> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags/form" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Index Page</title> </head> <body> <spring:form method="post" modelAttribute="userJSP" action="check-user"> Name: <spring:input path="name"/> (path="" - указывает путь, используемый в modelAttribute=''. в нашем случае User.name) <br/> Password: <spring:input path="password"/> <br/> <spring:button>Next Page</spring:button> </spring:form> </body> </html> |
Создаем форму с использованием тегов от spring (смотрите начало страницы), указываем метод формы (post или get), атрибут модели (используется в контроллере из описания выше) и что произойдет при подтверждении (сабмите) формы (после нажатия на кнопку в нашем случае).
secondPage.jsp
1 2 3 4 5 6 7 8 9 10 11 12 |
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Second Page</title> </head> <body> Введенное имя: ${userJSP.name}; <br/> Введенный пароль: ${userJSP.password}; <br/> </body> </html> |
используя имя атрибута можно вытянуть сохраненные (переданные) параметры формы.
7. Запуск приложения
После запуска откроется простая формочка:
После нажатия на кнопку Next Page попадем в контроллер в этот метод:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/*как только на index.jsp подтвердится форма <spring:form method="post" modelAttribute="userJSP" action="check-user">, то попадем вот сюда */ @RequestMapping(value = "/check-user") public ModelAndView checkUser(@ModelAttribute("userJSP") User user) { ModelAndView modelAndView = new ModelAndView(); //имя представления, куда нужно будет перейти modelAndView.setViewName("secondPage"); //записываем в атрибут userJSP (используется на странице *.jsp объект user modelAndView.addObject("userJSP", user); return modelAndView; //после уйдем на представление, указанное чуть выше, если оно будет найдено. } |
Обратите внимание, что в аннотации не указано какой метод используется get или post. В этом случае будут проверяться оба.
Итак мы попадаем в этот метод и идет поиск атрибута с именем userJSP, который будет записан в User.class с именем user.
Далее просто указываем новое представление и добавляем в модель объект, который пришел из формы в атрибут с тем же названием (для удобства) userJSP. Этот атрибут потом используем на второй странице, чтобы вытащить данные (см. предыдущий пункт).
Результат:
8. Подробное описание как собрать и запустить проект
В комментариях было указано на сложности в запуске исходных кодов проекта. Распишу всё подробнее.
8.1 Исходный код
Скачиваем проект по ссылке в конце статьи. Если просто разархивировать zip архив, то у вас получиться две папки с одинаковым названием. В IDEA нужно открывать второй уровень:
8.2. Settings, Project Structure
Поскольку в pom.xml не были указаны версии Java, то в IDEA у вас они выставятся по умолчанию на 1.5. Для начала заходите в Settings(alt+ctrl+s) и меняйте в пункте Java Compiler версию на 1.8.
Теперь в Project Structure (alt+ctrl+shift+s) меняем в Module уровень языка с 5 на 8.
8.3. Tomcat
Сначала создаем артефакт в том же месте где меняли уровень языка (Project Structure):
Теперь настроем сервер и запустим приложение.
Заходим в настройки запуска приложения (цифра 1). Выбираем ‘+’ и там Tomcat Local (у вас он должен быть скачан, например в папку program files). Далее под цифрой 3 указываем папку с томкатом. Во вкладке deployment нужно добавить артефакт, который создается чуть выше. Нажимаем значек плей и приложение откроется в браузере!
*как исправить кривой результат для русских символов смотрите в статье ниже.
Может быть интересно
Обзор приложения Spring MVC + AngularJS + Bootstrap + HTML5
Spring MVC – исправление проблем с русской кодировкой. Кодировка передачи параметров формы
Исходные коды
SpringMVC_JSPHelloWorld — исходные коды
4624 thoughts on “Spring MVC — Hello World, пример приложения. Передача параметров формы”
Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.
Спасибо большущее!
Работает!
Правда есть пара моментов, не описанные в статье, на которые я, как чайник, наткнулся и немного помучился. Но это касается только полных чайников и, возможно, и не должно быть отражено в статье (чтоб не утяжелять её).
А вы расскажите. Другим, думаю, будет интересно и сэкономит время. А может и в статью имеет смысл добавить, если что-то совсем не очевидное.
Я думаю, надо сказать о двух моментах (слов-то немного и пара скриншотов):
1) В Project Settings – Artifact в правой её части «Available Elements» выделить все библиотеки и в контекстном меню выбоать Put into WEB-INF\lib
2) Создать Run Configuration
Спасибо большое за подсказку. Только после того, как сделал пункт 1, всё заработало.
А нет, не всё. Уже непосредственно в браузере вылез
HTTP Status 500 — An exception occurred processing JSP page /index.jsp at line 21
опишите так же в деталях, как это запустить, плз. начиная с того, в какой папке проект создается, куда собирается, на какой версии какого сервера, что нужно настроить. А то выглядит, будто это само собой разумеющееся. У меня по этой статье ничего запустить не получилось. Приложение не разворачивается на сервере, выдает ранзые ошибки одну за другой….
UPDATE: Обновил статью для вас.
На самом деле так и есть — просто запустить. Вы скачивали проект, который находится в конце статьи? Попроую кратко описать:
Открывается Idea, добавляете Tomcat. В нем указывается артефакт (он задается в Project Structure). Нажимаете запустить — всё должно работать.
вот здесь JSF Hello World в картинках есть описание как сервер добавить и запустить (Настройка веб контейнера для приложения).
Подскажите пожалуйста, в чём может быть проблема?
//admin: тут был скриншот с стектрейсом о не найденном объекте userJSP
не видит переменную в запросе (request).
Извините за глупый вопрос, но как это исправить?
При построении страницы нужно, чтобы объект userJSP был доступен в ответе от сервера. В этом учебном проекте он добавляется в модели addObject(«userJSP»). Где он у вас теряется и в этом ли точная ошибка подсказать не смогу.
Как решить проблему с кодировкой? Если в поля вводить русские символы они уходят вдругую кодировку.
https://javastudy.ru/spring-mvc/spring-mvc-encoding-ruschars/
Добрый день, скажите пожалуйста назначение это строчки:
<mvc:resources mapping=«/resources/**» location=«/resources/» />
resources стандартная папка для maven проекта. Этой записью можно указать путь где физически лежат ресурсы по отношению к запросам вида /resources/**. И можно легко менять их, например записью location=»/resources/my-new-theme/». В этом случае все запросы пойдут в папку my-new-theme.
Большое спасибо за хороший урок. Но у меня возник вопрос — Когда удаляю:
в файле web.xml приложение работает. Получается чти параметры являются необязательными? Спасибо!
просто начинают грузится дефолтные настройки. В приложении такого масштаба как это вы не заметите разницу:)
Привет! Подскажите пожалуйста. У меня в Идее 2016.2.5 нет меню Add Frameworks Support. Я в структуре проекта в меню Modules добавляю Spring, потом по нему + SpringMVC и тогда выходит такое окно как у Вас Use Library или Download. Я выбираю Use , ОК. Но структура проекта у меня не меняется. Не появляется пакет web. Я правильно понял, что он должен сам появиться после добавления SpringMVC?
Получилось. На названии проекта правой кнопкой мыши, там будет Add frameworks support
Здравствуйте,
пытаюсь запустить проект, который я сам и создал по вашему уроку в итоге веб сервер выдает страничку:
<html>
<head>
<title>$Title$</title>
</head>
<body>
$END$
</body>
</html>
А если я запускаю ваш проект, то все получается как нужно.
Такая же фигня. заработало следующим образом:
Взял пример с oracle netbeans spring mvc:
добавил в web.xml
в index.jsp убрал / в path
создал WEB-INF/redirect.jsp
У вас в проекте два файла index.jsp. Удалите один и все норм будет.
Когда в jsp добавляешь
то сервер выдает ошибку, как ее решить?
HTTP Status 500 — java.lang.ClassNotFoundException: org.apache.jsp.WEB_002dINF.views.index_jsp
type Exception report
message java.lang.ClassNotFoundException: org.apache.jsp.WEB_002dINF.views.index_jsp
description The server encountered an internal error that prevented it from fulfilling this request.
exception
root cause
note The full stack trace of the root cause is available in the Apache Tomcat/8.5.9 logs.
Apache Tomcat/8.5.9
Я просто хочу передать объект и сделать foreach
Добрый день!
При запуске приложения вываливается страница приветствия TomCat. Тоже самое и на других подобных приложениях. Не знаю куда копать.
___________
(((((( сутки почти потратил на эту проблему … порты менял… на них в логе Tomcat ругался. Оказывается Томкат нужно было поставить, а службу соответствующую остановить. С запущенной службой целый букет ошибок:
фев 15, 2017 4:58:15 PM org.apache.catalina.core.StandardServer await
SEVERE: StandardServer.await: create[localhost:8005]:
java.net.BindException: Address already in use: JVM_Bind