文章越日後越是精華css
1、SpringMvc介紹html
1.什麼是springmvc前端
Spring Web MVC是一種基於Java的實現了Web MVC設計模式的請求驅動類型的輕量級Web框架,即便用了MVC架構模式的思想,將web層進行職責解耦,基於請求驅動指的就是使用請求-響應模型,框架的目的就是幫助咱們簡化開發,Spring Web MVC也是要簡化咱們平常Web開發的。java
2.springmvc優點mysql
清晰的角色劃分:css3
前端控制器(DispatcherServlet)git
請求處處理器映射(HandlerMapping)程序員
處理器適配器(HandlerAdapter)web
視圖解析器(ViewResolver)ajax
處理器或頁面控制器(Controller)
驗證器( Validator)
命令對象(Command 請求參數綁定到的對象就叫命令對象)
表單對象(Form Object 提供給表單展現和提交到的對象就叫表單對象)
分工明確
並且擴展點至關靈活,能夠很容易擴展,雖然幾乎不須要;
無需繼承API直接命令操做
因爲命令對象就是一個POJO,無需繼承框架特定API,可使用命令對象直接做爲業務對象;
與spring無縫銜接
和Spring 其餘框架無縫集成,是其它Web框架所不具有的;
適配任意類做爲處理器
可適配,經過HandlerAdapter能夠支持任意的類做爲處理器;
支持簡單定製
可定製性,HandlerMapping、ViewResolver等可以很是簡單的定製;
功能強大
功能強大的數據驗證、格式化、綁定機制;
靈活的單元測試
利用Spring提供的Mock對象可以很是簡單的進行Web層單元測試;
更容易的主題與國際化
本地化、主題的解析的支持,使咱們更容易進行國際化和主題的切換。
強大的jsp標籤庫
強大的JSP標籤庫,使JSP編寫更容易。
還有好比RESTful風格的支持、簡單的文件上傳、約定大於配置的契約式編程支持、基於註解的零配置支持等等。
2、springmvc運行原理
核心架構的具體流程步驟以下:
1.首先用戶發送請求——>DispatcherServlet,前端控制器收到請求後本身不進行處理,而是委託給其餘的解析器進行處理,做爲統一訪問點,進行全局的流程控制;
2.DispatcherServlet——>HandlerMapping,HandlerMapping將會把請求映射爲HandlerExecutionChain對象(包含一個Handler處理器(頁面控制器)對象、多個HandlerInterceptor攔截器)對象,經過這種策略模式,很容易添加新的映射策略;
3.DispatcherServlet——>HandlerAdapter,HandlerAdapter將會把處理器包裝爲適配器,從而支持多種類型的處理器,即適配器設計模式的應用,從而很容易支持不少類型的處理器;
4.HandlerAdapter——>處理器功能處理方法的調用,HandlerAdapter將會根據適配的結果調用真正的處理器的功能處理方法,完成功能處理;並返回一個ModelAndView對象(包含模型數據、邏輯視圖名);
5.ModelAndView的邏輯視圖名——> ViewResolver, ViewResolver將把邏輯視圖名解析爲具體的View,經過這種策略模式,很容易更換其餘視圖技術;
6.View——>渲染,View會根據傳進來的Model模型數據進行渲染,此處的Model實際是一個Map數據結構,所以很容易支持其餘視圖技術;
7.返回控制權給DispatcherServlet,由DispatcherServlet返回響應給用戶,到此一個流程結束。
更簡流程記憶:
用戶發起請求到前端控制器(Controller)
前端控制器沒有處理業務邏輯的能力,須要找到具體的模型對象處理(Handler),處處理器映射器(HandlerMapping)中查找Handler對象(Model)。
HandlerMapping返回執行鏈,包含了2部份內容: ① Handler對象、② 攔截器數組
前端處理器經過處理器適配器包裝後執行Handler對象。
處理業務邏輯。
Handler處理完業務邏輯,返回ModelAndView對象,其中view是視圖名稱,不是真正的視圖對象。
將ModelAndView返回給前端控制器。
視圖解析器(ViewResolver)返回真正的視圖對象(View)。
(此時前端控制器中既有視圖又有Model對象數據)前端控制器根據模型數據和視圖對象,進行視圖渲染。
返回渲染後的視圖(html/json/xml)返回。
給用戶產生響應。
3、框架組件
DispatcherServlet:前端控制器
用戶請求到達前端控制器,它就至關於mvc模式中的c,dispatcherServlet是整個流程控制的中心,由它調用其它組件處理用戶的請求,dispatcherServlet的存在下降了組件之間的耦合性。
HandlerMapping:處理器映射器
HandlerMapping負責根據用戶請求找到Handler即處理器,springmvc提供了不一樣的映射器實現不一樣的映射方式,例如:配置文件方式,實現接口方式,註解方式等。
Handler:處理器
Handler 是繼DispatcherServlet前端控制器的後端控制器,在DispatcherServlet的控制下Handler對具體的用戶請求進行處理。
因爲Handler涉及到具體的用戶業務請求,因此通常狀況須要程序員根據業務需求開發Handler。
HandlAdapter:處理器適配器
經過HandlerAdapter對處理器進行執行,這是適配器模式的應用,經過擴展適配器能夠對更多類型的處理器進行執行。
View Resolver:視圖解析器
View Resolver負責將處理結果生成View視圖,View Resolver首先根據邏輯視圖名解析成物理視圖名即具體的頁面地址,再生成View視圖對象,最後對View進行渲染將處理結果經過頁面展現給用戶。
View:視圖
springmvc框架提供了不少的View視圖類型的支持,包括:jstlView、freemarkerView、pdfView等。咱們最經常使用的視圖就是jsp。
通常狀況下須要經過頁面標籤或頁面模版技術將模型數據經過頁面展現給用戶,須要由程序員根據業務需求開發具體的頁面。
說明:在springmvc的各個組件中,處理器映射器、處理器適配器、視圖解析器稱爲springmvc的三大組件。
須要用戶開放的組件有handler、view
4、springmvc與struts2不一樣
springmvc的入口是一個servlet即前端控制器,而struts2入口是一個filter過慮器。
springmvc是基於方法開發(一個url對應一個方法),請求參數傳遞到方法的形參,能夠設計爲單例或多例(建議單例),struts2是基於類開發,傳遞參數是經過類的屬性,只能設計爲多例。
Struts採用值棧存儲請求和響應的數據,經過OGNL存取數據, springmvc經過參數解析器是將request請求內容解析,並給方法形參賦值,將數據和視圖封裝成ModelAndView對象,最後又將ModelAndView中的模型數據經過reques域傳輸到頁面。Jsp視圖解析器默認使用jstl。
5、springmvc與struts2有什麼區別?
1. 底層實現機制 match
struts2:filter
springmvc:servlet
2. 運行效率
struts2:底層是Servlet,參數基於屬性封裝,若是配置單例,會出現線程安全問題,因此配置多例
springmvc:底層是Servlet,單例
3. 參數封裝
struts2:基於屬性封裝
springmvc:基於方法進行封裝
6、入門案例
建立工程
導jar包
寫好頁面
建立Controller
建立springmvc.xml
在web.xml中配置前端控制器
註解驅動的做用:
1. 自動建立處理器映射器
2. 自動建立處理器適配器
3. 支持全部註解
4. 支持json格式數據
7、參數綁定
springmvc接收參數方式:直接把接收參數變量放在方法中自動接收參數
1.解決參數亂碼
get請求亂碼:
1).再次編碼
String(request.getParamter(「userName」).getBytes(「ISO8859-1」),」utf-8」)
2). server.xml設置 URIEncoding=」UTF-8」
post請求亂碼:
1). 使用spring編碼過濾器(web.xml),必須配置在前端控制器以前.
2.接收自定義參數
1).註解:@InitBinder:轉換參數
2).自定義轉換工具
在springmvc.xml中配置
3.默認支持的參數類型
1).HttpServletRequest:經過request對象獲取請求信息
2).HttpServletResponse:經過response處理響應信息
3).HttpSession:經過session對象獲得session中存放的對象
4).Model/ModelMap:ModelMap是Model接口的實現類,經過Model或ModelMap向頁面傳遞數據.
model.addAttribute("item", item);
頁面經過${item.XXXX}獲取item對象的屬性值。
若是使用Model則能夠不使用ModelAndView對象,Model對象能夠向頁面傳遞數據,View對象則可使用String返回值替代。無論是Model仍是ModelAndView,其本質都是使用Request對象向jsp傳遞數據。
5).綁定簡單類型:當請求的參數名稱和處理器形參名稱一致時會將請求參數與形參進行綁定。從Request取參數的方法能夠進一步簡化。
4.支持的數據類型
參數類型推薦使用包裝數據類型,由於基礎數據類型不能夠爲null
整形:Integer、int
字符串:String
單精度:Float、float
雙精度:Double、double
布爾型:Boolean、boolean
5.接收POJO
若是提交的參數不少,或者提交的表單中的內容不少的時候可使用pojo接收數據。要求pojo對象中的屬性名和表單中input的name屬性一致。
若是是包裝類型的POJO,包裝對象.
頁面定義:
Controller方法定義以下:
6.接收數組
7.接收list
標籤中varStatus屬性經常使用參數總結下:
8、springmvc註解
經常使用註解:
1. Controller
2. RequestMapping
3. RequestParam
4. Redirect
5. Forward
6. RequestBody/ResponseBody
1.Controller
@Controller:用於標識是處理器類.表示把個人控制器對象交給spring來建立。
Controller起做用:只須要掃描便可。
2.RequestMapping
@RequestMapping :請求映射註解
用法舉例:
1. @RequestMapping(「list.do」)
2. @RequestMapping(「/list.do」)
3. @RequestMapping(「list」)
4. @RequestMapping(value=」list」)
5. @RequestMapping(value=」list」,method.RequestMethod.POST)
get請求:
1. 全部從瀏覽器直接發送的請求,都是get請求
2. href發送的請求都是get請求
post:
1. 表單提交是post請求
2. ajax是post請求
3.URL路徑映射
@RequestMapping:請求處處理器功能方法的映射規則;
URL路徑映射:@RequestMapping(value=」/user」)或@RequestMapping(「/user」)
RequestMethod請求方法限定
4.URL模板映射
@RequestMapping(value="/useredit/{userId}」):{×××}
佔位符請求的URL能夠是
「/useredit/001」或「/useredit/abc」,經過在方法中使用@PathVariable獲取{×××}中的×××變量
實現restFul,全部的url都是一個資源的連接,有利於搜索引擎對網址收錄。
多個佔位符
若是有多個pojo、而且裏面具備相同的屬性,解決方案:
咱們使用包裝類來包裝pojo、通過包裝的pojo至關於加了一層包結構。因此後面即便具備相同的屬性也無所謂。
5.RequestParam
value:參數名字,即入參的請求參數名字,如value=「studentid」表示請求的參數區中的名字爲studentid的參數的值將傳入;
required:是否必須,默認是true,表示請求中必定要有相應的參數,不然將報400錯誤碼;
defaultValue:默認值,表示若是請求中沒有同名參數時的默認值
@RequestParam(defaultValue=」1」,value=」myid」)
功能1:設置默認值
功能2:給參數定義別名,別名和頁面傳遞參數匹配便可
6.Redirect
Contrller方法返回結果重定向到一個url地址.
- 同一個類內跳轉
redirect:add.do 與 redirect:/user/add.do」 在同一個類裏面進行跳轉。上面2個均可以實現跳轉。可是有區別:第一個是同一個根路徑下面跳轉。第二個是在項目路徑下進行跳轉。
- 不一樣的類進行跳轉
不一樣的類進行跳轉只能使用:redirect:/user/add.do進行跳轉。便是從項目路徑下來查詢。
redirect方式至關於「response.sendRedirect()」,轉發後瀏覽器的地址欄變爲轉發後的地址,由於轉發即執行了一個新的request和response。
因爲新發起一個request原來的參數在轉發時就不能傳遞到下一個url,若是要傳參數能夠/user/userlist.do後邊加參數,以下:
/user/userlist.action?groupid=2&…..
7.Forward
controller方法執行後繼續執行另外一個controller方法。
return 「forward:/user/userlist.action」;
forward方式至關於
「request.getRequestDispatcher().forward(request,response)」,轉發後瀏覽器地址欄仍是原來的地址。轉發並無執行新的request和response,而是和轉發前的請求共用一個request和response。因此轉發前請求的參數在轉發後仍然能夠讀取到。
8.json數據交互
@RequestBody註解用於讀取http請求的內容(字符串),經過springmvc提供的HttpMessageConverter接口將讀到的內容轉換爲json、xml等格式的數據並綁定到controller方法的參數上。
@RequestBody註解實現接收http請求的json數據,將json數據轉換爲java對象
@RequestBody/@ResponseBody要依賴Jackson
支持註解,註解映射器和註解適配器可使用代替。
默認註冊了註解映射器和註解適配器等bean。
9、異常處理
springmvc在處理請求過程當中出現異常信息交由異常處理器進行處理,自定義異常處理器能夠實現一個系統的異常處理邏輯。
1.自定義異常
全局異常解析接口 HandlerExceptionResolver
2.自定義異常處理器
3.新建錯誤提示頁面
略
4.異常處理器配置
在springmvc.xml中配置:
10、上傳文件
採用跨服務器異步上傳方式.
1.jar包
依賴:commons-io,commons-fileupload,jersey框架下的jar包
2.配置解析器
配置springmvc.xml
3.配置圖片服務器權限
readonly
false
4.Controller編寫
5.頁面編寫
11、RESTful支持
Restful就是一個資源定位及資源操做的風格。不是標準也不是協議,只是一種風格,是對http協議的詮釋。
資源定位:互聯網全部的事物都是資源,要求url中沒有動詞,只有名詞。沒有參數
Url格式:
http://blog.dn.net/beat_the_world/article/details/45621673
資源操做:使用put、delete、post、get,使用不一樣方法對資源進行操做。分別對應添加、刪除、修改、查詢。
1.前端控制器設置
2.靜態資源訪問
springmvc支持restFull風格軟件架構模式:
1. 沒有擴展名
2. 沒有?方式傳遞參數,參數都在url連接中
3. springmvc提供url默認映射,映射:
@RequestMapping(「/item/deitItem/{id}」)
4. 經過@Pathvariable 映射參數傳遞
12、攔截器
Spring Web MVC 的處理器攔截器相似於Servlet 開發中的過濾器Filter,用於對處理器進行預處理和後處理。
1.自定義攔截器
2.攔截器配置
在springmvc中配置
3.攔截器執行順序
preHandle按攔截器定義順序調用
postHandler按攔截器定義逆序調用
afterCompletion按攔截器定義逆序調用
postHandler在攔截器鏈內全部攔截器返成功調用
afterCompletion只有preHandle返回true才調用
4.攔截器與過濾器的區別
過濾器Filter依賴於Servlet容器,基於回調函數,過濾範圍大
攔截器Inerceptor依賴於框架容器,基於反射機制,只過濾請求
十3、ssm整合
控制層採用springmvc、持久層使用mybatis實現.
1.需求
實現商品查詢列表,從mysql數據庫查詢商品信息。
2.導jar包
包括:spring(包括springmvc)、mybatis、mybatis-spring整合包、數據庫驅動、第三方鏈接池、日誌等。
3.spring與mybatis整合
1).db.properties
2).log4j.properties
3).配置sqlMapConfig.xml
在classpath下建立mybatis/sqlMapConfig.xml
4).配置applicationContext.xml
5).配置ItemsMapper.xml
6).ItemsMapper.java
4.spring管理service
1).Service由spring管理。
2).spring對Service進行事務控制。
service層代碼:
5.spring與springmvc整合
1).配置springmvc.xml
2).web.xml
3).Controller編寫
SpringMVC項目總結:
1、經過指定的url獲取頁面的html
1.爲了不中文亂碼,須要實現指定jsp頁面的編碼爲utf-8,可是若是遇到html頁面的特殊標籤可能會產生一些部分中文亂碼
更好的解決方案能夠用jsonp
maven座標以下:
2.
2、SpringMVC框架裏jsp客戶端向服務端傳遞List類型的參數
客戶端
服務端
接收list數據
三.SpringMVC中的文件下載
4、基於iText和flying saucer結合freemark把html生成pdf (支持css樣式)
項目地址:
http://git.oschina.net/lemonzone2010/doc-render
嘗試了幾個開源項目感受這個效果最好,並且文旦詳盡,須要注意的是
一、不支持css3特殊樣式,html裏若是有中文須要如今css樣式裏申明所用字體
二、項目裏讀取html時使用了freemark技術也可是我本身操做的時候利用總結一里的jsonp讀取更加方便
5、把文件打包生成zip
6、圖片上傳到非工程文件夾下,但願經過該工程的url訪問該圖片
文件上傳到tomcat下的工程下,項目從新啓動圖片就沒了
解決的思路:
在配置文件下配置路徑
BASE_FILEUPLOAD_URL=/upload/username/type/year/month/
BASE_FILEUPLOAD_PATH=../../upload/username/type/year/month/
上傳文件時讀取該路徑並進行拼接:
//文件上傳目錄路徑
String savePath = pageContext.getServletContext().getRealPath(「/」) + BASE_FILEUPLOAD_PATH;
這樣配置之後圖片就上傳到tomcat的一級目錄下了
定義訪問的時候url爲localhost:8080//btkjsite_designcloud/before/getFile/upload/username/type/year/month/20160911.jpg
先根據訪問的url找到圖片的實際物理路徑,再經過輸入流讀取文件,寫入輸出流在網頁上把圖片顯示出來
企業工做實踐SpringMVC總結
一:配置SpringMVC開發環境
任何mvc的框架,都是須要在web.xml中進行核心的配置的,struts2是一個過濾器,而SpringMVC則是一個servlet,可是配置方法大同小異,都是在web.xml中進行配置,配置方法以下:
再而後就是配置springMVC-servlet.xml,這個文件名以前說過,能夠自定義路徑與名稱,若是不自定義,則必定要放在WEB-INFO下,注意引入正確的命名空間,而後加入核心分解解析器,就是解析url的請求,相似於stuts的配置文件,配置以下:
而後就是正式使用SpringMVC了,咱們一般是用註解的方式,由於註解真的太好用了,省事好多,可是這裏也簡單介紹一下使用xml配置文件的方式來寫一個簡單的helloworld
1.1.配置文件的helloworld
首先新建一個類,這個類要實現Controller接口,而後實現它的一個ModelAndView方法,代碼以下:
而後在springMVC-servlet.xml中配置一個bean:配置方法以下:
這種配置和struts2實際上是同樣的,name屬性就是瀏覽器請求的url,而class就是它處理的類,而運行的方法,就是上面所繼承的接口,而後在瀏覽器輸入http://localhost:8080/springMVC/test,就能夠跳轉到welcome.jsp下,這是根據以前配置的視圖分解解析器的先後綴前該方法返回的字符串拼接而成的。
1.2.基於註解的helloworld
使用註解就要簡單得多了,首先是在springMVC-servlet.xml中配置掃描的包,這樣spring就會自動根據註解來描述一些特定的註解,而後把這些bean裝載進入spring容器中,配置以下:
而後,在指定的包,或者其子包下新建一個類,代碼以下:
這樣就不用再寫配置文件,只要加上相應的註解就行,好比說這裏的helloworld方法,只要在瀏覽器輸入http://localhost:8080/project/hellowrold,就能夠進入spring.jsp頁面
二:@RequestMapping詳解
2.1.類的@RequestMapping註解
剛纔看到了@RequestMapping這個註解是用於給一個方法加上url的請求地址,不過,這個註解不只僅能夠加在方法上面,也能夠加在類上面,代碼以下圖所示:
如上代碼如示,若是同時在類與方法上面同時加上@RequestMapping註解的話,那麼URL確定不會是以前的那種寫法了,如今要寫成類的註解加上方法的註解,就是有點相似struts2中,的nameplace屬性,那如如上代碼,URL應該爲http://localhost:8080/project/springMVC/testReuqestMapping
2.2.請求方式的設置
像咱們日常提交一個表單,確定會有get,與post這兩個經常使用的請求,那麼在springMVC中要如何設置呢?很簡單,也是在@RequestMapping中使用,不過須要在方法的註解上面使用,代碼以下:
這下在from表單中,或者異步請求中,就須要以post作爲請求,否則會報錯的,由於這裏已經設置爲了post,若是客戶端再請求get,將會報錯。
2.3.參數的規定與請求頭的規定設置
咱們都知道http請求會有着請求參數與請求頭消息,那麼在springMVC裏面,是能夠規範這些信息的,首先給一段代碼示例:
不管是params,仍是headers,均可以包含多個參數,以逗號相隔就行,若是不知足寫了的條件,則就會報錯,不容許請求資源。其次這兩個屬性還支持一些簡單的表達式:
2.4.@RequestMapping映射中的通配符
在@RequestMapping的value屬性中,還支持Ant格式的能配符:
/user/*/createUser 匹配/user/abcd/createUser
/user/**/createUser 匹配/user/aa/bb/cc/createUser
/user/?/createUser 匹配/user/a/createUser
這裏就不做代碼演示了,相信你們一看就懂,由於這種通配符真的太常見了
2.5.@RequestMapping與@PathVariable註解的一塊兒使用
springMVC很靈活,它能夠獲取URL地址中的值,而後看成變量來輸出,這裏要使用@PathVariable註解,故名思意,就是路徑變量的意思,一般的話,@PathVariable要使用,是必定要與@RequestMapping一塊兒使用的,下面給出代碼示例:
先在括號中加上註解,其中value就是@RequestMapping中佔位符的聲明,而後加上數據類型和定義的變量,這樣就能夠對其進行使用了
2.6.Rest風格的URL
一般的話,表單有着post,與get提交方式,而rest風格的URL,則有着get,post,put,delete這四種請求方式,可是瀏覽器倒是隻支持get與post,因此咱們可使用springMVC,把它進行轉換,咱們要利用org.springframework.web.filter.HiddenHttpMethodFilter這個類,這是一個過濾器,咱們首先要在web.xml中配置它,請配置在第一個位置,否則的話,可能會先進入其它的過濾器,配置代碼以下:
如上的配置,這個過濾器則會攔截全部的請求,咱們能夠看一下org.springframework.web.filter.HiddenHttpMethodFilter的部分源代碼:
當這個過濾器攔截到一個請求時,就會先拿到這個請求的參數,它要知足兩個條件,第一,瀏覽器發出的請求爲post請示,第二,它還要有一個參數,參數名爲_method,而它的值,則能夠爲get,post,delete,put,此時過濾器就會把post請求轉換成相應的請求,否則的話就不進行轉換,直接請求。至於添加_method參數的話,則可使用hidden隱藏域,或者使用?拼接參數均可以。
下面就該是控制器的方法了,在本處第2小點中,有講到@RequestMapping的請求方式的設置,只要把這個請求方式設置成對應的請求就行,好比說轉換成了DELETE請求,則@RequestMapping也要寫成對應的DELETE請求,否則會出錯,示例代碼以下:
此時,就能夠正確轉換請求方式了。
三:獲取http請求中的信息
3.1.獲取請求中的參數,@RequestParam
在獲取相似這種:http://localhost:8080/project/test?user=a&password=2這種請求參數時,就須要用@RequestParam這個註解來獲取,代碼以下:
如上面註釋所寫,它經常使用這三個屬性,value是參數名,可是若是隻寫了參數名的話,請求時,就必須帶此參數,否則就會報錯。若是把required屬性設置爲false,就可使得該參數不傳,還有defaultValue屬性,此屬性能夠當瀏覽器沒有傳此參數時,給這個參數一個默認值
3.2.獲取請求頭的信息,@RequestHeader
以前也有提到過http的請求頭的信息,那麼這裏就可使用@RequestHeader註解來獲取請求頭的信息,它的使用方法與上面的@RequestParam是徹底同樣的,一樣擁有value,requied,defaultValue這三個屬性,而有表明的做用也是同樣的,下面給出代碼示例:
由於它的用法與本章第一點的獲取請求參數的用法同樣,因此這裏就不做過多的說明,詳細能夠查看@RequestParam的用法
3.3.獲取Cookie的信息,@CookieValue
在開發中,有不少狀況都會用到Cookie,這裏可使用@CookieValue註解來獲取,其使用方法與@RequestParam與@RequestHeader同樣,這裏就不過多敘述,給出示例代碼:
它也有着三個屬性,value,required,defaultValue,分別對應Cookie名,是否非空,默認值。
3.4.使用Pojo來獲取請求中的大量參數
若是http請求中只有一兩個參數,那麼使用@RequestParam還能夠,可是若是一個請求中帶有着大量的參數,那麼這樣就有點麻煩了,那麼springMVC就可使用Pojo對象來獲取此次請求中的全部參數,而且所有封裝到這個對象裏面,這種方式相似struts2的ModelDriver,相信使用過struts2的同窗都清楚,這種方式極其簡便,下面一邊給代碼,一邊解釋,首先給出請求的處理方法:
這裏無需使用其它的註解,只須要在這個處理方法中加上一個類就行,那麼springMVC就會自動把請求參數封裝到你寫好的類中,並且這種封裝還支持級聯操做,什麼是級聯操做呢?就是User類中的屬性還有着另外的一個類,下面給出User類的代碼:
由上面可見,其中不只有普通的屬性,還有着一個Address的類,咱們再來看一下Address類的代碼:
能夠很清楚的看清User類與Address類的關係,那麼像這種關係的對象,在瀏覽器form表單中的name屬性該如何寫呢?Address類中的字段,要加上address,好比address.province,或者address.city,其它的屬性,就直接寫User類中的屬性就能夠了。而這裏爲何Address變成了小寫的呢?其實這並非什麼命名規則,而是我在User類中就是這麼定義的
這下沒有什麼問題了吧,咱們再來看一下瀏覽器表單是怎麼寫的:
如上表單元素就能夠看到表單的name屬性是如何與User類對應的,其Address類中的屬性,就以address.city。
下面來講一下這種請求方式的特色:
1.簡便,不須要大量的@RequestParam註解。
2.與struts2的ModelDriver的用法差很少,只不過ModelDriver是接口,整個類裏面全部的方法均可以使用。而springMVC中這個Pojo對象的做用僅僅是當前的處理方法中。
3.這種Pojo的使用中,瀏覽器的參數能夠爲空,就是能夠不傳參數,也不會報錯,不像@RequestParam,若是不指定requried=false的話,還會報錯。
四:Servlet原生API
4.1.使用Servlet原生API
在咱們日常使用springMVC中,雖說springMVC已經幫咱們作了不少工做了,可是咱們實際中仍是會要用到Servlet的原生API,那這個時候要如何獲得Servlet的原生對象呢?這裏與struts2不一樣,springMVC是在方法中聲明對應的參數來使用這些對象,而struts2則是調用相應的方法來獲得這些對象。固然,對於沒有學過struts2的同窗,能夠忽略,下面給出代碼示例:
如上代碼所示,直接在對應的處理方法裏面聲明這些須要使用的對象就能夠了,那若是同時要使用Pojo來得到請求參數怎麼辦呢?這個不用擔憂,照常使用就好了,如上代碼所示,一樣聲明瞭一個User類來接收參數,並不會有任何的影響。
4.2.使用Servlet原生API的原理(部分springMVC的源代碼)
若是你想問,springMVC中的處理方法,裏面能夠支持哪些Servlet的原生API對象呢?或者你又想問,爲何能夠照常的使用Pojo來獲取請求參數呢?那麼這裏,咱們先來看一下springMVC的源代碼,而後再做解釋:
從這裏就能夠說明了一個問題了,springMVC首先會經過反射技術獲得這個方法裏面的參數(源代碼沒有貼上,有興趣的能夠自行查看springMVC的源代碼),而後比較這些參數的類型,是否與上面的九個類型想匹配,若是匹配成功,則返回這個對象,請注意,是與對象類型相匹配,而不是與形參名做匹配,因此這樣,就不會使得Pojo沒法工做了
4.3.springMVC支持哪些原生API
其實從4.2中的源代碼中也是能夠看到了,這裏支持九種個對象,對應關係分別是:
五:頁面中的傳值
5.1.簡單的使用ModelAndView來向頁面傳遞參數
實際開發中,總要大量的向頁面中傳遞後臺的數據,那麼存放數據的方法也有多種多樣,好比說存到request中,你們都知道是使用request.setAtrribute()來向request域中傳遞值,可是實際上springMVC給咱們封裝了更好的方法,那就是使用ModelAndView。
首先,方法的返回值,該由String變成ModelAndView,而後在處理方法中new一個ModelAndView對象,而後返回這個對象就能夠了,對象中能夠增長返回頁面的字符,也能夠向這個對象裏面傳遞參數,如今給出一個簡單的示例代碼:
如上代碼如示,咱們可使用構造方法給它傳一個值,那就是它最終要返回的頁面的值,或者使用setViewName方法來給它一個返回頁面的名字。使用addObject方法來給這個模型添加數據,這是一個鍵值對的數據,而後返回這個ModelAndView對象。
5.2.使用參數Map來向頁面傳值
能夠在執行方法中定義一個Map參數,而後在方法中,向map添加內容,而後在頁面中根據map的鍵來取對應的值,也是存在request域中,下面給出代碼示例:
這裏面就是在方法中有着一個Map類型的參數,其實不只僅能夠是Map類型,還能夠是Model與ModelMap類型的,由於最終傳入的根本就不是Map,而是
org.springframework.validation.support.BindingAwareModelMap
5.3.使用@SessionAttributes註解,把值放到session域中
其實5.1和5.2所訴的內容,雖然是把後臺數據傳遞到前臺,可是所有都是放置到request域中,這裏講訴一下使用@SessionAtrributes註解,把後臺數據同時放到session中。
首先介紹一下這個註解,這個註解只能放在類上面,而不能放在方法上面。它有兩個屬性,一個是value屬性,一個是types屬性,這兩個數據都是數組,因此能夠聲明多個,其實不管是value屬性,仍是types屬性,均可以把數據同時放到session域中,只不過value屬性對應的是執行方法中的map集合的鍵,只要是對應的鍵,那麼其值,也會同時被傳遞到session域中(這裏之因此加上「同時」這個詞,是由於它會同時存到request與session中),而types屬性,則是放置類的集合,只要map集合中存的是該類的數據,則也會同時被放到request中,下面給示例代碼:
如上代碼所示,先是在類上面使用了@SessionScope註解,而後同時使用了value與types屬性,第一個value屬性的值」user」,則是testSessionAtrributes方法中map集合中的」user」的鍵,因此這一個鍵值對會被同時放入session域中,而第二個types的屬性中的String.class,則是表明着這個類了,意思就是說,只要是map集合中放的String類型的數據,都會被放到session中。
注意:使用了value屬性後,這個屬性也就必須存在,意思就是說,必須有一個map,而後有一個user的鍵,否則會報錯,固然,這個是能夠解決的,後面會詳細講到。
5.4.@SessionAtrribute引起的異常
上一講說到使用@SessionAtrribute來修飾一個類,就能夠把一些值存放到session域中,可是若是找不到對應的值,就會報異常,這裏能夠用@ModelAtrribute來進行修飾,對它更名就能夠了,代碼以下:
或者加上一個有着@ModelAtrribute所修飾的方法,至於@ModelAtrribute註解,將會在第六章講到。
六:@ModelAtrribute註解詳解
6.1.簡單介紹@ModelAtrribute及其運行流程
在咱們開發中,會有這樣一種狀況,好比說我要修改一我的的信息,可是用戶名是不讓修改的,那麼我在瀏覽器頁面中確定會有一個表單,裏面有一個隱藏域的id,能夠改密碼,能夠改郵箱,可是用戶名不讓修改,因此咱們不能給用戶名的輸入框,而後用戶修改完數據後,點擊提交保存,而後發現這個時候用戶名不見了!固然你們都會想到就是從新取出用戶名,而後給這個對象賦值,或者先從數據庫裏面找到這個用戶的對象,而後再來修改這個對象,而不是本身來建立對象,@ModelAtrribute註解就是基於這種狀況的。
那麼這種狀況在springMVC中要如何實現呢?
首先給出執行的目標方法的代碼:
這個代碼很簡單,只是使用Pojo來獲取表單的參數,可是User類是不可能從表單獲得用戶名的,因此這個類就缺乏了一個屬性,若是這樣存到數據庫裏面,是確定要出問題的,那麼按照以前所說,咱們能夠先獲得這個User對象,而後給這個對象賦值,可是咱們有着簡化的方法,下面給出@ModelAtrribute註解的用法:
能夠發現,上面的類是沒有返回值的,可是經有一個map集合,咱們把這個從數據庫查出來的user對象放到了Map集合中,而後就不須要作什麼了,而後上面的
testModelAtrribute方法執行的時候,就會自動把用戶名給填充進去。
下面講一個@ModelAtrribute註解的執行流程
1.執行@ModelAtrribute註解修飾的方法:從數據庫中取出對象,並把對象放到了Map中,鍵爲user
2.springMVC從Map集合中取出User對象,並把表單的請求參數賦值給user對象相應的屬性
3.springMVC把上述對象傳入目標方法的參數
4.這個user對象是存在request中,若是jsp表單中有對應的字段,還會自動填充表單
注意:在@ModelAtrribute修飾的方法中,放入Map時的鍵要和目標方法的參數名一致
6.2.@ModelAtrribute源代碼分析
能夠一邊調試一邊查看源代碼,這裏的源代碼有點多,我就不貼出來了,有興趣的同窗能夠本身看,我這裏講訴一下原理:
1.調用@ModelAtrribute註解修飾的方法,其實是把@ModelAtrribute中的Map放到了implicitModel中。
2.解析請求處理器的標參數,實際上目標參數來自於WebDataBinder對象的target屬性
(1).建立WebDataBinder對象
肯定objectName屬性,若傳入的attrName屬性爲」「,則objectName爲類名第一個字母小寫
注意:atrributeName,若目標方法的Pojo屬性使用了@ModelAtrribute註解來修飾,則atrributeName值即爲@ModelAtrribute的value屬性值
(2).肯定target屬性
>在implicitModel中查找atrrName對應的屬性值,若存在ok,若不存在,則驗證Hander,是否使用了@SessionAtrributes進行修飾,若使用了,則嘗試從session中獲取attrName所對應的屬性值,若session中沒有對應的值,則拋出異常
>若Hander沒有使用@SessionAtrributes進行修飾,或@SessionAtrributes中沒有使用value值指定的鍵和attrName相互匹配,則經過反射建立了Pojo對象,這個時候target就建立好了。
3.springMVC把表單的請求參數賦給了WebDataBinder的target屬性
4.springMVC會把WebDataBinder的attrName和target給到implicitModel
5.把WebDataBinder的target做爲參數傳遞給目標方法的入參
6.3.解決@ModelAtrribute註解中,map集合的鍵與執行目標方法的參數名不一致的狀況
其實咱們能夠在目標方法裏面的參數中,定義一個@ModelAtrribute註解,並把其值指定爲@ModelAtrribute註解修飾的方法中的map的鍵,下面給出代碼示例:
能夠看到,目標方法的參數中,有着@ModelAtrribute修飾,其value屬性爲」abc」,再來看一下@ModelAtrribute所修飾的方法:
在這裏就但是很顯示的看到map是存放了一個」abc」的鍵。
七:轉發與重定向
7.1標籤
在springMVC的配置文件中使用標籤可使得url不須要進入handler處理方法,就能夠直接跳轉頁面,配置方法以下
根據如上的配置,就能夠直接在瀏覽器中輸入http://localhost:8080/project/good,就能夠跳轉至success.jsp頁面,而無需進入handler處理方法,更不須要進行@RequestMapping映射。
可是若是僅僅是這樣的配置,會有一個很大的問題,就是以前所寫的handler處理方法所有都不能使用了,所有會進行報錯,那麼要怎麼解決呢?能夠在springMVC的配置文件中,寫一個下面的標籤,就不會有這樣的問題了:
只要寫上這樣的一個標籤,那麼就能夠解決上面的問題,並且也不要寫任何參數。不過這個標籤具體有什麼用呢?後面會做介紹。
7.2.自定義視圖
下面來說一下自定義視圖,使用它能夠很好的和jfreechar或excel整合,下面來具體說明。
首先新建一個視圖,新建一個類,繼承view接口,而後覆蓋裏面的方法,代碼以下:
如上所示,寫一個類,繼承View接口,而後覆蓋裏面的方法,就能夠本身自定義視圖了,可是目前這個視圖尚未用,須要在springMVC的配置文件中進行配置,才能使用這個視圖,配置方法以下:
只要在springMVC的配置文件中寫如上的配置,那麼這個視圖就可使用了,而後咱們寫一個handler處理方法,代碼以下:
而後的話,咱們輸入以下url,http://localhost:8080/project/testView,就不會進行helloView.jsp,由於配置的解析視圖的order值爲最高,也就表明着它的優先級是最低的,因此會先執行咱們自定義的視圖,那麼就會在瀏覽器中顯示以前視圖中向瀏覽器寫的數據。
7.4.視圖的重定向操做
上面所說的所有都是視圖的轉發,而不是重定向,此次我來說一下重定向是怎麼操做的。
只要字符串中以forward或者redirect開頭,那麼springMVC就會把它解析成關鍵字,而後進行相應的轉發,或者重定向操做,下面給出示例代碼:
上面就分別是重定向與轉發操做,其實不止java代碼,標籤中的返回視圖,也能夠加上redirect或者forward字符串,也會進行相應的操做。
八:數據的格式化
8.1 日期格式化
form表單向後臺處理方法提交一個參數的時候,若是提交一個日期的數據,然後臺接收的數據類型則是Date類型,那麼springMVC確定沒法將其轉換成,由於springMVC不知道你傳的數據的格式是怎麼樣的,因此須要爲接收的字段指定日期的格式,使用@DateTimeFormat註解,使用方法以下:
使用前提:須要在springMVC-servlet.xml的配置文件中配置,這個在開發中確定會配置的,由於它有好多做用,若是不配置,則下面代碼無效:
下面是目標方法的代碼:
上面就是在接收的參數前面加了一個@DateTimeFormat註解,註解中寫明pattern屬性,寫上日期的格式,而後在瀏覽器輸入:http://localhost:8080/project/dateFormat?date=19951029,這樣springMVC就能夠把這個字符串轉成Date日期了。
若是是使用Pojo,使用一個對象來接收參數,那麼也是同樣的,一樣是在字段的上方,加上一個@DateTimeFormat註解,以下:
8.2.數字的格式化
除了日期的格式化,咱們可能還會遇到數字的格式化,好比會計人員做帳時,數字喜歡這樣寫 1,234,567.8 由於這樣簡單明瞭,可是若是由java直接來解析的話,確定是不行的,由於這根本就不是一個Float類型的數據,確定是要報錯的,那麼要如何呢?咱們可使用@NumberFormat()註解,這個註解的使用方式,和使用前提和8.1章節,日期的格式化是同樣的,請先查看8.1章節,再看本章。
和以前同樣,是確定要配置的,不過這裏就不詳細說明了,下面給出執行方法的代碼:
其使用方法,實際上是和@DateTimeFormat是同樣的,可是這裏的參數有必要說明同樣,」#「是表明數字,那麼這個時候,就能夠對其進行解析了。若是你傳入的是一個正確的Float類型的數據,那麼它會被正確的接收這個數字,若是不是一個Float類型的數據,那麼springMVC會嘗試使用@NumberFoamat註解的參數來嘗試解析。
如輸入的是http://locathost:8080/project?num=123,那麼springMVC會解析成123.0,若是是http://locathost:8080/project?num=123.1,則會正常顯示成123.1,那若是是http://locathost:8080/project?num=1,234,567.8這種特殊的寫法,則也會正確的解析成1234567.8
8.3.數據的校驗
數據的檢驗是使用Hibernate-validator的擴展註解,它是javaee6.0提出的JSR303的實現,使用它,能夠用註解對數據進行校驗,下面來講一下使用方法。
1.首先要導入jar包,這不是spring的jar包,須要下載Hibernate-validator的jar包,而後添加到項目工程中
2.其次是要在springMVC的配置文件中,即springMVC-servlet.xml中配置,不須要寫其它的屬性:
3.而後在字段面前加上對應的校驗註解,下面以一個bean做一個簡單的例子:
這樣就會對使用了註解的字段進行校驗,而後這樣還不行,還須要指定目標執行方法,因此須要在執行方法上面也加上一個註解@Valid,這樣加了這個註解的執行方法就會校驗數據,下面給出目標方法的註解:
只要在這個方法上面加上@Valid註解,而後這個執行方法就會校驗數據,校驗的結果可使用BindingResult對象顯示,這個對象會不只僅會保存數據校驗的結果,還會保存數據類型轉換的結果,因此均可以使用這個對象獲得相應的信息,顯示的方法以下面的代碼如示。
注意:須要校驗的bean對象與其綁定結果對象或錯誤對象是成對出現的,他們中間不容許聲明其它的參數
8.4.JSR303的驗證類型
經過上面的例子咱們知道可使用註解來驗證數據類型,可是具體可使用哪些註解呢,下面給出說明:
8.5.傳遞json類型的數據
而在springMVC中,使用json很是的簡單,可是首先須要引進其它的一些jar包,那就是jackson,這是一個解析json的jar包,而後就能夠直接使用了,下面給出代碼示例:
如上如示,只要在執行方法的上面加上@ResponseBody註解,而後定義目標方法的返回值,其返回值能夠是任意集合,也能夠是任意對象,而後springMVC會自動將其轉換成json
8.6.文件上傳
springMVC也封裝了文件上傳,變的極其簡單,可是須要引入common-io.jar與common.upload.jar包,而後須要在spinrgMVC-serlvet.xml中做以下的配置:
注意:id必須如上寫法,否則會報錯
而後給出處理方法的代碼:
若是是多個文件上傳,則改成數組,若是是單個,方式也是同樣,與struts2的文件的上傳極其的相似。
九:攔截器
9.1.第一個攔截器
編寫攔截器極其簡單,只要編寫一個類,實現HandlerInterceptor的方法,而後在springMVC的配置文件中配置這個類,就可使用這個攔截器了。
首先給出配置文件的寫法:
而後再來寫FirstInterceptor這個攔截器,代碼以下:
而後在每一個執行方法調用以前,都會先進攔截器,這就是一個簡單的攔截器的寫法了。
9.2.攔截器的指定範圍
在使用攔截器時候,並不必定要對全部的目標方法都進行攔截,因此咱們能夠只對指定的方法進行攔截,這就須要更改配置文件了,下面給出配置文件的寫法:
只須要在中配置一個,而後指定其路徑,就能夠了,這個路徑能夠指定一個URL,也可使用通配符。
9.3.攔截器的使用順序
當同時定義了多個攔截器的時候,那麼它的使用順序是怎麼樣的呢?
preHandle是按配置文件中的順序執行的
postHandle是按配置文件中的倒序執行的
afterCompletion是按配置文件中的倒序執行的