關(guān)于SpringMVC攔截器和異常

一.文件上傳

1.文件上傳

  • SpringMVC為文件上傳提供了直接的支持吼鳞,這種類型是通過即插即用的MultipartResolver技術(shù)的奄抽。Spring用Jakarta Commons FileUpload技術(shù)實(shí)現(xiàn)了一個(gè)MultipartResolver實(shí)現(xiàn)類:CommonsMultipartResolver.
  • SpringMVC上下文中默認(rèn)沒有裝配MultipartResolver蔼两,因此默認(rèn)情況下不能處理文件的上傳工作,如果想使用Spring的文件上傳功能逞度,需現(xiàn)在上下文中配置MultipartResolver额划。

2. 配置MultipartResolver

  • defaultEncoding:必須和用戶JSP的pageEncoing屬性一致,以便正確解析表單的內(nèi)容档泽。
  • 為了讓CommonsMulitpartResolver正確工作俊戳,必須先將Jakarta Commons FileUpload及Jakarta Commons io的類包添加到類路徑下。
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <propert name="defaultEncoding" value="UTF-8"></property>
    <property name="maxUploadSize" value="524880"></property>
</bean>

二.攔截器

1.自定義攔截器

SpringMVC也可以使用攔截器對(duì)請(qǐng)求進(jìn)行攔截處理馆匿,用戶可以自定義攔截器來實(shí)現(xiàn)特定的功能抑胎,自定義的攔截器必須實(shí)現(xiàn)HandlerInterceptor接口。接口中有三個(gè)方法:

  • preHandle():這個(gè)方法在業(yè)務(wù)處理器請(qǐng)求之前被調(diào)用渐北,在該方法中對(duì)用戶請(qǐng)求request進(jìn)行處理阿逃。如果你決定該攔截器對(duì)請(qǐng)求進(jìn)行攔截處理好還要調(diào)用其他的攔截器,或者是業(yè)務(wù)處理器去進(jìn)行處理赃蛛,則返回true恃锉;如果程序員決定不需要再調(diào)用其他的組件去處理請(qǐng)求,則返回false呕臂。

  • postHandle():這個(gè)方法在業(yè)務(wù)處理器處理完請(qǐng)求后淡喜,但是DispatcherServlet向客戶端返回響應(yīng)前被調(diào)用,在該方法中對(duì)用戶請(qǐng)求request()進(jìn)行處理诵闭。

  • afterCompletion():這個(gè)方法在DispatcherServlet完全處理完請(qǐng)求后被調(diào)用,可以在該方法中進(jìn)行一些資源清理的操作。

2.攔截器方法執(zhí)行順序

image.png

3.配置自定義攔截器

<mvc:interceptors>
      <!--  攔截所有資源 -->
      <bean class="com.desperado.interceptors.FirstInterceptor"></bean>
      <!--攔截指定資源-->
      <mvc:interceptor>
              <mvc:mapping path="/emps"/>
              <bean class="com.desperado.interceptors.SecondInterceptor"></bean>
      </mvc:interceptor>
      <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
</mvc:interceptors>

4.多個(gè)攔截器的執(zhí)行順序

image.png

5.攔截器preHandle()方法返回false時(shí)候的執(zhí)行順序

image.png

6.一道經(jīng)典面試題

攔截器和過濾器有什么區(qū)別:

  1. 攔截器是基于java的反射機(jī)制的疏尿,而過濾器是基于函數(shù)回調(diào)的瘟芝。
  2. 攔截器不依賴于Servlet容器,而過濾器依賴與Servlet容器褥琐。
  3. 攔截器只能對(duì)action請(qǐng)求起作用锌俱,而過濾器則可以對(duì)幾乎所有的請(qǐng)求其作用。
  4. 攔截器可以訪問action的上下文敌呈、值棧里面的對(duì)象贸宏,而過濾器不能訪問。
  5. 在action的聲明周期中磕洪,攔截器可以多次被調(diào)用吭练,而過濾器只能在容器初始化時(shí)被調(diào)用一次、(這里的調(diào)用一次析显,是對(duì)于構(gòu)造函數(shù)而言的鲫咽,而doFilter會(huì)對(duì)匹配的請(qǐng)求做持續(xù)的處理。)
  6. 攔截器可以獲取IOC容器中的Bean谷异,而過濾器不行分尸。

執(zhí)行順序

image.png

三.異常處理

1.異常處理

  • Spring MVC通過HandlerExceptionResolver處理程序的異常把曼,包括Handler映射卡儒、數(shù)據(jù)綁定以及目標(biāo)方法執(zhí)行時(shí)發(fā)生的異常吧兔。
  • SpringMVC提供的HandlerExceptionResolver的實(shí)現(xiàn)類
    - AbstractHandlerExceptionResolver
    - AbstractHandlerMethodExceptionResolver
    - ExceptionHandlerExceptionResolver
    - AnnotationMethodHandlerExceptionResolver
    - DefaultHandlerExceptionResolver
    - ResponseStatusExceptionResolver
    - SimpleMappingExceptionResolver
    - HandlerExceptionResolverComposite

2.HandlerExceptionResolver

  • DispatcherServlet默認(rèn)裝配的HandlerExceptionResolver:
    • 沒有使用<mvc:annotation-driver />
      -AnnotationMethodHandlerExceptionResolver
      -DefaultHandlerExceptionResolver
      -ResponseStatusExceptionResolver

    • 使用了<mvc:annotation-driver />
      -ExceptionHandlerExceptionResolver
      -DefaultHandlerExceptionResolver
      -ResponseStatusExceptionResolver

3.ExceptionHandlerExceptionResolver

  • 主要處理Handler中用@ExceptionHandler注解定義的方法肴楷。
  • @ExceptionHandler注解定義的優(yōu)先級(jí)問題:如果發(fā)生的是NullPointerException胧砰,但是聲明的異常有RuntimeException和Exception瞬沦,此時(shí)會(huì)根據(jù)異常的最近繼承關(guān)系找到繼承深度最淺的那個(gè)@ExceptionHandler注解方法臊泌,即標(biāo)記了RuntimException的方法猫妙。
  • ExceptionHandlerMethodResolver內(nèi)部若找不到@ExceptionHandler注解的話尖昏,會(huì)找@ControllerAdvice中的@ExceptionHandler注解方法

4.ResponseStatusExceptionResolver

  • 在異常及異常父類中找到@ResponseStatus注解仰税,然后使用這個(gè)注解的屬性進(jìn)行處理。
  • 定義一個(gè)@ResponseStatus注解修飾的異常類抽诉。
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public class UnAuthorizedException extends RuntimeException{}
  • 若在處理器方法中拋出了上面定義的異常:
    由于觸發(fā)的異常帶有@ResponseStatus注解陨簇,因此會(huì)被ResponseStatusExceptionResolver解析到。最后響應(yīng)HttpStatus.UNAUTHORIZED代碼給客戶端迹淌。

5.DefaultHandlerExceptionResolver

對(duì)一些特殊的異常進(jìn)行處理河绽,比如:
NoSuchRequestHandlingMethodException
HttpRequestMethodNotSupportedException
HttpMediaTypeNotSupportedException
HttpMediaTypeNotAcceptableException
等。

6.SimpleMappingExceptionResolver

如果希望對(duì)所有異常進(jìn)行統(tǒng)一處理唉窃,可以使用該解析器耙饰,它將異常類名映射為視圖名,即發(fā)生異常是使用對(duì)應(yīng)的視圖報(bào)告異常

四.Spring的運(yùn)行流程

  1. 請(qǐng)求到達(dá)Spring DispatcherServlet的url-pattern纹份。
  2. 判斷SpringMVC中是否存在對(duì)應(yīng)的映射
  3. 如果不存在判斷是否配置了<mvc:default-servlet-handler />
  4. 如果配置了就去找目標(biāo)資源苟跪,如果沒有配置廷痘,返回404頁(yè)面。
  5. 如果存在則從HandlerMapping獲取handlerExecutionChain對(duì)象件已。
  6. 獲取HandlerAdapter對(duì)象笋额。
  7. 調(diào)用攔截器的preHandle方法。
  8. 調(diào)用目標(biāo)Handler的目標(biāo)方法得到ModelAndView對(duì)象篷扩。
  9. 調(diào)用攔截器的postHandle方法兄猩。
  10. 判斷是否存在異常
  11. 存在異常,由HandlerExceptionResolver組件處理異常得到新的ModelAndView對(duì)象鉴未。
  12. 不存在異常枢冤,由ViewResolver組件根據(jù)ModelAndView對(duì)象得到實(shí)際的View
  13. 渲染視圖
  14. 調(diào)用攔截器的afterCompletion方法。
image.png

五.在Spring的環(huán)境下使用SpringMVC

1.Bean被創(chuàng)建兩次?

Spring的IOC容器不應(yīng)該掃描SpringMVC中的Bean铜秆,對(duì)應(yīng)的SpringMVC的IOC容器不應(yīng)該掃描Spring中的Bean淹真。

2.在SpringMVC配置文件中引用業(yè)務(wù)層的Bean

  • 多個(gè)SpringIOC容器之間可以設(shè)置為父子關(guān)系,以實(shí)現(xiàn)良好的解耦羽峰。
  • SpringMVC WEB層容器可作為"業(yè)務(wù)層"Spring容器的子容器趟咆,即WEB層容器可以引用業(yè)務(wù)層容器的Bean,而業(yè)務(wù)層容器卻訪問不到WEB層容器的Bean梅屉。
image.png

六值纱、Spring和Struts2對(duì)比

  1. SpringMVC的入口是Servlet,而Struts2是Filter.
  2. SpringMVC會(huì)比Struts2快點(diǎn)坯汤,SpringMVC是基于方法設(shè)計(jì)的虐唠,而Struts2是基于類,每次發(fā)一個(gè)請(qǐng)求都會(huì)實(shí)實(shí)例一個(gè)Action
  3. SpringMVC使用更加簡(jiǎn)潔惰聂,開發(fā)效率高疆偿。
  4. Struts2的OGNL表達(dá)式使頁(yè)面開發(fā)效率相比SpringMVC要高一點(diǎn)。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末搓幌,一起剝皮案震驚了整個(gè)濱河市杆故,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌溉愁,老刑警劉巖处铛,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異拐揭,居然都是意外死亡撤蟆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門堂污,熙熙樓的掌柜王于貴愁眉苦臉地迎上來家肯,“玉大人,你說我怎么就攤上這事盟猖√忠拢” “怎么了换棚?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)反镇。 經(jīng)常有香客問我圃泡,道長(zhǎng),這世上最難降的妖魔是什么愿险? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮价说,結(jié)果婚禮上辆亏,老公的妹妹穿的比我還像新娘。我一直安慰自己鳖目,他們只是感情好扮叨,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著领迈,像睡著了一般彻磁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上狸捅,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天衷蜓,我揣著相機(jī)與錄音,去河邊找鬼尘喝。 笑死磁浇,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的朽褪。 我是一名探鬼主播置吓,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼缔赠!你這毒婦竟也來了衍锚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤嗤堰,失蹤者是張志新(化名)和其女友劉穎戴质,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體梁棠,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡置森,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了符糊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凫海。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖男娄,靈堂內(nèi)的尸體忽然破棺而出行贪,到底是詐尸還是另有隱情漾稀,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布建瘫,位于F島的核電站崭捍,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏啰脚。R本人自食惡果不足惜殷蛇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望橄浓。 院中可真熱鬧粒梦,春花似錦、人聲如沸荸实。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽准给。三九已至泄朴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間露氮,已是汗流浹背祖灰。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留沦辙,地道東北人夫植。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像油讯,于是被迫代替她去往敵國(guó)和親详民。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容