Java SpringMVC攔截器與異常處理機(jī)制詳解分析
攔截器(interceptor)的作用
Spring MVC的攔截器類似于Servlet開發(fā)中的過濾器Filter,用于對(duì)處理器進(jìn)行預(yù)處理和后處理。
將攔截器按一定的順序聯(lián)結(jié)成一條鏈,這條鏈稱為攔截器鏈(Interceptor Chain)。在訪問被攔截的方法或字段時(shí),攔截器鏈中的攔截器就會(huì)按其之前定義的順序被調(diào)用。攔截器也是AOP思想的具體實(shí)現(xiàn)。
攔截器和過濾器區(qū)別
攔截器快速入門
攔截器快速入門自定義攔截器很簡(jiǎn)單,只有如下三步:
①創(chuàng)建攔截器類實(shí)現(xiàn)Handlerlnterceptor接口
②配置攔截器
③測(cè)試攔截器的攔截效果
①創(chuàng)建攔截器類實(shí)現(xiàn)Handlerlnterceptor接口
public class MyInterceptor1 implements HandlerInterceptor { //在目標(biāo)方法執(zhí)行之前 執(zhí)行 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException { System.out.println("preHandle....."); String param = request.getParameter("param"); if("yes".equals(param)){ return true; }else{ request.getRequestDispatcher("/error.jsp").forward(request,response); return false;//返回true代表放行 返回false代表不放行 } } //在目標(biāo)方法執(zhí)行之后 視圖對(duì)象返回之前執(zhí)行 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { modelAndView.addObject("name","itheima"); System.out.println("postHandle..."); } //在流程都執(zhí)行完畢后 執(zhí)行 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { System.out.println("afterCompletion...."); } }
②配置攔截器
<mvc:interceptors> <mvc:interceptor> <!--對(duì)哪些資源執(zhí)行攔截操作--> <mvc:mapping path="/**"/> <bean class="com.longdi.interceptor.MyInterceptor1"/> </mvc:interceptor> </mvc:interceptors>
③測(cè)試攔截器的攔截效果
@Controller public class TargetController { @RequestMapping("/target") public ModelAndView show(){ System.out.println("目標(biāo)資源執(zhí)行......"); ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("name","itcast"); modelAndView.setViewName("index"); return modelAndView; } }
案例:用戶登錄權(quán)限控制
需求:用戶沒有登錄的情況下,不能對(duì)后臺(tái)菜單進(jìn)行訪問操作,點(diǎn)擊菜單跳轉(zhuǎn)到登錄頁面,只有用戶登錄成功后才能進(jìn)行后臺(tái)功能的操作
public class PrivilegeInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { //邏輯:判斷用戶是否登錄 本質(zhì):判斷session中有沒有user HttpSession session = request.getSession(); User user = (User) session.getAttribute("user"); if(user==null){ //沒有登錄 response.sendRedirect(request.getContextPath()+"/login.jsp"); return false; } //放行 訪問目標(biāo)資源 return true; } }
spring-mvc.xml:
<mvc:interceptors> <mvc:interceptor> <!--配置對(duì)哪些資源執(zhí)行攔截操作--> <mvc:mapping path="/**"/> <!--配置哪些資源排除攔截操作--> <mvc:exclude-mapping path="/user/login"/> <bean class="com.longdi.interceptor.PrivilegeInterceptor"/> </mvc:interceptor> </mvc:interceptors>
UserServiceImpl
public User login(String username, String password) { try { User user = userDao.findByUsernameAndPassword(username,password); return user; }catch (EmptyResultDataAccessException e){ return null; } }
UserService
User login(String username, String password);
UserDaoImpl
public User findByUsernameAndPassword(String username, String password) throws EmptyResultDataAccessException { User user = jdbcTemplate.queryForObject("select * from sys_user where username=? and password=?", new BeanPropertyRowMapper<User>(User.class), username, password); return user; }
UserDao
User findByUsernameAndPassword(String username, String password);
攔截器方法說明
SpringMVC異常處理
異常處理的思路
系統(tǒng)中異常包括兩類∶預(yù)期異常和運(yùn)行時(shí)異常RuntimeException,前者通過捕獲異常從而獲取異常信息,后者主要通過規(guī)范代碼開發(fā)、測(cè)試等手段減少運(yùn)行時(shí)異常的發(fā)生。
系統(tǒng)的Dao、Service、Controller出現(xiàn)都通過throws Exception向上拋出,最后由SpringMVC前端控制器交由異常處理器進(jìn)行異常處理,如下圖:
異常處理兩種方式
1、使用Spring MVC提供的簡(jiǎn)單異常處理器SimpleMappingExceptionResolver
SpringMVC已經(jīng)定義好了該類型轉(zhuǎn)換器,在使用時(shí)可以根據(jù)項(xiàng)目情況進(jìn)行相應(yīng)異常與視圖的映射配置
2、實(shí)現(xiàn)Spring的異常處理接口HandlerExceptionResolver自定義自己的異常處理器
①創(chuàng)建異常處理器類實(shí)現(xiàn)HandlerExceptionResolver
public class MyExceptionResolver implements HandlerExceptionResolver { /* 參數(shù)Exception:異常對(duì)象 返回值ModelAndView:跳轉(zhuǎn)到錯(cuò)誤視圖信息 */ public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { ModelAndView modelAndView = new ModelAndView(); if(e instanceof MyException){ modelAndView.addObject("info","自定義異常"); }else if(e instanceof ClassCastException){ modelAndView.addObject("info","類轉(zhuǎn)換異常"); } modelAndView.setViewName("error"); return modelAndView; } }
②配置異常處理器
<!--自定義異常處理器--> <bean class="com.longdi.resolver.MyExceptionResolver"/>
③編寫異常頁面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>通用的錯(cuò)誤提示頁面</h1> <h1>${info}</h1> </body> </html>
④測(cè)試異常跳轉(zhuǎn)
到此這篇關(guān)于Java SpringMVC攔截器與異常處理機(jī)制詳解分析的文章就介紹到這了,更多相關(guān)Java SpringMVC內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java判斷對(duì)象是否為空(包括null ,"")的方法
這篇文章主要介紹了Java判斷對(duì)象是否為空(包括null ,"")的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05mybatis?foreach傳兩個(gè)參數(shù)批量刪除
這篇文章主要介紹了mybatis?foreach?批量刪除傳兩個(gè)參數(shù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04Java中使用While語句自增運(yùn)算遍歷數(shù)組典型實(shí)例
這篇文章主要介紹了Java中使用While語句自增運(yùn)算遍歷數(shù)組典型實(shí)例,本文直接給出實(shí)例代碼,并對(duì)每一句代碼都注解了詳細(xì)注釋,需要的朋友可以參考下2015-06-06Java網(wǎng)絡(luò)編程基礎(chǔ)用法詳解
網(wǎng)絡(luò)編程是指編寫運(yùn)行在多個(gè)設(shè)備(計(jì)算機(jī))的程序,這些設(shè)備都通過網(wǎng)絡(luò)連接起來,本文將帶大家詳細(xì)了解Java的網(wǎng)絡(luò)編程,文中有相關(guān)的代碼示例,需要的朋友可以參考下2023-05-05解決Spring Data Jpa 實(shí)體類自動(dòng)創(chuàng)建數(shù)據(jù)庫表失敗問題
這篇文章主要介紹了解決Spring Data Jpa 實(shí)體類自動(dòng)創(chuàng)建數(shù)據(jù)庫表失敗問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09Java計(jì)算Date類時(shí)間差實(shí)例代碼演示
最近工作中遇到需要計(jì)算時(shí)間差,這里給大家總結(jié)下,下面這篇文章主要給大家介紹了關(guān)于Java計(jì)算Date類時(shí)間差的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12