1 Spring Web MVC
本文将介绍Spring Web MVC的几种配置方法。
2 准备工作
首先得有一个工程,我们随便建一个web工程,比如SpringMvcTest。
按照从零搭建Web应用
中介绍的,先调整下pom.xml文件。
<?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>org.example</groupId>
<artifactId>SpringMvcTest</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
另外,既然是要用Spring Web MVC搭建Web应用,那我们自然需要在pom.xml中增加jar包依赖。
<?xml version="1.0" encoding="UTF-8"?>
<project ...>
...
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
</dependencies>
...
</project>
此外,我们准备一个@Controller
类,用于处理浏览器发送的请求。当在浏览器输入http://localhost:8080/test时,服务器端返回Hello. This is Spring Web MVC.
package org.example.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@RequestMapping("/test")
public String sayHello() {
return "Hello. This is Spring Web MVC.";
}
}
3 使用web.xml
在从零搭建Web应用
中曾说过,Web应用加载的入口是web.xml文件,这一点在Spring Web MVC中也适用。我们在WEB-INF/web.xml文件中进行如下配置:
<?xml version="1.1" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app-context.xml</param-value>
</context-param>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
listener
节点配置监听器,监听的是Web容器ServletContext
的事件,这在ServletContextListener
的定义中可以看出来:
/**
* Interface for receiving notification events about ServletContext
* lifecycle changes.
**/
public interface ServletContextListener extends EventListener {
default public void contextInitialized(ServletContextEvent sce) {}
default public void contextDestroyed(ServletContextEvent sce) {}
}
ContextLoaderListener
是spring-web中的类,其作用是初始化WebApplicationContext
。WebApplicationContext和ServletContext是不同性质的类,WebApplicationContext是Spring的IoC容器,而ServletContext是Web容器类。
public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
initWebApplicationContext(event.getServletContext());
}
@Override
public void contextDestroyed(ServletContextEvent event) {
closeWebApplicationContext(event.getServletContext());
ContextCleanupListener.cleanupAttributes(event.getServletContext());
}
}
上面这段配置的意思是,WebApplicationContext
伴随着ServletContext
对象创建而创建,也跟着ServletContext
对象消亡而消亡,这个特性在所有的Spring Web MVC工程中都是通用的。
servlet
和servlet-mapping
两段配置的意思是所有的请求(/*
)都由DispatcherServlet
类处理。DispatcherServlet
类是何方神圣,为何它能处理所有的请求呢?
这便是MVC模式中所说的控制器功能(Model-View-Controller),其实DispatcherServlet
并不对任何的请求进行具体的处理,它会为每次请求找到某个Controller对象的方法,由它来处理该请求。
contextConfigLocation
属性则配置了一个文件路径,该文件是WebApplicationContext
初始化时用到的配置文件,当中有WebApplicationContext
初始化时需要用到的各类配置。
DispatcherServlet
中引用了WebApplicationContext
对象,利用Spring IoC容器的各种特性完成请求分发处理的工作。WebApplicationContext
中包含了对ServletContext
的引用。这便是DispatcherServlet
、WebApplicationContext
和ServletContext
三者的关系。
在WEB-INF目录下创建app-context.xml文件。
<?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/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="org.example.controller" />
<mvc:annotation-driven/>
</beans>
context:component-scan
配置指明需要扫描注解的package的根路径,这条配置保证我们前面创建的MyController
对象可以被WebApplicationContext
识别并加载到IoC容器中。若没有该配置,DispatcherServlet
便无法识别我们编写的MyController
,那么请求也就无法正确被执行。
mvc:annotation-driven
注解的意思是告诉Spring Web MVC启动自动配置功能。Spring Web MVC具有很强大的自适配功能,可以根据应用环境选择最合适的加载方式,自主确定哪些Bean对象需要在应用启动时加载到IoC容器中。
这样配置完成后,运行应用,在浏览器上输入http://localhost:8080/test便能得到正确的返回了。
4 后续
后续的文章中,将会介绍如何完全舍弃web.xml文件来配置应用。
5 结论
Spring Web MVC框架还是很复杂的,要深入了解还需要多花时间的。