日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringMVC自定义拦截器与异常处理(自定义异常)

發布時間:2024/4/15 javascript 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringMVC自定义拦截器与异常处理(自定义异常) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

SpringMVC自定義攔截器與異常處理

攔截器概念



攔截器代碼演示

創建maven工程

pom.xml

<?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>org.example</groupId><artifactId>day02_SpringMVC_Interceptor</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><!-- 版本鎖定--><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><spring.version>5.1.9.RELEASE</spring.version></properties><dependencies><!-- spring--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><!-- servlet3.0規范的坐標 --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><!--jsp坐標--><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.1</version><scope>provided</scope></dependency><!-- lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency><!--json相關坐標3--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.9.0</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.0</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.9.0</version></dependency></dependencies><build><plugins><!--tomcat插件--><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version><configuration><port>80</port><path>/</path><!-- 配置tomcat插件編碼,因為請求的數據會經過tomcat.所以在tomcat也要設置一下編碼--><uriEncoding>UTF-8</uriEncoding></configuration></plugin></plugins></build> </project>

web.xml

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"version="3.0"><!--springMVC程序啟動流程1.tomcat啟動首先加載web.xml2.保證DispatcherServlet能夠正常加載配置文件3.spring配置文件必須掃描有spring注解的的包--><!-- 配置調度服務器(前端控制器),配置后就能夠去調度controller中的路徑--><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><!-- 初始化DispatcherServlet,初始化springIOC容器,讀取類路徑下的spring-mvc.xml配置文件(target/classes/就會有這個配置文件),掃描controller注解下的RequestMapping的路徑--><param-name>contextConfigLocation</param-name> <!-- <param-value>classpath:spring-mvc.xml</param-value>--><param-value>classpath:spring-mvc.xml</param-value></init-param><!-- 配置load-on-startup元素表示這個servlet應該是在啟動時加載(實例化并調用其init())的web應用程序。--><load-on-startup>1</load-on-startup></servlet><!--配置請求調度服務--><servlet-mapping><!-- 配置調度服務--><servlet-name>dispatcherServlet</servlet-name><!--在spring中, / /*/ : 匹配所有的請求/* :匹配所有的請求,查詢結果頁面,都是以文本顯示,不會做任何的渲染頁面,包括jsp頁面--><url-pattern>/</url-pattern></servlet-mapping><!-- 配置過濾器,來解決post請求亂碼問題--><filter><filter-name>characterEncodingFilter</filter-name><!-- 加載spring提供的過濾器--><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><!-- 設置過濾器中的屬性值--><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><!-- 啟動過濾器--><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><!-- 過濾所有請求--><filter-mapping><filter-name>characterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping> </web-app>

spring-mvc.xml

注意在核心配置文件中配置自定義攔截器的bean

<?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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 設置掃描spring注解的包--><context:component-scan base-package="com.fs.springmvc"/><!-- 靜態資源加載,核心控制器攔截的是所有請求,需要對靜態資源請求進行放行,通過配置放行資源實現下面這個配置是可以放行所有的普通資源調用讓springMVC不處理靜態資源,.css .js .html .MP3 等--><mvc:default-servlet-handler/><!-- 配置注解驅動的Spring MVC控制器編程模型. 一、mvc:annotation-driven的作用 Spring 3.0.x中使用了mvc:annotation-driven后,默認會幫我們注冊默認處理請求,參數和返回值的類,其中最主要的兩個類:DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter ,分別為HandlerMapping的實現類和HandlerAdapter的實現類,從3.1.x版本開始對應實現類改為了RequestMappingHandlerMapping和RequestMappingHandlerAdapter。HandlerMapping的實現類的作用 實現類RequestMappingHandlerMapping,它會處理@RequestMapping 注解,并將其注冊到請求映射表中。HandlerAdapter的實現類的作用 實現類RequestMappingHandlerAdapter,則是處理請求的適配器,確定調用哪個類的哪個方法,并且構造方法參數,返回值。當配置了mvc:annotation-driven/后,Spring就知道了我們啟用注解驅動。然后Spring通過context:component-scan/標簽的配置,會自動為我們將掃描到的@Component@Controller@Service@Repository等注解標記的組件注冊到工廠中,來處理我們的請求。 --><mvc:annotation-driven/><!-- 配置視圖解析器,方便訪問jsp頁面,并交給spring管理--><bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 視圖解析前綴(訪問前綴)--><property name="prefix" value="/WEB-INF/pages/"/> <!-- 視圖解析后綴(訪問后綴)--><property name="suffix" value=".jsp"/></bean><!--開啟攔截器使用--><mvc:interceptors><!--開啟具體的攔截器的使用,可以配置多個--><mvc:interceptor><!--設置攔截器的攔截路徑,支持*通配--><!--/** 表示攔截所有映射--><!--/* 表示攔截所有/開頭的映射--><!--/user/* 表示攔截所有/user/開頭的映射--><!--/user/add* 表示攔截所有/user/開頭,且具體映射名稱以add開頭的映射--><!--/user/*All 表示攔截所有/user/開頭,且具體映射名稱以All結尾的映射--><mvc:mapping path="/*"/><mvc:mapping path="/**"/><mvc:mapping path="/handleRun*"/><!--設置攔截排除的路徑(配置不攔截的路徑),配置/**或/*,達到快速配置的目的--><mvc:exclude-mapping path="/b*"/><!--指定具體的攔截器類--><bean class="com.fs.springmvc.interceptor.MyInterceptor"/></mvc:interceptor><!--配置多個攔截器,配置順序即為最終運行順序--><mvc:interceptor><mvc:mapping path="/*"/><bean class="com.fs.springmvc.interceptor.MyInterceptor2"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/*"/><bean class="com.fs.springmvc.interceptor.MyInterceptor3"/></mvc:interceptor></mvc:interceptors> </beans>

創建自定義攔截器類(代碼中注釋有詳細解釋)

MyInterceptor

package com.fs.springmvc.interceptor; /* 攔截器與過濾器有什么不同Interceptor攔截器是SpringMVC的技術,攔截控制的controller,攔截springIOC中的controllerfilter過濾器是tomcat中所有的接收到的請求都可以被攔截,包括spring中的controller//三個方法的運行順序為 preHandle -> controller中被攔截的方法執行 ->postHandle -> afterCompletion//如果preHandle返回值為false,三個方法僅運行preHandle由HandlerInterceptor接口源碼得知,方法被default修飾了(java8新特性)被默認實現了方法的,所以我們自定義攔截器沒有強制我們重寫接口中的方法所以我們需要自己重寫接口中的方法實現自定義攔截器的具體功能HandlerInterceptor接口源碼public interface HandlerInterceptor {default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return true;}default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {}default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {} }*/ import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //自定義攔截器需要實現HandleInterceptor接口,實現這個接口沒有被強制現實所有方法 //是因為HandlerInterceptor接口中的方法有默認的default實現方法,所以我們需要自己重寫接口中的方法 public class MyInterceptor implements HandlerInterceptor {//處理器運行之前執行@Overridepublic boolean preHandle(HttpServletRequest request,//請求攜帶的requestHttpServletResponse response,//響應攜帶的Response//handler就是我們執行的controller方法路徑Object handler) throws Exception {//下面打印的就是我們自己寫的controller的方法,使用反射技術//public java.lang.String com.fs.springmvc.controller.InterceptorController.handleRun()///System.out.println(handler.toString());System.out.println("前置運行----a1");//返回值為false將攔截原始處理器的運行,訪問的controller中的方法不會被執行,//而且后面的postHandle,afterCompletion也不會執行//如果配置多攔截器,返回值為false將終止當前攔截器后面配置的攔截器的運行return true;}//處理器運行之后執行@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,//controller執行方法后要返回的視圖ModelAndViewModelAndView modelAndView) throws Exception {System.out.println("后置運行----b1");}//所有攔截器的后置執行全部結束后,執行該操作@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,//Exception ex) throws Exception {System.out.println("完成運行----c1");}//三個方法的運行順序為 preHandle -> postHandle -> afterCompletion//如果preHandle返回值為false,三個方法僅運行preHandle }

MyInterceptor2

package com.fs.springmvc.interceptor;import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class MyInterceptor2 implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {System.out.println("前置運行------a2");return true;}@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) throws Exception {System.out.println("后置運行------b2");}@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) throws Exception {System.out.println("完成運行------c2");} }

MyInterceptor3

package com.fs.springmvc.interceptor;import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class MyInterceptor3 implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {System.out.println("前置運行--------a3");return true;}@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) throws Exception {System.out.println("后置運行--------b3");}@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) throws Exception {System.out.println("完成運行--------c3");} }

controller

InterceptorController

package com.fs.springmvc.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.config.annotation.EnableWebMvc;//@Controller public class InterceptorController {@RequestMapping("/handleRun")public String handleRun() {System.out.println("controller業務處理器運行------------main");return "page";} }

測試

輸入地址訪問:

控制臺輸出

攔截器執行流程

攔截器參數



核心配置文件中關于攔截器的配置

攔截器鏈配置

異常處理

我們在controller中調用業務層出現了異常,我們不可能給前端響應一大堆異常信息,所以,我們需要將我們的異常進行封裝返回給前端,然后前端對異常進行友好的提示告知客戶

HandlerExceptionResolver接口方式(異常處理器)

package com.fs.springmvc.exception;import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /* 自定義異常類,必須實現異常處理程序解析器HandlerExceptionResolver接口,重寫resolveException()方法 自定義異常類(全局(IOC類)異常管理)@Component注解后spring發現這個類實現了HandlerExceptionResolver接口,就認定為異常處理的類,然后就會對所有的IOC管理的對象的方法進行異常處理,當IOC管理的類的方法執行出現異常了,就會到達異常處理類的resolveException()方法,執行里面的異常處理邏輯使用自定義異常類處理異常是在controller的方法加載參數后才會加載這個類,就會導致前端傳遞參數 的時候,SpringMVC將前端傳遞過來參數封裝到方法的參數的時候出現類型轉換異常,就不會對這個異常進行處理 所以爭對這個問題,出現了注解方式處理異常.注解處理器就可以攔截Dao入參類型轉換異常*/ @Component public class ExceptionResolver implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) {System.out.println("自定義異常類正在運行 ...."+ex);ModelAndView modelAndView = new ModelAndView();//對異常類型進行判斷使用instanceof關鍵字if( ex instanceof NullPointerException){//將異常數據返回給前端modelAndView.addObject("msg","空指針異常");}else if ( ex instanceof ArithmeticException){//將異常數據返回給前端modelAndView.addObject("msg","算數運算異常");}else{//將異常數據返回給前端modelAndView.addObject("msg","未知的異常");}//然后跳轉到異常頁面展示modelAndView.setViewName("error.jsp");return modelAndView;} }

@ControllerAdvice注解實現異常分類管理@ExceptionHandler(常用方式)

**注意:**要在核心配置文件中添加==< mvc:annotation-driven/>mvc的注解支持==

兩種異常推薦使用注解,因為注解可以攔截到入參類型轉換異常

注解代碼

package com.fs.springmvc.exception;import com.fs.springmvc.domain.ResultMapper; import com.fs.springmvc.domain.User; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; /* 注解的方式處理異常(常用) @ControllerAdvice 聲明該類是一個Controller的通知類,聲明后該類就會被加載成異常處理器 使用注解異常處理器就可以攔截到入參類型轉換異常 而非注解(實現HandlerExceptionResolver接口)就無法攔截到入參類型轉換異常*/ @Component //使用注解開發異常處理器 //聲明該類是一個Controller的通知類,聲明后該類就會被加載成異常處理器 @ControllerAdvice public class ExceptionAdvice {/*//類中定義的方法攜帶@ExceptionHandler注解的會被作為異常處理器,后面添加實際處理的異常類型@ExceptionHandler(NullPointerException.class)@ResponseBodypublic String doNullException(Exception ex){return "空指針異常";}@ExceptionHandler(ArithmeticException.class)@ResponseBodypublic String doArithmeticException(Exception ex){return "ArithmeticException";}//處理大異常@ExceptionHandler(Exception.class)@ResponseBodypublic String doException(Exception ex){return "all";}*//*一般處理一個大異常就行了*///處理大異常,返回結果集對象,以json返回@ExceptionHandler(Exception.class)@ResponseBodypublic ResultMapper doExceptionTo(Exception ex){//給返回的結果集的數據準備User user = new User();user.setName("小付");user.setAge(18);ResultMapper resultMapper = new ResultMapper(500,false,"服務器繁忙~",user);return resultMapper;}//處理自定義異常,返回結果集對象,以json返回@ExceptionHandler(BusinessException.class)@ResponseBodypublic ResultMapper doExceptionToBusinessException(BusinessException ex){//給返回的結果集的數據準備User user = new User();user.setName("小花");user.setAge(18);ResultMapper resultMapper = new ResultMapper(500,false,ex.getMessage(),user);return resultMapper;} }
ResultMapper對返回的結果進行封裝
package com.fs.springmvc.domain;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;/* 返回的結果對象*/ @Data @NoArgsConstructor @AllArgsConstructor public class ResultMapper<T> {//狀態碼private Integer code;//是否成功private Boolean flag;//返回消息private String message;//返回的數據private T data; }

自定義異常

自定義異常BusinessException

package com.fs.springmvc.exception; //自定義異常繼承RuntimeException,覆蓋父類所有的構造方法 public class BusinessException extends RuntimeException {public BusinessException() {}public BusinessException(String message) {super(message);}public BusinessException(String message, Throwable cause) {super(message, cause);}public BusinessException(Throwable cause) {super(cause);}public BusinessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);} }

controller中一個請求方法模擬異常來測試我們的異常代碼

package com.fs.springmvc.controller;import com.fs.springmvc.domain.User; import com.fs.springmvc.exception.BusinessException; import com.fs.springmvc.exception.SystemException; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import java.util.ArrayList; import java.util.List;@Controller public class UserController {@RequestMapping("/save")@ResponseBodypublic List<User> save(@RequestBody User user) {System.out.println("user controller save is running ...");//拋出自定義的異常throw new BusinessException("請勿連續刷新頁面,謝謝~~");}// @RequestMapping("/save") // @ResponseBody // public List<User> save(@RequestBody User user) { // System.out.println("user controller save is running ...");//模擬業務層發起調用產生了異常 // int i = 1/0; // String str = null; // str.length();//對用戶的非法操作進行判定,并包裝成異常對象進行處理,便于統一管理 // if(user.getName().trim().length() < 8){ // throw new BusinessException("對不起,用戶名長度不滿足要求,請重新輸入!"); // } // if(user.getAge() < 0){ // throw new BusinessException("對不起,年齡必須是0到100之間的數字!"); // } // if(user.getAge() > 100){ // throw new SystemException("服務器連接失敗,請盡快檢查處理!"); // }// User u1 = new User(); // u1.setName("Tom"); // u1.setAge(3); // User u2 = new User(); // u2.setName("Jerry"); // u2.setAge(5); // ArrayList<User> al = new ArrayList<User>(); // al.add(u1); // al.add(u2); // // return al; // } }

總結

以上是生活随笔為你收集整理的SpringMVC自定义拦截器与异常处理(自定义异常)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。