Spring MVC的功能和优点
MVC模式
即Model、View、Controller模式,一种业务逻辑、数据、界面显示分离的代码组织方式,
Model(模型)是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据。
View(视图)是应用程序中处理数据显示的部分, 通常视图是依据模型数据创建的。
Controller(控制器)是应用程序中处理用户交互的部分,通常控制器负责从视图读取数据,控制用户输入,并向模型发数据。
- 基于动作的MVC框架,突出HTTP中的请求/响应特性。通过将每个请求URL映射到一个可执行方法,请求参数映射到方法参数来实现的。
- 视图不可知。视图层不一定要用JSP而可以用其他视图技术。
- 提供组件测试方法
Dispatcher Servlet机制
Dispatcher Servlet配合使用处理器映射(handler mapping)和视图解析器(view resolver)确定用户请求执行哪个业务逻辑以及返回什么内容。过程图示如下
1. Dispatcher Servlet根据HTTP请求确定执行哪个控制器,然后通过处理器适配器调用处理器方法
2. 调用容器内处理方法处理业务逻辑,首先设置模型数据,然后向Dispatcher Servlet返回视图名称
3. Dispatcher Servlet集成视图解析器并根据解析器配置确定合适的视图
4. Dispatcher Servlet将模型传给视图并在浏览器中显示视图
Spring MVC “Hello Reader”显示程序的创建
首先用webapp模板创建maven项目
关于如何修改maven创建的webapp项目中servlet版本,参见Maven创建Webapp项目时,如何设置JDK版本以及servlet版本!
整个工程的目录结构如下:
以下提供一个本书web项目基本都够用的pom.xml模板
<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>org.springframework.samples.service.service</groupId>
<artifactId>SpringAOPTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<!-- Generic properties -->
<java.version>1.6</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Web -->
<jsp.version>2.3.1</jsp.version>
<jstl.version>1.2</jstl.version>
<servlet.version>3.1.0</servlet.version>
<!-- Spring -->
<spring-framework.version>4.3.10.RELEASE</spring-framework.version>
<!-- Hibernate / JPA -->
<hibernate.version>5.2.10.Final</hibernate.version>
<!-- Logging -->
<logback.version>1.2.3</logback.version>
<slf4j.version>1.7.25</slf4j.version>
<!-- Test -->
<junit.version>4.12</junit.version>
<!-- AspectJ -->
<aspectj.version>1.8.10</aspectj.version>
<!-- JSON Evaluation -->
<jackson.version>2.9.0</jackson.version>
<!-- Security -->
<spring-security.version>4.2.3.RELEASE</spring-security.version>
<!-- Database -->
<h2.version>1.4.196</h2.version>
</properties>
<dependencies>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- Other Web dependencies -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>${jsp.version}</version>
<scope>provided</scope>
</dependency>
<!-- Spring and Transactions -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</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-jdbc</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- Logging with SLF4J & LogBack -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<scope>runtime</scope>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- Test Artifacts -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<!-- JSON Evaluation -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring-security.version}</version>
</dependency>
<!-- Database -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.1.v20140609</version>
<configuration>
<scanIntervalSeconds>2</scanIntervalSeconds>
<webApp>
<contextPath>/</contextPath>
</webApp>
</configuration>
</plugin>
</plugins>
</build>
</project>
在其中web.xml文件中使用URL映射定义Dispatcher Servlet:
<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>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.mvc</url-pattern>
</servlet-mapping>
</web-app>
其中<servlet>标签中定义了servlet的名字和实现方法(DispatcherServlet),<servlet-mapping>标签中定义了传给该servlet的URL请求格式。
然后创建springmvc-servlet.xml文件来配置DispatcherServlet
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.wiley.beginningspring.ch3" />
<context:annotation-config />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
该文件中定义的InternalResourceViewResolver决定了视图解析策略,此处将prefix属性定义为/WEB-INF/pages,suffix定义为.jsp,因此返回的视图是WEB-INF/pages目录下的jsp文件。
最后我们创建一个简单的控制器类
@Controller
public class HelloReaderController {
@RequestMapping(value = "/hello")
public ModelAndView sayHello() {
ModelAndView mv = new ModelAndView();
mv.addObject("message", "Hello Reader!");
mv.setViewName("helloReader");
return mv;
}
}
@RequestMapping注解放置在sayHello方法上,确定了调用该方法的HTTP请求格式。返回注入了视图参数和视图名称的ModelAndView实例给Servlet。再由以上配置的servlet返回视图
返回的视图文件helloReader.jsp内容如下
<html>
<body>
${message}
</body>
</html>
可以看到定义了名为message的视图参数,该参数在controller中被注入了值
将工程部署到tomcat服务器
然后启动服务器
在浏览器中输入URL:http://localhost:8080/basic/hello.mvc
得到页面
使用注解配置Spring MVC
除了使用springmvc-servlet.xml以外,还可以用注解配置配置servlet,配置文件如下
@Configuration
@ComponentScan(basePackages = {"com.wiley.beginningspring.ch3"})
public class AppConfig {
@Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/pages/");
resolver.setSuffix(".jsp");
return resolver;
}
}
配置与之前用xml配置的servlet相同,此时web.xml中需要加入新的类和参数获取注解配置
<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>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
com.wiley.beginningspring.ch3.config.AppConfig
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.mvc</url-pattern>
</servlet-mapping>
</web-app>