springmvc這個框架真的很是簡單,感受比struts2還更簡單,好好沉澱下來學習~html
--WZY前端
1、什麼是springmvc?java
咱們知道三層架構的思想,而且若是你知道ssh的話,就會更加透徹的理解這個思想,struts2在web層,spring在中間控制,hibernate在dao層與數據庫打交道,而前面剛寫的mybatis跟hibernate同樣,與數據庫打交道在dao層的另外一個框架,而今天所要講解的springmvc是在web層的另外一個框架。web
springmvc全名是spring web mvc,springmvc是spring的一個模塊,而且看名字便可知道,springmvc是一個基於mvc設計模式的前端web框架。spring
mvc:m(model模型)、v(view視圖)、c(control控制)數據庫
mvc的運用概念圖編程
2、springmvc的入門程序json
經過這個來快速瞭解springmvc大概的開發流程,其實經過上面的mvc分析圖,差很少就知道了如何開發了。重點就是三步。設計模式
一、在web.xml中配置一個serlvet,用來控制,數組
二、編寫一個handler(controller)類,用來作業務處理。
三、編寫jsp或者別的視圖,用來展現數據
思路已經有了,那麼就開始編寫把。
問題描述:使用springmvc來完成前端請求的處理
2.一、建立web工程
2.二、添加jar包
2.三、編程步驟
前面三步只是經過mvc圖的分析出最關鍵的三步,其中實現的時候步驟應該更多,好比spring的配置文件,但關鍵的重點仍是那三個。
一、建立po類
二、配置前端控制器,DispatcherServlet
三、建立springmvc的配置文件
四、開發handler(controller)
五、在springmvc的配置文件中(取名爲springmvc.xml)配置handler
六、開發jsp或者別的視圖
八、部署測試
2.四、建立po類
2.五、配置前端控制器
1 <!-- springmvc 的前端控制器 --> 2 <servlet> 3 <servlet-name>springmvc</servlet-name> 4 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 5 <!-- 指定springmvc的配置文件的地址 --> 6 <init-param> 7 <param-name>contextConfigLocation</param-name> 8 <param-value>classpath:springmvc.xml</param-value> 9 </init-param> 10 </servlet> 11 <servlet-mapping> 12 <servlet-name>springmvc</servlet-name> 13 <!-- 這裏有三種配置url-pattern方案 14 一、*.do:後綴爲.do的請求才可以訪問到該servlet[用這個] 15 二、/ :全部請求都可以訪問到該servlet(除jsp),包括靜態請求(處理會有問題,不用) 16 三、/* :有問題,由於訪問jsp也會到該servlet,而訪問jsp時,咱們不須要這樣,也不用 17 --> 18 <url-pattern>*.do</url-pattern> 19 </servlet-mapping>
2.六、建立springmvc的配置文件
在config目錄下,建立springmvc.xml文件
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd "> </beans>
2.七、開發handler(controller)類,也就是處理業務邏輯的類,
2.八、在springmvc.xml中配置handler類,也就是spring幫咱們建立該類的實例,因此須要配置。
注意:2.7和2.8一塊兒講解,由於開發handler類講解三種方式,因此配置也連在一塊兒講解,以避免分開來,看不清楚
Springmvc開發handler有多種方式,咱們只講解三種:實現HttpRequestHandler接口、實現Controller接口、使用註解開發(掌握)
實現HttpRequestHandler接口
1 package com.wuhao.springmvc.controller; 2 3 import java.io.IOException; 4 import java.util.ArrayList; 5 import java.util.List; 6 7 import javax.servlet.ServletException; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 import org.springframework.web.HttpRequestHandler; 12 13 import com.wuhao.springmvc.domain.Items; 14 15 public class ItemController implements HttpRequestHandler { 16 17 @Override 18 public void handleRequest(HttpServletRequest request, HttpServletResponse response) 19 throws ServletException, IOException { 20 //獲取商品列表(用靜態數據模擬) 21 List<Items> itemsList = new ArrayList<Items>(); 22 23 Items items_1 = new Items(); 24 items_1.setName("聯想筆記本 HttpRequestHandler"); 25 items_1.setPrice(6000f); 26 items_1.setDetail("ThinkPad T430 聯想筆記本電腦!"); 27 28 Items items_2 = new Items(); 29 items_2.setName("蘋果手機"); 30 items_2.setPrice(5000f); 31 items_2.setDetail("iphone6蘋果手機!"); 32 33 itemsList.add(items_1); 34 itemsList.add(items_2); 35 36 //把商品數據放到request域中 37 request.setAttribute("itemsList", itemsList); 38 //指定視圖 39 request.getRequestDispatcher("/WEB-INF/jsp/items/itemsList.jsp").forward(request, response); 40 41 } 42 43 }
springmvc.xml中配置該處理器
經過localhost:8080/項目名/queryItems01.do 就可以訪問到DispatcherSerlvet,該servlet就會幫咱們找到你對應的處理器(依據就是經過下面的這行配置,queryItems01對應了一個處理器的class,也就可以找到)
1 <!-- 配置實現HttpRequestHander接口的處理器 --> 2 <bean name="/queryItems01.do" class="com.wuhao.springmvc.controller.ItemController"></bean>
實現Controller接口
1 package com.wuhao.springmvc.controller; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 import org.springframework.web.servlet.ModelAndView; 10 import org.springframework.web.servlet.mvc.Controller; 11 12 import com.wuhao.springmvc.domain.Items; 13 14 public class ItemController02 implements Controller { 15 16 @Override 17 public ModelAndView handleRequest(HttpServletRequest request, 18 HttpServletResponse response) throws Exception { 19 //獲取商品列表(用靜態數據模擬) 20 List<Items> itemsList = new ArrayList<Items>(); 21 22 Items items_1 = new Items(); 23 items_1.setName("聯想筆記本 Controller"); 24 items_1.setPrice(6000f); 25 items_1.setDetail("ThinkPad T430 聯想筆記本電腦!"); 26 27 Items items_2 = new Items(); 28 items_2.setName("蘋果手機"); 29 items_2.setPrice(5000f); 30 items_2.setDetail("iphone6蘋果手機!"); 31 32 itemsList.add(items_1); 33 itemsList.add(items_2); 34 35 //實現Controller接口的話,就必須使用MoldeAndView對象來將數據裝載到對應的jsp視圖上,而後返回該對象便可 36 //因此須要兩步,將數據給該對象,將指定的視圖在交給該對象,最後返回該對象便可。 37 ModelAndView mv = new ModelAndView(); 38 //相似於request.setAttribute("itemsList", itemsList); 39 mv.addObject("itemsList", itemsList); 40 41 //指定視圖 42 mv.setViewName("/WEB-INF/jsp/items/itemsList.jsp"); 43 44 return mv; 45 46 } 47 48 }
配置該handler類
<!-- 配置實現Controller接口的處理器 -->
<bean name="/queryItems02.do" class="com.wuhao.springmvc.controller.ItemController02"></bean>
使用註解開發
註解的配置,就是配置一個掃描器,掃描使用了註解的地方
<!-- 使用註解的handle,則須要配置組件掃描器,加載handler base-package:指定要掃描的包 --> <context:component-scan base-package="com.wuhao.springmvc.controller" ></context:component-scan>
2.九、開發jsp
在WEB-INF/jsp/items/下建立jsp:itemsList.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>查詢商品列表</title> </head> <body> <form action="${pageContext.request.contextPath }/item/queryItem.action" method="post"> 查詢條件: <table width="100%" border=1> <tr> <td><input type="submit" value="查詢"/></td> </tr> </table> 商品列表: <table width="100%" border=1> <tr> <td>商品名稱</td> <td>商品價格</td> <td>生產日期</td> <td>商品描述</td> <td>操做</td> </tr> <c:forEach items="${itemsList }" var="item"> <tr> <td>${item.name }</td> <td>${item.price }</td> <td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/></td> <td>${item.detail }</td> <td><a href="${pageContext.request.contextPath }/editItems.do?id=${item.id}">修改</a></td> </tr> </c:forEach> </table> </form> </body> </html>
2.十、部署測試
測試上面三種採用不一樣的方式編寫的處理類。可以成功訪問即成功
3、springmvc框架原理圖分析
前面瞭解了springmvc的mvc設計模式的運用而且還編寫了一個簡單的實例,關鍵點就幾個,配置DispatcherServlet,編寫處理類以及配置,jsp,就mvc的三個關鍵點,可是這也是粗略的使用一下springmvc,並不知道其中運行的原理,好比
springmvc是如何找處處理器的?
springmvc如何執行處理器的?
springmvc如何查找到視圖對象的?
看圖便可
一、發起請求到前端控制器(DispatcherServlet),該控制器中就會過濾出你哪些請求能夠訪問該servlet哪些不能夠,就是url-pattern的做用,而且會加載springmvc.xml配置文件
二、前端控制器會找到HandlerMapping(處理器映射器),經過HandlerMapping完成url到controller映射的組件,通俗點講,就是將在springmvc.xml中配置的或者註解的url與對應的處理類找到並進行存儲,其實是用一個map集合來保存這種映射關係,map<url,handler>; 這樣,就將全部的這種映射關係都記錄保存了下來
三、經過HandlerMapping有了這些映射關係,而且找到了url對應的處理器,HandlerMapping就會將其處理器(圖中紅色標明的handler)返回,在其返回以前,在加上不少的攔截器,其做用後面
進行講解,這裏知道在返回的處理器前會有不少的攔截器便可。
四、DispatcherServlet拿到了handler以後,找到HandlerAdapter(處理器適配器),經過它來訪問處理器,而且執行處理器。
這裏會有人會有疑惑,爲何須要處理器適配器,咱們都得到了處理類了,直接調用不就好了嗎?
不行,由於咱們只知道處理類在哪裏,並不知道執行處理類中的哪一個方法,其實也就是不知道處理類是經過哪一種方式建立出來的,實現HttpRequestHandler?仍是註解方式,或者是 其餘方式,咱們不知道,因此須要HandlerAdapter來幫咱們確認調用哪一個方法。
五、執行處理器
六、處理器會返回一個ModelAndView對象給HandlerAdapter
七、經過HandlerAdapter將ModelAndView對象返回給前端控制器(DispatcherServlet)
八、前端控制器請求視圖解析器(ViewResolver)去進行視圖解析,根據邏輯視圖名解析成真正的視圖(jsp),其實就是將ModelAndView對象中存放視圖的名稱進行查找,找到對應的頁面造成視圖對象
九、返回視圖對象到前端控制器。
十、視圖渲染,就是將ModelAndView對象中的數據放到request域中,用來讓頁面加載數據的。
十一、經過第8步,經過名稱找到了對應的頁面,經過第10步,request域中有了所須要的數據,那麼就可以進行視圖渲染了。最後將其返回便可。
經過上面的圖和分析過程,就可以完美解答上面的三個問題了。理解了圖,那麼springmvc就會用了。很簡單把,跟struts2差很少,記住原理圖便可。
4、組件分析(默認組件和手動配置組件)
經過圖能夠看到
前端控制器:對其餘組件進行解耦,這樣就增長了組件的可擴展性 無需開發直接配置
處理器映射器:無需開發,直接用,做用見上面
處理器適配器:無需開發,
處理器:須要開發,方式不少
視圖解析器:無需開發
視圖:須要開發
就這麼點東西,真正須要寫的就兩個(處理器+視圖)和一個配置(前端控制器),就是mvc中的三個重點,在第二小節中就是這樣編寫的,第三小結就是解釋其中的原理。
處理器映射器、處理器適配器、視圖解析器這三個是默認配置的,在下面位置中能夠查看
DispatchServlet.properties
上面是使用默認的,若是沒有配置這幾個組件,那麼就使用默認的,咱們也能夠手動指定。
4.一、非註解的處理器映射器和處理器適配器 [看看便可]
BeanNameUrlHandlerMapping:映射器
在springmvc配置文件中,配置BeanNameUrlHandlerMapping
他的做用是找到在springmvc.xml中配置的url和處理器的bean
HttpRequestHandlerAdapter:適配執行實現了HttpRequestHandler接口的處理類的方法
在springmvc配置文件中,配置HttpRequestHandlerAdapter
它的做用就是適配實現了HttpRequestHandler接口的處理類,也就是找到該處理類對應的方法
如何適配,就是須要看源碼了,能夠百度一下講解該適配器的源碼。
SimpleControllerHandlerAdapter:適配執行實現了Controller接口的處理類的方法
在springmvc配置文件中,配置SimpleControllerHandlerAdapter
總結:這就是非註解的組件的配置方式,很簡單,注意
處理器映射器和處理器適配器能夠配置多個
處理器映射器和處理器適配器能夠混用
4.二、配置註解的處理器映射器和適配器(掌握)
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping 是在spring3.1以前使用的註解映射器
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping是在spring3.1以後使用的註解映射器
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter 是在spring3.1以前使用的註解適配器
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter是在spring3.1以後使用的註解配置器
注意:
一、註解方式的映射器和適配器在3.1版本先後是不同的,使用3.1以後的
二、註解方式的處理器映射器和處理器適配器必須配對使用,不能與非註解的處理器映射器和適配器混用(用了註解的就不能在配置非註解的,二選一)
配置方式有兩種:
一、使用bean標籤配置
二、使用mvc標籤(推薦)
4.三、視圖解析器
4.3.一、JSP視圖解析器(默認的就是使用該解析器)
其中兩個配置的意思是:prefix:前綴 suffix:後綴 。 配置以後在指定視圖時,就不用寫這前綴和後綴了,直接寫關鍵代碼便可。看下圖
雖然指定視圖只寫 items/itemsList 可是會幫咱們加上咱們配置的前綴和後綴,也就是變爲了 /WEB-INF/jsp/items/itemsList.jsp
4.3.2 Freemarker視圖解析器
org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver
等何時使用到了在學習把。
5、requestMapping註解的三種功能
requestMapping有三種功能:映射請求url、窄化請求、限制請求方法
5.一、映射請求url
也就是寫在方法上,上面咱們已經用過了這種功能,這裏詳細講解一下
@RequestMapping(value="/item,/user")或@RequestMapping("/item」) value是數組,能夠將多個url映射到同一個方法上,用逗號隔開便可。若是value中只有一個屬性,則能夠省去value,就像這樣:@RequestMapping(value="/item ")寫成@RequestMapping("/item」)
5.二、窄化請求
在class上面加上requestmapping註解,能夠對url進行分類管理,這樣也實現了請求的窄化
加在class上
加在方法上
訪問路徑爲:http://localhost:8080/xxx/items/queryItems.do
5.三、限制請求方法
限制訪問該方法必須是get或者post方式,至關於對請求進行過濾。
限定GET方法,也就是隻能容許get請求方式過來的請求訪問
@RequestMapping(method = RequestMethod.GET)
若是post請求方式的過來訪問,則報錯 HTTP Status 405 - Request method 'POST' not supported
限定post方法。
@RequestMapping(method = RequestMethod.POST)
若是get請求方式過來訪問,報錯 HTTP Status 405 - Request method 'GET' not supported
get、post均可以
@RequestMapping(method={RequestMethod.GET,RequestMethod.POST})
6、controller類中的方法返回值問題
一樣有三種:ModelAndView對象、void、String
6.一、返回ModelAndView對象
controller方法中定義ModelAndView對象並返回,對象中可添加model數據、指定view。 而後經過視圖解析器對其進行解析。上面用的就是這個。不用在過多的解釋了
6.二、void
若是返回值爲void的時候,能夠在controller方法形參上定義request和response,使用request或response指定響應結果(這裏在形參上定義request和response,還沒講到。可是能夠這樣用,至關於controller方法上默認有這兩個形參。加上去就可使用)
使用request轉向頁面,以下
request.getRequestDispatcher("頁面路徑").forward(request, response)
經過response頁面重定向
response.sendRedirect("url")
能夠經過response指定響應結果,例如響應json數據以下
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");
6.三、String
使用一:返回邏輯視圖
解釋:形參中有Model對象,該對象也是默認形參,只要聲明瞭,就能夠拿過來用,該Model對象的做用就是添加屬性到request做用域中的,就跟ModelAndView對象添加值到request做用域中同樣,只是model對象不可以指定視圖。正好其model就是modelAndView的一半,很好理解。 其次,由於沒有采用modelAndView對象,因此不可以指定視圖,可是能夠直接返回視圖地址便可,效果是跟使用modelAndView對象同樣的。
使用二:請求轉發