研究一下spring mvcjava
springMVC是什麼?web
Spring MVC是一種基於Java的實現了Web MVC設計模式的請求驅動類型的輕量級Web框架,將web層進行職責解耦,基於請求驅動指的就是使用請求-響應模型,Spring MVC簡單的說,最主要的做用就是幫咱們簡化開發。spring
springMVC的好處?json
√讓咱們能很是簡單的設計出乾淨的Web層設計模式
√進行更簡潔的Web層的開發;promise
√天生與Spring框架集成(如IoC容器、AOP等);數據結構
√支持靈活的URL到頁面控制器的映射;mvc
√很是容易與其餘視圖技術集成,如Velocity、FreeMarker等等,由於模型數據不放在特定的API裏,而是放在一個Model裏app
√很是靈活的數據驗證、格式化和數據綁定機制,能使用任何對象進行數據綁定,沒必要實現特定框架的API;框架
√支持Restful風格。
一個請求是如何被SpringMVC接受,處理,並返回的:
HandlerAdapter
處理器的適配器,用來綁定數據,解析數據,處理返回值等等。
若是咱們沒有指定默認的HandlerAdapter的時候,spring MVC 會採用默認的類RequestMappingHandlerAdapter來充當Adapter角色。 看一下RequestMappingHandlerAdapter類。
1、 springMVC 之 參數解析器 —— ArgumentResolver
SpringMVC,對你們印象最深入的確定它強大的參數綁定機制,簡單的說就是經過SpringMVC,咱們能夠把前臺各類複雜的數據結構組裝好,後臺直接能夠以對象的方式接收並綁定好數據。
咱們來研究一下spring MVC是如何解析參數而且綁定數據,另外,解析器分別支持哪些參數類型。
有兩個參數,customArgumentResolvers和argumentResolvers,分別是自定義的參數解析器和默認的參數解析器。
接口的定義,HandlerMethodArgumentResolver。
常見的實現(HandlerMethodArgumentResolver的實現)。
很是多,
1>.RequestParamMethodArgumentResolver-->這個解析器可以爲參數上加了RequestParam註解的參數提供支持
2>.RequestParamMapMethodArgumentResolver,支持參數上加了RequestParam註解而且是Map類型的參數.
3>.PathVariableMethodArgumentResolver,支持參數上加了PathVariable註解而且不是Map類型的參數,
4>.PathVariableMapMethodArgumentResolver,支持參數上加了PathVariable註解而且參數類型爲Map的參數,
5>.RequestResponseBodyMethodProcessor支持參數上加了RequestBody註解的參數,
6>.RequestPartMethodArgumentResolver支持參數上了RequestPart註解的參數,
7>.ServletCookieValueMethodArgumentResolver支持參數上加了CookieValue註解的參數.
8>.ExpressionValueMethodArgumentResolver支持參數上加了Value註解的參數
簡單看兩個具體的實現
1>.RequestParamMethodArgumentResolver-->這個解析器可以爲參數上加了RequestParam註解的參數提供支持
1)@RequestParam註解的參數
2)另外一種就是簡單類型,如Integer、String、Date、URI, URL,Locale
3) MultipartFile類型的文件上傳
2>.RequestResponseBodyMethodProcessor—>支持參數上加了@Request註解的參數
它的代言人(封裝和實現)HandlerMethodArgumentResolverComposite。
經過方法getArgumentResolver迭代去尋找可用的resolver直到TRUE;
初始化。
如何增長ArgumentResolver?
WebMvcConfigurationSupport
WebMvcConfigurerAdapter
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(resolver);
}
推薦使用
1、PageableHandlerMethodArgumentResolver
如何自定義添加ArgumentResolver?
如何實現
public Object test(Teacher teacher, Student student){
}
(1) @RequestBody的辦法 (2) 自已定義一個 HandlerMethodArgumentResolver(怎麼定義呢)
2、 springMVC 之 返回值處理器 —— HandlerMethodReturnValueHandler
一個請求中有入參的綁定處理,那麼固然也會有響應參數的處理
HandlerMethodReturnValueHandler就是用來處理當含有@RequestMapping的方法調度完成後,後面要進行的事情。
有兩個參數,customReturnValueHandlers和returnValueHandlers,分別是自定義的返回值處理器和默認的返回值處理器。
常見的實現。
也很是多
1>. ViewNameMethodReturnValueHandler返回值類型是String 或者void類型的
2>. ModelAndViewMethodReturnValueHandler 返回值類型是ModelAndView或其子類
3>. ModelMethodProcessor 返回值類型是Model或其子類
4>. ViewMethodReturnValueHandler 返回值類型是View或其子類
5>. ModelAttributeMethodProcessor 返回值有@ModelAttribute註解
6>. MapMethodProcessor 返回值是Map的
簡單看兩個具體的實現
1>.ViewNameMethodReturnValueHandler 支持處理返回值是void或String的
2>.RequestResponseBodyMethodProcessor 支持處理返回值被@ResponseBody註解的
接口的定義 HandlerMethodReturnValueHandler, 封裝實現是HandlerMethodReturnValueHandlerComposite。
原理和參數解析器同樣, 調用方法 selectHandler ,有所不一樣,多實現了AsyncHandlerMethodReturnValueHandler,支持處理一些異步的返回值,好比promise。
初始化。
如何添加
如何實現自定義的 HandlerMethodReturnValueHandler,
好比要實現返回類型是的某個Tid從long改爲String
@RequestMapping(value = "/test3")
public Object test3(){
Trade trade = new Trade();
trade.setUserId(11878123L);
trade.setTid(91234444L);
trade.setSellerNick("q奇園");
return trade;
}
其中mavContainer.setRequestHandled(true);
標誌着這次請求是不是由handler本身控制的,true表示本方法會響應請求。
使用本身的實現後,須要去除controller方法上的@ResponseBody註解,由於咱們再也不須要使用默認的處理器。
3、springMVC 之 消息轉換器 —— HttpMessageConverter
Http請求和響應報文本質上都是一串字符串,當請求報文被Java讀取以後,它會被封裝成爲一個ServletInputStream的輸入流,供咱們讀取報文。響應報文則是經過一個ServletOutputStream的輸出流,來輸出響應報文。咱們從流中,只能讀取到原始的字符串報文,一樣,咱們往輸出流中,也只能寫原始的字符。可是咱們在Java中, 全部東西都是以對象來作處理的。
咱們不可能手動的把字符串轉成對象,簡單的說,從字符串到java所認識的對象這一處理過程,就是由HttpMessageConverter來完成的。
HttpInputMessage類就是http請求報文的抽象。
HttpOutputMessage類就是SpringMVC內部對一次Http響應報文的抽象
再來看看消息轉換器的抽象 HttpMessageConverter。
常見的實現
StringHttpMessageConverter: 能夠從請求中讀和寫 String data。
FormHttpMessageConverter:能夠從、中讀和寫 form data。
ByteArrayMessageConverter:能夠從請求中讀和寫 byte arrays。
MarshallingHttpMessageConverter:XML的轉換須要使用Spring的 Marshaller 和 Unmarshaller.
MappingJacksonHttpMessageConverter:JSON的轉換.
舉個例子,具體實現
StringHttpMessageConverter
@RequestMapping(value="/string", method=RequestMethod.POST)
@ResponseBody
public String readString(@RequestBody String string) {
return "Read string '" + string + "'";
}
在SpringMVC進入readString方法前,會根據@RequestBody註解選擇適當的HttpMessageConverter實現類來將請求參數解析到string變量中,具體來講是使用了StringHttpMessageConverter類,它的canRead()方法返回true,而後它的read()方法會從請求中讀出請求參數,綁定到readString()方法的string變量中。
當SpringMVC執行readString方法後,因爲返回值標識了@ResponseBody,SpringMVC將使用StringHttpMessageConverter的write()方法,將結果做爲String值寫入響應報文,固然,此時canWrite()方法返回true。
推薦使用
MappingJackson2HttpMessageConverter
通常加上對Java8時間的解析支持。
如何添加messageConvert?
4、請求值和返回值加強 ——RequestBodyAdvice,ResponseBodyAdvice
ResponseBodyAdvice是spring4.1的新特性,其做用是在響應體寫出以前作一些處理;好比,修改返回值、對返回值統一加密等。
接口的定義
看下AbstractMessageConverterMethodProcessor類
咱們通常在方法writeWithMessageConverters以前調用
從這個能夠看出,咱們能夠在使用這些HandlerMethodReturnValueHandler的時候,咱們能對返回值返回以前作統一處理。
初始化
initControllerAdviceCache();
添加ResponseBodyAdvice
首先一個實現類,實現RequestBodyAdvice,而後在類上加上註解@ControllerAdvice,好比有些請求的參數須要作加密處理,能夠在此將json串解密處理,再處理。