1. 配置
一個常見的以servlet為主的Java Web與Spring MVC的首要區(qū)別在于WEB-INF文件夾下的web.xml的配置。老式的Servlet項目,web.xml中會配置很多Servlet,處理不同的url。而Spring MVC則將請求用一個前端Servlet來統(tǒng)一分發(fā)到不同的Controller,由Controller控制器處理具體的請求(中間還有Handler Mapping過程,此處略)。這樣就減少了很多不必要的Servlet配置了。
首先配置web.xml,一般來說,以下配置即可夠用:
<?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">
<display-name>SpringMVCDemo Web Application</display-name>
<!--配置log4j-->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<!--配置applicationContext-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.util.Log4jConfigListener
</listener-class>
</listener>
<!--前端Dispatcher-->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!--啟動即加載該servlet-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--處理中文的Filter-->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
名為dispatcher的Servlet,是前端控制器。它有相應(yīng)的配置文件,既可以自己指定一個配置文件,也可以不做處理,但要在WEB-INF文件夾下建立一個dispatcher-servlet.xml的文件,這個就是它默認的配置文件,與它的名字一致。
在dispatcher-servlet.xml文件里,我們對這個前端控制器做一些簡單的配置:
<?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-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">
<!--配置注解驅(qū)動-->
<mvc:annotation-driven />
<!--配置掃描器-->
<context:component-scan base-package="com.chenyi.learn"/>
<!--靜態(tài)文件自動處理-->
<mvc:default-servlet-handler/>
<!--配置視圖解析器-->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
此外注意我們在web.xml文件中配置了一個applicationContext.xml文件,并給了對應(yīng)的目錄。這個文件用于在Spring容器啟動的時候,初始化一些配置。一些開發(fā)中用到的Bean都可以在此處配置。我們現(xiàn)在在里面寫了以下內(nèi)容:
<?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">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="${mysql.db.url}?useUnicode=true&characterEncoding=UTF-8&failOverReadOnly=false&autoReconnect=true" />
<property name="username" value="${mysql.db.user}" />
<property name="password" value="${mysql.db.pwd}" />
<property name="removeAbandoned" value="true"/>
<property name= "testWhileIdle" value="false" />
<property name= "testOnBorrow" value="true" />
<property name= "testOnReturn" value="false" />
<property name= "validationQuery" value="select 1" />
</bean>
</beans>
這里面配置了MySQL的數(shù)據(jù)源的Bean。里面的參數(shù)由pom.xml中依據(jù)對應(yīng)的proflie進行過濾,對了,我們這兒就不用conf.properties來處理MySQL不同環(huán)境不同配置的問題。
2. 先運行起來
首先創(chuàng)建一些分隔代碼要用的包和一些靜態(tài)文件目錄。

注意到j(luò)s文件中我增加了個目前很火的vue的js文件。另外把index.jsp文件修改一下:
<html>
<script src="js/vue.min.js" type="text/javascript"></script>
<body>
<h2>Hello World!</h2>
</body>
</html>
增加對js的引用,運行時用來測試靜態(tài)文件引用是否成功。注意它代碼中的路徑和項目中文件的路徑。另外在dispatcher-servlet.xml中,我們已經(jīng)配置了靜態(tài)文件處理的handler,如果沒有那個配置,會找不到靜態(tài)文件。
Intellij 菜單->Run->Edit Configurations:

"+"增加一個新的Tomcat本地服務(wù)器。這個必須要事先安裝好Tomcat。其實Linux上安裝Tomcat很容易,把下載的包解壓到某個文件夾下,然后在Bash/Zsh配置文件下增加幾個環(huán)境變量就可以了。具體可以Google。比較喜歡這種安裝方式,Hadoop/Hbase/Spark都是這樣安裝的,不像windows下,做了很多我們不知道的事情。配置好了之后是這樣子的:

點擊運行,會自動啟動瀏覽器。

按照js的訪問路徑在瀏覽器上輸入路徑,如果正常訪問,則結(jié)果是這樣子:

通過以上操作我們能夠在本地正常運行Tomcat了,也能運行我們的初始項目了。接下來我們寫一個簡單的controller代碼,開始SpringMVC的學(xué)習(xí)。
簡單的代碼
在controller包下增加一個HomeController.java文件,內(nèi)容如下:
@Controller
@RequestMapping("/")
public class HomeController {
@RequestMapping("/home")
public String sayHome() {
return "home";
}
}
@Controller注解將該類注冊為一個Bean,Spring容器初始化時會創(chuàng)建該類對像。可能有疑問,容器是怎么找到該注解呢?之前我們在dispatcher-servlet.xml中定義了一句代碼:
<!--配置掃描器-->
<context:component-scan base-package="com.chenyi.learn"/>
前端控制器初始化時會掃描這個配置下的代碼,如果發(fā)現(xiàn)帶有@Controller的類,就會為它生成一個Bean。這種方法就是Spring中的注解,即AOP,注意哦,它的實現(xiàn)原理就是動態(tài)代理,有機會把這部分好好梳理一下。
@RequestMapping注解就是把一個類或者某個方法注冊到一個路徑下,前端控制器根據(jù)請求中的路徑,匹配到某個類對象,某個方法進行處理。這也是面向切面編程的方法,我猜想是利用動態(tài)代理把函數(shù)注冊到一個全局變量中,然后根據(jù)這個全局變量查找對應(yīng)方法進行處理。后續(xù)再研究這部分。
我們把sayHome函數(shù)注冊到了/home路徑下。代碼中返回了一個home字符串,這個字符串會用來同dispatcher-servlet.xml里面配置的視圖解析器中的參數(shù)構(gòu)造出返回的html文件及路徑。我們之前的配置是:
<!--配置視圖解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
根據(jù)這個配置,我們的視圖html文件路徑是/WEB-INF/views/home.jsp。于是在代碼的該路徑下創(chuàng)建一個home.jsp文件,內(nèi)容為:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Home</title>
</head>
<body>
Welcome to Home Page!
</body>
</html>
保存,運行,并在瀏覽器中輸入http://localhost:8081/home,會得到如下結(jié)果:

這樣,咱們簡單的運行代碼已經(jīng)實現(xiàn)了。接下來為了更好理解Spring MVC的開發(fā)方法,我們開發(fā)一個能通過Json接口來進行CRUD的小項目。