攔截器
攔截器的操作是基于aop的
攔截器的定義:
定義攔截器實(shí)現(xiàn)HandlerInteceptor接口,接口中三個(gè)方法:
preHandle:
進(jìn)入Handler方法之前執(zhí)行
用于身份認(rèn)證和身份授權(quán),登錄認(rèn)證和權(quán)限校驗(yàn)
比如身份認(rèn)證嗤练,如果認(rèn)證不通過饵骨,表示當(dāng)前用戶沒有登錄,需要此方法攔截不再向下執(zhí)行
return false表示攔截住,不往下執(zhí)行
postHandle
進(jìn)入Handler方法之后湿诊,返回ModelAndView之前返回
應(yīng)用場景:
從ModelAndView出發(fā),將公用的模型數(shù)據(jù)(比如菜單導(dǎo)航)在這里傳到視圖瘦材,也可以在這里統(tǒng)一指定視圖
afterCompletion
執(zhí)行Handler完成之后執(zhí)行此方法
統(tǒng)一的異常處理
統(tǒng)一的日志處理
攔截器的配置:
SpringMVC的攔截器是針對HandlerMapping進(jìn)行攔截設(shè)置
如果在某個(gè)HandlerMapping中配置攔截器厅须,經(jīng)過該HandlerMapping攔截成功的Handler最終才使用該攔截器
SpringMVC可以配置類似全局的攔截器,SpringMVC將配置的類似的全局的攔截器注入到每個(gè)HandlerMapping中
攔截器的全局配置:
<mvc:inteceptors>可以設(shè)置多個(gè)攔截器食棕,順序執(zhí)行朗和,/**攔截所有的url和所有的子url路徑
攔截器的編寫:
測試需求:
測試多個(gè)攔截器各個(gè)方法的執(zhí)行時(shí)機(jī)
攔截器的放行:
在第一個(gè)方法中設(shè)置return true
總結(jié):
1、當(dāng)兩個(gè)攔截器都放行的時(shí)候簿晓,preHandle方法順序執(zhí)行眶拉,postHandle、afterCompletion逆向執(zhí)行
2憔儿、攔截器1放行忆植,攔截器2的preHandle方法才會執(zhí)行,攔截器2的preHandler不放行谒臼,攔截器2的剩下的方法不執(zhí)行
3朝刊、只要有一個(gè)攔截器不放行,post方法就都不會執(zhí)行
兩個(gè)攔截器均不放行:
只執(zhí)行第一個(gè)攔截器的preHandle方法蜈缤,剩下的所有的都不執(zhí)行
小結(jié):
根據(jù)測試結(jié)果對攔截器進(jìn)行應(yīng)用拾氓,比如統(tǒng)一的日志處理,需要該攔截器的preHandle方法一定要放行底哥,并且要放在攔截器鏈的第一個(gè)位置
登錄認(rèn)證的攔截器咙鞍,放在攔截器鏈的第一個(gè)位置,權(quán)限校驗(yàn)攔截器叠艳,需要放在登錄認(rèn)證攔截器之后(因?yàn)榈卿浲ㄟ^后才校驗(yàn)權(quán)限)
攔截器的應(yīng)用:
登錄認(rèn)證的攔截器:
需求:
1奶陈、用戶請求url
2易阳、攔截器進(jìn)行攔截校驗(yàn):
如果請求的url是公開地址(無需登錄附较,即可訪問的地址),放行
如果用戶session不存在潦俺,跳轉(zhuǎn)到登錄頁面
如果用戶session存在拒课,那么放行,繼續(xù)操作
登錄的controller方法:
設(shè)置輸入用戶名和密碼登錄事示,在形參里面定義session形參
在session中保存用戶身份信息:
session.setAttribute("arg0",arg1);
重定向到其他的頁面
退出的controller方法:
退出清除session即可:
session.invalidate();
登錄攔截器的實(shí)現(xiàn):
//獲取請求的url
String url = request.getRequestURI();
//判斷url是否是公開地址(實(shí)際使用時(shí)將公開地址配置到配置文件中)
//這里的公開地址是登錄提交的地址
if(url.indexOf("login.action")>=0){
//如果要進(jìn)行登錄提交早像,放行
return true;
}
//判斷session
HttpSession session = request.getSession();
String username = (String)session.getAttribute("username");
//判斷身份信息
//身份信息存在,放行
if(username!=null){
return true;
}
//如果執(zhí)行到這里肖爵,表示用戶身份需要認(rèn)證
//跳轉(zhuǎn)到登錄界面
request.getRequestDisptcher("").forword(request,response);