Spring MVC — интеграция с JSF
Рассмотрим пример создания простого приложения «Hello World» с использованием Spring MVC и JSF 2.0. В статье будет показаны базовые настройки для создания и запуска проекта .
Используемые технологии:
- Spring MVC 4.1.5
- JSF 2.0
- Maven 3.2.5
- IntelliJ IDEA 14.1.4
- JDK 1.8
1. Структура проекта
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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
<?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.springmvc</groupId> <artifactId>springmvc</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> <!-- JSR-330 --> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <!--PrimeFaces components --> <dependency> <groupId>org.primefaces</groupId> <artifactId>primefaces</artifactId> <version>5.2</version> </dependency> </dependencies> </project> |
Вначале добавляются три зависимости spring, затем идут стандартные зависимости для приложений J2EE.
3. Добавляем поддержку фреймворков Spring MVC и JSF
Если в maven все зависимости загрузились успешно, то IDEA предложит использовать библиотеки maven как для JSF, так и для 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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
<?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"> <!-- Обрабатывает все запросы. Центральное понятие--> <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>/</url-pattern> </servlet-mapping> <!-- Add Support for Spring --> <!-- Создает Spring Container, доступный всем сервлетам и фильтрам --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml, WEB-INF/dispatcher-servlet.xml</param-value> </context-param> <!--Для FacesServlet --> <listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener> <!-- Welcome page --> <welcome-file-list> <welcome-file>login.xhtml</welcome-file> </welcome-file-list> <!-- JSF Mapping --> <servlet> <servlet-name>facesServlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>facesServlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>facesServlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> <!-- Change to "Production" when you are ready to deploy --> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> <!-- Skip comments in .XHTML view --> <context-param> <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name> <param-value>true</param-value> </context-param> </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:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="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 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <!--Сканирует пакеты для поиска компонентов--> <context:component-scan base-package="ru.javastudy.*"/> <!--Включает Spring MVC @Controller программную модель. (можно сказать аннотации сканирует) --> <mvc:annotation-driven/> <!--Перехватывает HTTP.GET запросы для /resources/**". Эффективно для обработки статических данных в директории {webappRoot}/resources--> <mvc:resources mapping="/resources/**" location="resources"/> <!-- Ищет представление и подставляет переданные данные --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <!--не используйте /WEB-INF/views/* - получите HTTP Status 404 - /WEB-INF/views/*<pageName>.xhtml Not Found in ExternalContext as a Resource--> <property name="suffix" value=".xhtml"/> </bean> </beans> |
Комментарии в коде говорят сами за себя, но хотелось бы отметить, что при конфигурировании префикса не стоит использовать *, т.к. в итоге получите ошибку:
1 |
HTTP Status 404 - *.xhtml Not Found in ExternalContext as a Resource |
faces-config.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?xml version='1.0' encoding='UTF-8'?> <faces-config version="2.2" 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-facesconfig_2_2.xsd"> <!--Обязательно, чтобы JSF View увидели Spring MVC бины (@Controller)--> <application> <el-resolver> org.springframework.web.jsf.el.SpringBeanFacesELResolver </el-resolver> </application> </faces-config> |
В xml файле для JSF нужно указать этот класс:
org.springframework.web.jsf.el.SpringBeanFacesELResolver
без него не сработают аннотации Spring @Controller и будет выходить ошибка
Target Unreachable, identifier 'controllerName' resolved to null .
application-context.xml
1 2 3 4 5 6 |
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> </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 41 42 43 44 |
package ru.javastudy.springmvc.controllers; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; 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; /** * Created by Nick on 01.08.2015. */ @Controller("indexController") public class IndexController { private String name; private String password; public String exampleClick() { return "WEB-INF/views/secondPage"; } @RequestMapping(value = "/secondPage", method = RequestMethod.GET) public ModelAndView secondPage(ModelAndView modelAndView) { modelAndView.setViewName("secondPage"); return modelAndView; } 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; } } |
Изначально мы помечаем класс аннотацией Spring @Controller. После этого все методы удовлетворяющие условиям будут видны в <context:component-scan> (из настроек выше). Теперь немного о методах:
На странице login.xhtml есть две кнопки p:commandButton, у одной из которых установлены такие атрибуты
<p:commandButton action="#{indexController.exampleClick}" value="OK"/>
После нажатия будет вызван метод indexController.exampleClick(), который вернет строковое значение следующего «view».
Если попробовать вбить в браузере URL http://localhost:8080/secondPage,
то запрос будет перехвачен здесь:
1 2 3 4 5 |
@RequestMapping(value = "/secondPage", method = RequestMethod.GET) public ModelAndView secondPage(ModelAndView modelAndView) { modelAndView.setViewName("secondPage"); return modelAndView; } |
и произойдет переход на параметр установленный в методе.
*Отмечу, что это просто пример для понимания базовых процессов JSF+Spring MVC и не стоит его принимать как за базу проектирования веб-приложений.
6. Запуск приложения
Для начала добавим сервер приложений Tomcat 8.0.20. Каких либо настроек не требуется. Единственное нужно добавить артефакт нашего приложения.
Запускаем приложение и переходим на страницу login.xhtml, указанную в атрибуте <welcome-file-list> файла web.xml.
Исходные коды
38 thoughts on “Spring MVC — интеграция с JSF”
Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.
Спасибо за статью, но у меня этот пример почему-то не заработал. Вроде всё как у вас, а получаю ошибку 404
The requested resource is not available
Скачал ваш проект — работает.
Сравнил проекты, подогнал свой под ваш (я делал всё по статье, но обнаружилось немало отличий), но всё равно не работает.
Буду благодарен, если посмотрите на мой проект и укажите на ошибку.
мой проект
Скачал ваш проект и запустил как есть.
Единственное что пришлось поправить: Project Structure-Project-JDK Invalid 1.7 (у меня этой версии просто нет). И поставил 7ю версию language level. (но и без этого должно у вас работать).
Что точно нужно сделать в том, что вы прислали — удалить папку Out (с ней у меня так же 404), зайти в проект и удалить-добавить артифакт со всеми зависимостями. В присланном варианте не добавлен весь спринг и Mojara.
После этого всё заработало с вашей версией.
Ещё хочу добавить, что здесь пример с JSF и Spring MVC, а это конкурирующие технологии. Просто так было быстрее показать что что-то отображается. Зайдите в дебаг в контроллер и дальше ручками вбейте ссылку /secondPage — должен отработать.
Спасибо, ошибка пропала. Отображаются и первая и вторая страничка. Но в отладчике в контроллере не останавливается. Правда я не делал «не добавлен весь спринг и Mojara» (потому что не знаю что и зачем добавлять).
https://yadi.sk/d/Mr-XTNpFjNGFP
Просто без библиотек спринга он работать и не будет. Рад что заработало:)
А каких библиотек спринга у меня не хватает? Сейчас у меня (см.
VitV6Maven8v3.rar\VitV6Maven8\out\artifacts\VitV6Maven8_war_exploded\WEB-INF\lib\) вроде как есть они. Я сравнил наши pom.xml – они совпадают
Возможно я вас огорчу, но ваш проект с предыдущей ссылки запускается как есть. Опять же, я сменил 1.7 на 1.8 Project SDK (скачайте и попробуйте с новым JDK).
Я установил и задал Project SDK: 1.8. Как у меня сейчас работает приложение: открывается первая страница, я ввожу имя и пароль и жму на OK, после чего открывается страничка, отображающая имя и пароль. Но всё равно отладчик не останавливается в контроллере. Что это означает? Как должно работать ваше приложение с контроллером и как без него?
последний вариант моего проекта
Виталий, обновил название статьи, т.к. наверное она сбивала вас с толку. Если нужно чтобы по нажатию кнопки вы видели как отрабатывает контроллер, то прочтите вот это
https://javastudy.ru/spring-mvc/hello-world-example/
Здесь поставьте точку в дебаге в контроллере и введите в браузер путь http://localhost:8080/secondPage и он будет перехвачен контроллером (заметьте что даже если вы только начнете набирать http://localhost:8080/se , то контроллер уже поймет что надо брать запрос:) )