步驟:html
maven依賴java
<?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>com.meituan.spring</groupId> <artifactId>mvc</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.14.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.14.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.14.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.14.RELEASE</version> </dependency> </dependencies> <build> <plugins> <!-- 添加編譯插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> </plugin> </plugins> </build> </project>
在Module Settings->Project Settings->Artifacts->output layout中,找到WEB-INF目錄,確認在其下存在lib目錄,不存在則建立,將library files添加進去程序員
web.xmlweb
<?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_4_0.xsd" version="4.0"> <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> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
dispatcher-servlet.xmlspring
<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd "> <context:component-scan base-package="com.meituan.springmvc"/> <mvc:annotation-driven/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
注意:先後綴必定不要出錯數據庫
Controller類apache
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class HelloWorld { @RequestMapping("/helloworld") public String hello() { System.out.println("hello world, hello springmvc !"); return "success"; } }
index.jsp文件瀏覽器
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> <a href="/helloworld">hello world!</a> </body> </html>
視圖jsp文件spring-mvc
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> <h4>success page!</h4> </body> </html>
值得注意的是,在deployment->Deploy at the server startup中添加artifact安全
源碼
@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Mapping public @interface RequestMapping
能夠用來修飾方法,還能夠用來修飾類
params和headers支持簡單的表達式
Ant風格資源地址支持3種匹配符:
@RequestMapping 還支持 Ant 風格的 URL :
@RequestMapping("/delete/{id}") public String delete(@PathVariable("id") Integer id) { System.out.println(id); return "redirect:/user/list.action"; }
REST 即Representational State Transfer。 (資源)表現層狀態轉化。是目前最流行的一種互聯網軟件架構。它結構清晰、符合標準、易於理解、擴展方便, 因此正獲得愈來愈多網站的採用
HiddenHttpMethodFilter: 瀏覽器 form 表單只支持 GET 與 POST請求,而 DELETE、PUT等method並不支持,Spring3.0添加了一個過濾器,能夠將這些請求轉換爲標準的http方法,使得支持GET、POST、PUT與DELETE請求
web.xml
<!--配置org.springframework.web.filter.HiddenHttpMethodFilter:能夠把POST請求轉換爲DELETE或PUT請求--> <filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
jsp
添加一個form,增長一個隱藏域name="_method",指明請求的類型,值取PUT或DELETE
<form action="/testRest" method="post"> <input type="hidden" name="_method" value="DELETE"> <input type="submit" value="TestRest DELETE"> </form>
java
@RequestMapping("/delete/{id}") public String delete(@PathVariable("id") Integer id) { userDao.deleteUserById(id); return "success"; }
在Tomcat8以上版本,會出現問題,須要在jsp文件中添加
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true"%>
指定屬性isErrorPage="true"
在處理方法入參處使用@RequestParam能夠把請求參數傳遞給請求方法
請求頭包含了若干個屬性,服務器可據此獲知客戶端的信息,經過@RequestHeader便可將請求頭中的屬性值綁定處處理方法的入參中
@CookieValue可以讓處理方法入參綁定某個cookie值
SpringMVC會按請求參數名和POJO屬性名進行自動匹配,自動爲該對象填充屬性值,支持級聯屬性
如:dept.deptId、dept.address.tel等
MVC的handler訪求能夠接受如下Servlet API類型的參數
Spring MVC提供瞭如下幾種途徑輸出模型數據:
SpringMVC會把 ModelAndView 裏model 中的數據放入到request域對象( requestScope )中
添加模型數據:
設置視圖:
具體步驟
@SessionAttributes除了能夠經過<u>屬性名</u>指定須要放到會話中的屬性外,還能夠經過模型屬性的<u>對象類型</u>指定哪些模型屬性須要放到session會話中
在方法的入參前使用@ModelAttribute註解:
@ModelAttribute 註解也能夠來修飾目標方法POJO類型的入參,其 value 屬性值有以下的做用:
@ModelAttribute public void getUser(@RequestParam(value="id", required=false) Integer id, Map<String, Object> map) { System.out.println("modelAttribute method"); if (id != null) { //模擬從數據庫中獲取對象 User user = new User(1, "Tom", "123456", "Tom@meituan.com", 12); System.out.println("從數據庫中獲取一個對象: " + user); map.put("user", user); } }
運行流程:
一、 執行@ModelAttribute註解修飾的方法;從數據庫中取出對象,把對象放入到Map中,鍵爲user
二、SpringMVC從Map中取出User對象,並把表單的請求參數賦值給該User對象對應的屬性
三、SpringMVC把上述對象傳入目標方法的參數
注意:在@ModelAttribute修飾的方法中,放入到Map時的鍵須要和目標方法入參類型的第一個字母小寫的字符串一致!
解析請求處理器的目標參數,實際上該目標參數來自於WebDataBinder對象的target屬性,
建立WebDataBinder對象:
注意:attrName,若目標方法的POJO屬性使用了@ModelAttribute來修飾,則attrName值即爲@ModelAttribute的value屬性
在implicitModel中查找attrName對應的屬性值。若存在,ok;若不存在,則驗證當前handler是否使用了@SessionAttributes進行修飾,若使用了,則嘗試從Session中獲取attrName所對應的屬性值,若session中沒有對應的屬性值,則拋出異常;若handler沒有使用@SessionAttribute進行修飾,或@SessionAttributes中沒有使用value值指定的key和attrName相匹配,則經過反射建立POJO對象
肯定一個key
若@ModelAttribute標記的方法在Map中保存過,且key和1肯定的key一致,則會獲取到
org.springframework.web.HttpSessionRequiredException: Session attribute 'user' required - not found in session
若是在處理類定義處標註了@SessionAttributes(「xxx」), 則嘗試從session會話中獲取該屬性,並將其賦給該入參,而後再用請求消息填充該入參對象。若是在會話中找不到對應的屬性,則拋出HttpSessionRequiredException 異常
經常使用的視圖實現類:
若但願直接響應經過SpringMVC渲染的頁面,可使用mvc:view-controller標籤實現:
<!-- 配置直接轉發的頁面 --> <!-- 能夠直接相應轉發的頁面, 而無需再通過 Handler 的方法. --> <mvc:view-controller path="/success" view-name="success"/>
那麼如今能夠直接在某一頁面中經過請求路徑」success」訪問到/WEB-INF/views/success.jsp頁面(由於咱們上面配置了視圖解析器將邏輯視圖解析爲前綴爲/WEB-INF/views/,後綴爲.jsp的物理視圖)。可是,這種狀況下經過控制器就沒法映射到請求了,須要再進行以下配置:
<!-- 在實際開發中一般都需配置 mvc:annotation-driven 標籤, 以前的頁面纔不會由於配置了直接轉發頁面而受到影響 --> <mvc:annotation-driven></mvc:annotation-driven>
通常狀況下,控制器方法返回字符串類型的值會被當成邏輯視圖名處理,但若是返回的字符串中帶forward:或redirect:前綴時,SpringMVC會對它們進行特殊處理:將forward: 和redirect: 當成指示符,其後的字符串做爲URL 來處理。示例以下:
index.jsp:
<a href="${pageContext.request.contextPath }/springmvc/testRedirect">Test Redirect</a>
controller:
@Controller @RequestMapping("/springmvc") public class SpringMVCTest { @RequestMapping("/testRedirect") public String testRedirect() { System.out.println("testRedirect"); return "redirect:/index.jsp"; } }
便可重定向到index.jsp。也可在redirect:/後添加控制器方法的映射路徑,重定向到該目標方法。
經過SpringMVC的表單標籤能夠實現將模型數據 中的屬性和HTML表單元素相綁定,以實現表單
數據更便捷編輯和表單值的回顯
form:input、 form:passwordN form:hidden、 form:textarea :對應 HTML 表車的 text、password、hidden、 textarea 標籤
form:radiobuttons :單選框組標籤,用於構造多個單選
能夠在SpringMVC的配置文件中配置的方式解決靜態資源的問題:
SpringMVC經過反射機制對目標處理方法進行解析,將請求消息綁定處處理方法的入參中。數據綁定的核心部件是DataBinder,運行機制以下:
還將提供如下支持:
由@lnitBinder標識的方法,能夠對WebDataBinder對
象進行初始化。WebDataBinder是DataBinder的子類,用
於完成由表單字段到JavaBean屬性的綁定
@lnitBinder方法不能有返回值,它必須聲明爲void。
@lnitBinder方法的參數一般是是WebDataBinder
FormattingConversionServiceFactroyBean 內部已經註冊了:
以在Spring MVC入參綁定及模型數據輸出時使用註解驅動
了。<mvc:annotation-driven/>
默認建立的ConversionService 實例即爲FormattingConversionServiceFactroyBean
@DateTimeFormat 註解可對java.util.Date、java.util.Calendar、java.long.Long 時間類型進行標註:
@NumberFormat可對相似數字類型的屬性進行標註,它擁有兩個互斥的屬性:
<form:errors path="userName">
顯示錯誤消息Spring MVC也可使用攔截器對請求進行攔截處理,用戶 能夠自定義攔截器來實現特定的功能,自定義的攔截器必須實現 Handlerlnterceptor 接口
DispatcherServlet 默認裝配的HandlerExceptionResolver
<mvc:annotation-driven/>
配置
<mvc:annotation-driven/>
配置
對一些特殊的異常進行處理,好比NoSuchRequestHandlingMethodException、 HttpReques tMethodNotSupportedException、 HttpMediaTypeNotSuppo rtedException、 HttpMediaTypeNotAcceptableException 等
若是但願對全部異常進行統一處理,可使用SimpleMappingExceptionResolver,它將異常類名映射爲視圖名,即發生異常時使用對應的視圖報告異常
須要進行Spring 整合SpringMVC嗎
仍是否須要再加入Spring的IOC容器?
是否須要在web.xml文件中配置啓動Spring IOC容器的ContextLoaderListener?
若Spring的IOC容器和SpringMVC的IOC容器掃描的包有重合的部分,就會致使有的bean會被建立2次
解決: