Spring web MVC框架提供了模型-视图-控制(Model-View-Controller(MVC))的体系结构和可以用来开发灵活、松散耦合的Web应用程序的组件。MVC模式使应用程序的不同方面(输入逻辑、业务逻辑和UI逻辑)的分离,同时提供了在这些元素之间的松散耦合。

  • 模型(Model)封装了应用程序数据,并且通常它们由POJO组成。
  • 视图(View)主要用于呈现模型数据,并且通常它生成客户端的浏览器可以解释的HTML输出。
  • 控制器(Controller)主要用于处理用户请求,并且构建合适的模型并将其传递到视图呈现。

DispatcherServlet

Spring Web模型-视图-控制(MVC)框架是围绕DispatcherServlet设计的,DispatcherServlet用来处理所有的HTTP请求和响应。Spring Web MVC DispatcherServlet的请求处理的工作流程如下图所示:

Spring的Web MVC框架_java

下面是对应于DispatcherServlet传入HTTP请求的事件序列:

  • 收到一个HTTP请求后,DispatcherServlet根据HandlerMapping来选择并且调用适当的控制器。
  • 控制器接受请求,并基于使用的GET或POST方法来调用适当的Service方法。Service方法将设置基于定义的业务逻辑的模型数据,并返回视图名称到DispatcherServlet中。
  • DispatcherServlet会从ViewResolver获取帮助,为请求检取定义视图。
  • 一旦确定视图,DispatcherServlet将把模型数据传递给视图,最后呈现在浏览器中。

上面所提到的所有组件,即HandlerMapping、Controller和ViewResolver是WebApplicationContext的一部分,而WebApplicationContext是带有一些对Web应用程序有必要且有额外特性的ApplicationContext的扩展。

必须的配置

你需要映射你想让DispatcherServlet处理的请求,通过使用在web.xml文件中的一个URL映射。下面是一个显示声明和映射HelloWeb DispatcherServlet的示例:



<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>Spring MVC Application</display-name>

<servlet>
<servlet-name>HelloWeb</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>HelloWeb</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>

</web-app>


web.xml文件将被保留在你的应用程序的WebContent/WEB-INF目录下。在初始化HelloWebDispatcherServlet时,该框架将尝试加载位于该应用程序的WebContent/WEB-INF目录中文件名为​​[servlet-name]-servlet.xml​​的应用程序内容。在这种情况下,我们的文件将是HelloWeb-servlet.xml。

​<servlet-mapping>​​标签表明哪些URLs将被DispatcherServlet处理。这里所有以.jsp结束的HTTP请求将由HelloWeb DispatcherServlet处理。

如果你不想使用默认文件名​​[servlet-name]-servlet.xml​​和默认位置WebContent/WEB-INF,通过以下参数进行重写:



<servlet>
<servlet-name>mHelloWeb</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- override default name [servlet-name]-servlet.xml -->
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc-myconfig.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>


也可以通过在web.xml文件中添加servlet监听器ContextLoaderListener自定义添加其它文件的名称和位置,如下所示:



<web-app...>
....
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/HelloWeb-context.xml</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

</web-app>


现在,检查HelloWeb-servlet.xml文件的请求配置,该文件位于web应用程序的WebContent/WEB-INF目录下:



<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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
            http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="com.jsoft.testspring" />

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

</beans>


提示:其实这就是一个Beans。

以下是关于HelloWeb-servlet.xml文件的一些要点:

  • [servlet-name]-servlet.xml文件将用于创建bean定义,重新定义在全局范围内具有相同名称的任何已定义的bean。
  • <context:component-scan...>标签将用于激活Spring MVC注解扫描功能,该功能允许使用注解,如@Controller和@RequestMapping等等。
  • InternalResourceViewResolver将使用定义的规则来解决视图名称。按照上述定义的规则,一个名称为hello的逻辑视图将发送给位于​​/WEB-INF/jsp/hello.jsp​​中实现的视图。

定义控制器

DispatcherServlet发送请求到控制器中执行特定的功能。@Controller注解表明一个特定类是控制器的作用。@RequestMapping注解用于映射URL到整个类或一个特定的处理方法。



@Controller
@RequestMapping("/hello")
public class HelloController {
@RequestMapping(method = RequestMethod.GET)
public String printHello(ModelMap model) {
model.addAttribute("message", "Hello Spring MVC Framework!");
return "hello";
}
}


@Controller注解定义该类作为一个Spring MVC控制器。在这里,第一次使用的@RequestMapping表明在该控制器中处理的所有方法都是相对于/hello路径的。下一个注解@RequestMapping(method = RequestMethod.GET)用于声明printHello()方法作为控制器的默认Service方法来处理HTTP GET请求。可以在相同的URL中定义其他方法来处理任何POST请求。

可以用另一种形式来编写上面的控制器,也可以在@RequestMapping中添加额外的属性,如下所示:



@Controller
public class HelloController{
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String printHello(ModelMap model) {
model.addAttribute("message", "Hello Spring MVC Framework!");
return "hello";
}
}


值(value)属性表明URL映射到哪个处理方法,方法(method)属性定义了Service方法来处理HTTP GET请求。关于上面定义的控制器,这里有以下几个要注意的要点:

  • 你将在一个Service方法中定义需要的业务逻辑。你可以根据每次需求在这个方法中调用其他方法。
  • 基于定义的业务逻辑,你将在这个方法中创建一个模型。你可以设置不同的模型属性,这些属性将被视图访问并显示最终的结果。这个示例创建了一个带有属性“message”的模型。
  • 一个定义的Service方法可以返回一个包含视图名称的字符串用于呈现该模型。这个示例返回“hello”作为逻辑视图的名称。

创建JSP视图

对于不同的展现技术,Spring MVC支持许多类型的视图。这些包括JSP、HTML、PDF、Excel工作表、XML、Velocity模板、XSLT、JSON、Atom和RSS摘要、JasperReports等等。但我们最常使用的是利用JSTL编写的JSP模板。所以让我们在/WEB-INF/hello/hello.jsp中编写一个简单的hello视图:



<html>
<head>
<title>Hello Spring MVC</title>
</head>
<body>
<h2>${message}</h2>
</body>
</html>


其中,${message}是我们在控制器内部设置的属性。你可以在你的视图中有多个属性显示。