SPRING-SOURCE.RU

1 Часть. Spring MVC Framework работаем с контроллером

MVC — это шаблон, помогающий разделаять презентацию от бизнес логики. Если кратко, в приложении MVC все Web запросы обрабатываются контроллером. Контроллер ответственен за распознавание запросов пользователя и за взимодействие с объектами бизнес логики. Эта бизнес объекты — модель (model). Контроллер, после выполнения входящего запроса, решает, какой view нужно выбрать. View использует данные модели для создания презентации, которая возвращается пользователю.

В этой статье мы научимся работать с контроллерами. Здесь мы покажем три реализации, каждая из которых будет раскрывать особый тип контроллера доступного в Spring.

Давайте начнем

Перед погружением в Spring, мы настроим механизм для развертывания вашего приложения на вашем Web сервере.

Вот структура директорий, которая понадобится вам для создания веб приложения:
/WEB-INF
     /src (java классы)
     /jsp (jsp файлы_
     /lib (jar файлы - библиотеки)
     /classes (скомпилированные классы)

Для тестирования приложения, давайте создадим файл index.jsp и положим его в корневую директорию приложения.

                        
<html>
<head><title>Trading App Test</title></head>
<body>
Trading App Test
</body>
</html>
		

Наберите в адресной строке: http://localhost:8080/tradingapp/index.jsp. Результатом должно быть:

Spring forms

В большинстве серверов, пользователь имеет доступ к корневой директории контекста. Здесь мы обращаемся к файлу index.jsp напрямую. В MVC архитектуре, все входящие вызовы должен обрабатывать контроллер. Чтобы начать это делать, нужно чтобы наши jsp файлы лежали в директории к которой пользователь не имеет прямого доступа. Вот почему мы кладем наши jsp файлы в директорию WEB-INF/jsp. Сюда мы еще вернемся, а сейчас давайте теперь перейдем к реализации контроллера.

Контроллер

Как и в других Web фреймворках, Spring использует сервлет DispatcherServlet для управления всеми входящими запросами (этот шаблон еще называют Front controller). Этот сервлет будет определяться в Web web.xml файле:

                        
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN'
 'http://java.sun.com/dtd/web-app_2_3.dtd'>

<web-app>
     <servlet>
          <servlet-name>tradingapp</servlet-name>
          <servlet-class>
               org.springframework.web.servlet.DispatcherServlet
          </servlet-class>
          <load-on-startup>1</load-on-startup>
     </servlet>
     
     <servlet-mapping>
          <servlet-name>tradingapp</servlet-name>
          <url-pattern>*.htm</url-pattern>
     </servlet-mapping>
     
     <welcome-file-list> 
          <welcome-file>index.jsp</welcome-file>
     </welcome-file-list>
     
</web-app>
		

В web.xml файле, мы определили servlet mapping (соотнесли), который реагирует на любой URL, заканчивающийся на .htm. Если .htm встретилось, мы переходим на tradingapp сервлет (DispatcherServlet). Этот сервлет анализирует входящие запросы URL и определяет, какому контроллеру передать управление. Этот Spring XML файл должен находиться в /Web-INF директории и должен иметь то же имя, что и имя сервлета определенного нами в web.xml файле с -servlet приставкой в конце. Мы создаем tradingapp-servlet.xml файл.

Вот наш Spring XML файл, который DispatcherServlet будет использовать.

                        
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>  
     <bean id="portfolioController" 
           class="com.devx.tradingapp.web.portfolio.PortfolioController">
     </bean>

     <!-- you can have more than one handler defined -->
     <bean id="urlMapping" 
          class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
          <property name="urlMap">
               <map>
                    <entry key="/portfolio.htm">
                         <ref bean="portfolioController" />
                    </entry>
               </map>
          </property>
     </bean>
</beans>
		

Мы назвали бин urlMapping, но Spring... В действительности мы может иметь несколько mapping объектов. Класс SimpleUrlHandlerMaping имеет свойство urlMap, которое связывает URL к объекту, который реализует Controller интерфейс. Когда DispatcherServlet смотрит в файл определения бинов, он будет загружать связывания и будет определять какой контроллер использовать. Мы создали ссылку на PortfolioController.

Существует несколько типов контроллеров доступных в Spring Framework. В этой статье мы рассмотрим три типа контроллеров:

Страница Portfolio

Первым делом нужно изменить страницу index.jsp для redirect (перенаправления) на нашу portfolio страницу. Также мы создадим JSP c названием include.jsp, который будем включать в другие jsp страницы. В этом файле будут содержаться определения общих свойств и тегов.

/index.jsp

                        
<%@ include file="/WEB-INF/jsp/include.jsp" %>

<core:redirect url="/portfolio.htm"/>
		

/WEB-INF/jsp/include.jsp

                        
<%@ page session="false"%>
		

Теперь сделаем простую страницу portfolio View и сделаем, чтобы контроллер мог переходить на нее.

/WEB-INF/jsp/portfolio.jsp

                        
<html>
<head><title>Portfolio Page</title></head>
<body>
Portfolio Page
</body>
</html>
		

/WEB-INF/src/com/devx/tradingapp/web/PortfolioController.java

                        
package com.devx.tradingapp.web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class PortfolioController implements Controller {

    public ModelAndView handleRequest(HttpServletRequest request,
            HttpServletResponse response) {

        return new ModelAndView("/WEB-INF/jsp/portfolio.jsp");
    }

}
		

Controller интерфейс определяет единственный метод:

                 
public ModelAndView handleRequest(HttpServletRequest request, 
HttpServletResponse response) throws java.lang.Exception;		
		

Объект, возвращенный handleRequest методом, является типом ModelAndView. Этот тип представляет Model и View в MVC шаблоне. ModelAndView имеет несколько конструкторов. Один из них мы используем прямо сейчас, он берет String, который представляет view на который мы хотим перейти. Так как наш portfolio.jsp не имеет динамического контента (пока), мы не должны возвращать объект model.

Компилируйте PortfolioController и проверьте чтобы он находился в директории WEB-INF/classes. Далее вы можете попробовать написанное приложение. Снова заходите на index.jsp и вы увидите следующий результат.

Spring forms

Теперь упростим определение нашего view в котроллере. Цель: избежать написания полного пути к JSP внутри контроллера. Этого можно достич за счет использования ViewResolver, который мы укажем в tradingapp-servlet.xml файле. ViewResolver добавляет prefix и suffix к view возращенному контроллером.

/WEB-INF/tradingapp-servlet.xml

                        
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
        <property name="prefix"><value>/WEB-INF/jsp/</value></property>
        <property name="suffix"><value>.jsp</value></property>
</bean>
		

Упростим контроллер.

/WEB-INF/src/com/devx/tradingapp/web/PortfolioController.java

                        
package com.devx.tradingapp.web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class PortfolioController implements Controller {

    public ModelAndView handleRequest(HttpServletRequest request,
            HttpServletResponse response) {

        return new ModelAndView("portfolio");
    }

}
		

Первая часть урока подошла к концу.