前言
原創(chuàng)文章轉(zhuǎn)載請注明出處,文中錯誤歡迎指正也切。
使用Spring MVC已經(jīng)有很長一段時間了腰湾,但在使用中還有存在一些模棱兩可的細(xì)節(jié)费坊,趁這次機會爭取將所有的這些問題一一解決旬痹,以便今后更加熟練地使用這個框架來解決問題。
創(chuàng)建一個基于Maven的Web項目
使用的IDE是IDEA永毅,簡單介紹一下步驟:
- 新建一個空的maven類型的module人弓;
- 為這個module添加web支持(本質(zhì)上是在
src/main/
下面添加了一個webapp
目錄,其中webapp
目錄包含WEB-INF/web.xml
目錄和文件)意蛀。事實上健芭,webapp這個目錄的名字可以隨便取慈迈,但是需要在IDEA中配置這個目錄的路徑,以便于在打包的時候谴麦,IDEA可以幫你將該目錄中的內(nèi)容復(fù)制到項目的根目錄下伸头;
添加Spring MVC的maven依賴
使用maven管理jar包依賴非常的方便熊锭。對于Spring MVC而言雪侥,只需要引入一個依賴速缨。在項目的pom.xml
文件中添加spring-webmvc
的依賴:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>
之后代乃,maven會自動解決依賴,并把其依賴的所有jar包引入原茅,如下圖所示:
由上圖可見擂橘,在Spring3.2.3中摩骨,Spring MVC依賴了如下幾個包:
- spring-beans:
- spring-context:
- spring-aop:
- spring-core:
- spring-web:
- spring-expression:
- commons-logging:
- aopalliance:
配置Spring MVC
首先,在resources目錄
下面添加一個config目錄
昌罩,在config目錄
中創(chuàng)建一個名為spring-mvc-config.xml
的文件(resouces/config/spring-mvc-config.xml)來作為Spring MVC的配置文件灾馒。這個文件的名字可以隨便取,因為之后我們可以在web.xml
文件中自定義指定這個文件的位置和名稱绘搞。
配置web.xml
文件
Spring MVC之所以可以整合到web應(yīng)用中傅物,是通過名為一個由框架提供的名為DispatcherServlet
的servlet攔截請求實現(xiàn)的。因此蒿褂,在web.xml
中添加這個servlet卒暂,如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">
<servlet>
<servlet-name>springmvc-app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/spring-mvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc-app</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
需要注意兩點:
-
<init-param>
中指定了該servlet啟動時的參數(shù)contextConfigLocation
也祠,這個參數(shù)的值用來指定Spring MVC的配置文件的位置。 -
<load-on-startup>
通常應(yīng)為正整數(shù)堪旧,指定啟動順序削葱,值越小優(yōu)先級越高析砸。此處設(shè)置為1
表示第一個啟動爆袍。
<url-pattern>
寫成/
和/*
的區(qū)別
注意到,<servlet-mapping>
中的<url-pattern>
參數(shù)為/
弦疮,而如果寫成/*
又有什么區(qū)別呢蜘醋?
先看結(jié)論:
-
<url-pattern>/</url-pattern>
:會匹配到/springmvc
這樣的路徑型url政钟,不會匹配到模式為*.jsp
這樣的后綴型url万皿。 -
<url-pattern>/*</url-pattern>
:會匹配所有的url:路徑型的和后綴型的url(包括/springmvc无蜂,.jsp斥季,.js和*.html等)累驮。
下面是關(guān)于這個問題在stack overflow上的解釋:
原文鏈接:http://stackoverflow.com/questions/4140448/difference-between-and-in-servlet-mapping-url-pattern
簡單的翻譯如下:
<url-pattern>/*</url-pattern>
這種形式將會覆蓋所有其它的servlet。不管你發(fā)出了什么樣的請求躁锡,最終都會在這個servlet中結(jié)束置侍。因此,對于servlet來說杠输,這是一個很糟糕的URL模式秕衙。通常來講,你只會想要在一個Filter中使用這種模式鹦牛。它可以通過調(diào)用doFilter()方法來使請求繼續(xù)搞糕。
<url-pattern>/</url-pattern>
這種形式不會覆蓋任何其它的servlet寞宫。它僅僅替換了servlet容器中內(nèi)建的默認(rèn)servlet拉鹃。這種形式通常只用來請求靜態(tài)資源(CSS/JS/image等)和展示目錄的列表。servlet容器內(nèi)建的默認(rèn)servlet同樣可以處理HTTP cache請求钥屈、媒體(聲音/視頻)流以及文件的下載坝辫。通常來說,你不會想要覆蓋這個默認(rèn)的servlet竭业,否則及舍,你將不得不自己處理一些瑣碎的任務(wù)。因此咐柜,對于sevlet來說攘残,這同樣是一個糟糕的URL模式。說到為什么JSP頁面的請求并不會命中這個servlet遗契,那是因為servlet容器內(nèi)建的JSP servlet將會被調(diào)用病曾,而這個容器內(nèi)建的JSP servlet已經(jīng)默認(rèn)地映射在了*.jsp
上。
<url-pattern></url-pattern>
這種空串的形式捷兰。當(dāng)上下文的根被請求的時候负敏,它將被調(diào)用。這與<welcome-file>
的方式是不同的顶考,因為這種形式在當(dāng)任何子目錄被請求的時候不會被調(diào)用。當(dāng)你期望一個“首頁servlet”的時候艘策,這種URL模式就是適合你的。
配置spring-mvc-config.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"
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="me.johnshen.springmvc.controller"/>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
使用注解標(biāo)識Controller類
package me.johnshen.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/springmvc")
public class HelloWorldController {
@RequestMapping("/helloworld")
public String sayHello(){
System.out.println("Hello World!");
return "helloworld";
}
}
@Controller
表示該類作為項目的控制器組件;
類級別的@RequestMapping
表示所有該類中方法級別的@RequestMapping
都要相對于這個類級別的@RequestMapping
的值驯妄;
方法級別的@RequestMapping
相對于類級別@RequestMapping
的映射路徑合砂。
請求的處理過程
當(dāng)有請求http://localhost:8080/springmvc/helloworld
時,請求會被Spring MVC的DispatcherServlet
攔截翩伪,并映射到HelloWorldController
的sayHello()
方法上處理。
返回的helloworld
將被交給配置在spring-mvc-config.xml
文件中的InternalResourceViewResolver
視圖處理器處理凛剥。
這個處理器的配置將controller中返回的字符串"success"囊颅,加上前綴"/WEB-INF/views/jsp/"傅瞻,加上后綴".jsp",拼成資源的完整路徑"/WEB-INF/views/jsp/helloworld.jsp"嗅骄,最后返回該jsp視圖溺森。