Java SpringMVC攔截器與異常處理機(jī)制詳解分析
攔截器(interceptor)的作用
Spring MVC的攔截器類(lèi)似于Servlet開(kāi)發(fā)中的過(guò)濾器Filter,用于對(duì)處理器進(jìn)行預(yù)處理和后處理。
將攔截器按一定的順序聯(lián)結(jié)成一條鏈,這條鏈稱(chēng)為攔截器鏈(Interceptor Chain)。在訪問(wèn)被攔截的方法或字段時(shí),攔截器鏈中的攔截器就會(huì)按其之前定義的順序被調(diào)用。攔截器也是AOP思想的具體實(shí)現(xiàn)。
攔截器和過(guò)濾器區(qū)別

攔截器快速入門(mén)
攔截器快速入門(mén)自定義攔截器很簡(jiǎn)單,只有如下三步:
①創(chuàng)建攔截器類(lèi)實(shí)現(xiàn)Handlerlnterceptor接口
②配置攔截器
③測(cè)試攔截器的攔截效果
①創(chuàng)建攔截器類(lèi)實(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;
}
}
案例:用戶(hù)登錄權(quán)限控制
需求:用戶(hù)沒(méi)有登錄的情況下,不能對(duì)后臺(tái)菜單進(jìn)行訪問(wèn)操作,點(diǎn)擊菜單跳轉(zhuǎn)到登錄頁(yè)面,只有用戶(hù)登錄成功后才能進(jìn)行后臺(tái)功能的操作
public class PrivilegeInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
//邏輯:判斷用戶(hù)是否登錄 本質(zhì):判斷session中有沒(méi)有user
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
if(user==null){
//沒(méi)有登錄
response.sendRedirect(request.getContextPath()+"/login.jsp");
return false;
}
//放行 訪問(wèn)目標(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);
攔截器方法說(shuō)明

SpringMVC異常處理
異常處理的思路
系統(tǒng)中異常包括兩類(lèi)∶預(yù)期異常和運(yùn)行時(shí)異常RuntimeException,前者通過(guò)捕獲異常從而獲取異常信息,后者主要通過(guò)規(guī)范代碼開(kāi)發(fā)、測(cè)試等手段減少運(yùn)行時(shí)異常的發(fā)生。
系統(tǒng)的Dao、Service、Controller出現(xiàn)都通過(guò)throws Exception向上拋出,最后由SpringMVC前端控制器交由異常處理器進(jìn)行異常處理,如下圖:

異常處理兩種方式
1、使用Spring MVC提供的簡(jiǎn)單異常處理器SimpleMappingExceptionResolver
SpringMVC已經(jīng)定義好了該類(lèi)型轉(zhuǎn)換器,在使用時(shí)可以根據(jù)項(xiàng)目情況進(jìn)行相應(yīng)異常與視圖的映射配置

2、實(shí)現(xiàn)Spring的異常處理接口HandlerExceptionResolver自定義自己的異常處理器
①創(chuàng)建異常處理器類(lèi)實(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","類(lèi)轉(zhuǎn)換異常");
}
modelAndView.setViewName("error");
return modelAndView;
}
}
②配置異常處理器
<!--自定義異常處理器-->
<bean class="com.longdi.resolver.MyExceptionResolver"/>
③編寫(xiě)異常頁(yè)面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>通用的錯(cuò)誤提示頁(yè)面</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)文章
SpringBoot項(xiàng)目引入第三方sdk?jar包的解決方案
這篇文章主要介紹了SpringBoot項(xiàng)目引入第三方sdk?jar包,個(gè)人感覺(jué)比較好的解決方案是將 jar上傳到本地的maven倉(cāng)庫(kù),然后通過(guò)pom依賴(lài),引入第三方j(luò)ar包,需要的朋友可以參考下2022-05-05
Fluent Mybatis學(xué)習(xí)之Update語(yǔ)法實(shí)踐
Fluent MyBatis是一個(gè)MyBatis的增強(qiáng)工具,沒(méi)有對(duì)mybatis做任何修改。本篇文章將詳細(xì)介紹對(duì)Fluent Mybatis中的update語(yǔ)法進(jìn)行驗(yàn)證。代碼具有一定價(jià)值,感興趣的小伙伴可以學(xué)習(xí)一下2021-11-11
SpringBoot3各種配置的優(yōu)先級(jí)對(duì)比小結(jié)
SpringBoot3提供了多種配置來(lái)源以滿(mǎn)足不同場(chǎng)景下的需求,本文詳細(xì)介紹了SpringBoot3中的配置優(yōu)先級(jí)對(duì)比小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下2024-12-12
Springboot實(shí)現(xiàn)對(duì)配置文件中的明文密碼加密詳解
我們?cè)赟pringBoot項(xiàng)目當(dāng)中,會(huì)把數(shù)據(jù)庫(kù)的用戶(hù)名密碼等配置直接放在yaml或者properties文件中,這樣維護(hù)數(shù)據(jù)庫(kù)的密碼等敏感信息顯然是有一定風(fēng)險(xiǎn)的。所以本文為大家整理了對(duì)配置文件中的明文密碼加密的方法,希望對(duì)大家有所幫助2023-03-03
Java實(shí)現(xiàn)excel動(dòng)態(tài)列導(dǎo)出的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)excel動(dòng)態(tài)列導(dǎo)出,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03

