Springmvc中的轉(zhuǎn)發(fā)重定向和攔截器的示例
本文介紹了Springmvc中的轉(zhuǎn)發(fā)重定向和攔截器的示例,分享給大家,具體如下:
可變參數(shù)在設(shè)計(jì)方法時(shí),使用 數(shù)據(jù)類(lèi)型...
來(lái)聲明參數(shù)類(lèi)型,例如: public static void function(int... numbers)
在實(shí)現(xiàn)方法體時(shí),可變參數(shù)是作為數(shù)組來(lái)處理
public class Test{ public static void main(String[] args){ System.out.println(Test.sum(1,2,3)); System.out.println(Test.sum(1,2,3,4,54)); } public static int sum(int... numbers){ int sum=0; for(int i=0;i<numbers.length;i++){ sum+=numbers[i]; } return sum; } }
注意:每個(gè)方法中,最多只允許存在1個(gè)可變參數(shù),并且,如果存在 可變參數(shù) ,那么必須是最后一個(gè)參數(shù)
轉(zhuǎn)發(fā)和重定向
在控制器內(nèi)部處理請(qǐng)求的方法中,默認(rèn)返回字符串時(shí)的處理方式是 轉(zhuǎn)發(fā) ,轉(zhuǎn)發(fā)的值是 view 組件的名稱(chēng),比如 return "login" ,實(shí)質(zhì)上會(huì)根據(jù)視圖解析器( ViewResolver )得到最終負(fù)責(zé)顯示的頁(yè)面,而通過(guò) return redirect:路徑 這樣的語(yǔ)法表示重定向,在 redirect: 右側(cè)的內(nèi)容是路徑,這個(gè)路徑通常使用相對(duì)的路徑,是以當(dāng)前客戶(hù)端的地址欄中的路徑為標(biāo)準(zhǔn)進(jìn)行參考,例如當(dāng)前的地址為: http://localhost:8080/Project/user/reg.do ,然后 return "redirect:login.do" ,則會(huì)重定向到 http://localhost:8080/Project/user/login.do ,如果 return "redirect:/main/index.do" 或者 return "redirect:../main/index.do" ,則會(huì)重定向到 http://localhost:8080/Project/main/index.do
forward:
默認(rèn)的方式,但是也是可以使用 return "forward:login"
返回的一定是一個(gè) view ,經(jīng)過(guò)視圖解析器之后會(huì)轉(zhuǎn)發(fā)到指定的視圖
redirect:
重定向 : return "redirect:login.do"
返回的是一個(gè)Controller方法的路徑,而不是一個(gè)view,這個(gè)不會(huì)經(jīng)過(guò)視圖解析器,而是直接跳轉(zhuǎn)
實(shí)例
@RequestMapping(value="/handle_reg.do", method=RequestMethod.POST) public String handleReg(User user,ModelMap map){ try { userService.reg(user); System.out.println("注冊(cè)成功!"); return "redirect:login.do"; //重定向到login.do這個(gè)控制方法,login.do對(duì)應(yīng)的就是轉(zhuǎn)發(fā)到login.jsp } catch (UsernameConflictException e) { System.out.println(e.getMessage()); map.put("errorMessage", e.getMessage()); return "error"; } } @RequestMapping(value="login.do") public String handleLogin(){ return "login"; }
攔截器
基本概念
- 攔截器( interceptor )是springmvc中的一個(gè) 組件 ,是運(yùn)行在 DispatcherServlet 之后,運(yùn)行在 Controller 之前的
- 攔截器可以決定對(duì)某些符合條件的進(jìn)行 攔截 或者 放行 ,所以,通常用于對(duì)一些具有相同運(yùn)行條件的功能進(jìn)行約束
使用攔截器
自定義攔截器類(lèi)
創(chuàng)建一個(gè)攔截類(lèi)( DemoInterceptor ),實(shí)現(xiàn) HandlerInterceptor 接口
public class DemoInterceptorimplements HandlerInterceptor{ /** * 處理器執(zhí)行之前調(diào)用 * @param request HttpServletRequest對(duì)象,可以獲取請(qǐng)求參數(shù)等等 * @param response HttpServletResponse對(duì)象 * @param Handler 攔截器的Controller對(duì)象 * @return 如果返回false,就會(huì)中斷處理流程,不會(huì)處理后續(xù)的攔截器和Controller。如果返回true,則會(huì)執(zhí)行后續(xù)的攔截器和處理器 */ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("DemoInterceptor的PreHandler執(zhí)行"); return true; } /** * 處理器執(zhí)行之后調(diào)用,跳轉(zhuǎn)到指定視圖之前調(diào)用 * @param request HttpServletRequest對(duì)象 * @param response HttpServletResponse對(duì)象 * @param Handler 攔截器的Controller對(duì)象 * @param modelAndView ModelAndView對(duì)象,其中存放的是處理結(jié)果和視圖的信息 */ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { /** * 1. 可以自己設(shè)計(jì)邏輯,例如某些情況下返回false,返回true * 2. 返回true表示執(zhí)行后續(xù)的處理器和攔截器,返回false會(huì)中斷處理流程 */ System.out.println("handler:"+handler); System.out.println("DemoInterceptor的PostHandler執(zhí)行"); //設(shè)置視圖的名稱(chēng),那么執(zhí)行完成之后就會(huì)條跳轉(zhuǎn)到index.jsp頁(yè)面 //modelAndView.setViewName("index"); } /** * 請(qǐng)求處理完成之后調(diào)用 */ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("DemoInterceptor的afterCompletion執(zhí)行"); } }
在springmvc的配置文件中配置
- 配置攔截的路徑: <mvc:mapping path=""/> 可以使用通配符 * 比如: /** 匹配所有的路徑, /user/* 只能匹配 /user 的子路徑
- 配置不攔截的路徑 : <mvc:exclude-mapping path=""/> 可以配置 多個(gè)
- 配置攔截器類(lèi)( bean ) : <bean class="">
配置
必須按照上面的順序配置,否則將會(huì)報(bào)錯(cuò)
<!-- 配置攔截器,其中可以配置多個(gè)攔截器 --> <mvc:interceptors> <mvc:interceptor> <!-- 配置攔截器的攔截路徑,攔截/user下的全部處理器方法映射 比如:http://localhost:8080/Springmvc/user/login.do這個(gè)請(qǐng)求就會(huì)被攔截 --> <mvc:mappingpath="/user/*"/> <!-- 配置不被該攔截器攔截器的controller方法,這個(gè)是可選配置 比如:http://localhost:8080/Springmvc/user/index.do將不會(huì)被攔截器 --> <mvc:exclude-mappingpath="/user/index.do"/> <mvc:exclude-mappingpath="/user/login.do"/> <!-- 配置攔截器的bean,指定的是全類(lèi)名 --> <beanclass="cn.tedu.spring.interceptor.DemoInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
其中實(shí)現(xiàn)的方法
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler)
- 該方法在 controller 處理請(qǐng)求之前執(zhí)行
- 如果返回的 false ,則會(huì)中斷處理流程,不會(huì)執(zhí)行后續(xù)的攔截器和處理器,返回 true 會(huì)執(zhí)行后續(xù)的攔截器和處理器
- 可以自行設(shè)計(jì)邏輯返回 false 或者 true
public void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,ModelAndView modelAndView)
- 處理器執(zhí)行之后,視圖處理之前調(diào)用,此時(shí)可以通過(guò)對(duì) ModelAndView 對(duì)數(shù)據(jù)和視圖進(jìn)行處理
- 當(dāng)然需要 prehandler 方法返回 true 才會(huì)執(zhí)行
public void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)
- 所有的請(qǐng)求處理完畢之后調(diào)用,比如性能監(jiān)控中,我們可以在此記錄結(jié)束時(shí)間和消耗時(shí)間,還可以進(jìn)行一些資源處理
- 當(dāng)然需要 prehandler 方法返回 true 才會(huì)執(zhí)行
演示登錄檢查
- 登錄檢查: 當(dāng)涉及到用戶(hù)信息的修改,查看什么的,必須要驗(yàn)證是否登錄,因此需要設(shè)計(jì)攔截器驗(yàn)證登錄
- 先設(shè)定登錄數(shù)據(jù),即: 在 login.jsp 中添加登錄按鈕,登錄完成之后,需要自己定義一個(gè)標(biāo)記存儲(chǔ)在 session 中,比如 用戶(hù)的id 或者 用戶(hù)的對(duì)象
- 我們使用用戶(hù)的 id 作為標(biāo)記驗(yàn)證是否已經(jīng)的登錄,如果用戶(hù)登錄成功,會(huì)在 session 中添加一個(gè) uid 的屬性
- 用戶(hù)退出登錄使用 session.invalidate(); 清除 session ,并且重定向到 登錄界面
自定義攔截器(LoginInterceptor)
具體流程在 prehandler 方法中寫(xiě)的很清楚
public class LoginInterceptorimplements HandlerInterceptor{ /* * 在處理器執(zhí)行之前調(diào)用(non-Javadoc) * 1. 獲取session * 2. 讀取session中的uid的值 * 如果為null,表示沒(méi)有登錄,那么直接重定向到登錄界面,同時(shí)返回false,不需要執(zhí)行后面的流程了 * 如果不為null,表示已經(jīng)登錄了,那么直接返回true,繼續(xù)執(zhí)行后面的攔截器或者處理器 */ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session=request.getSession(); //獲取session Object uid=session.getAttribute("uid"); //讀取session中的對(duì)象 //如果uid存在,那么即可登錄完成 if (uid!=null) { return true; //返回true,登錄成功就需要執(zhí)行后續(xù)的流程 } response.sendRedirect(request.getContextPath()+"/user/login.do"); //重定向到登錄界面 return false; //返回false,后面的流程也不用執(zhí)行了,直接中斷 } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
springmvc中配置攔截器
由于這里只是跳轉(zhuǎn)到用戶(hù)中心需要驗(yàn)證登錄,那么只是匹配了 user_center.do
<!-- 配置攔截器,其中可以配置多個(gè)攔截器 --> <mvc:interceptors> <mvc:interceptor> <mvc:mappingpath="/user/user_center.do"/> <beanclass="cn.tedu.spring.interceptor.LoginInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
多個(gè)攔截器的執(zhí)行順序
根據(jù)在 springmvc 配置文件中配置的順序執(zhí)行,即是在 <mvc:interceptors> 下配置的攔截器的順序,如果對(duì)同一個(gè)路徑進(jìn)行了攔截器,那么先配置的先攔截
攔截器和過(guò)濾器的區(qū)別(主要的區(qū)別)
- 攔截器是springmvc中,僅僅當(dāng)使用 springmvc 才可以使用攔截器,過(guò)濾器是 Java EE 體系中的,無(wú)論使用哪種框架都可以使用過(guò)濾器
- 攔截器在 DispatcherServlet 之后,在處理器之前執(zhí)行,過(guò)濾器在 DispatcherServlet 之前執(zhí)行
- 過(guò)濾器會(huì)在所有的 servlet 之前執(zhí)行(所有的請(qǐng)求都會(huì)執(zhí)行),而攔截器會(huì)在springmvc中 DispatcherServlet 之后執(zhí)行,所以過(guò)濾器在項(xiàng)目中可以過(guò)濾任何請(qǐng)求(只要是配置了對(duì)應(yīng)的路徑),而攔截器只會(huì)在 DispatcherServlet 處理的請(qǐng)求的基礎(chǔ)之上進(jìn)行攔截
總結(jié)
當(dāng)多種請(qǐng)求都需要做相同或者極為相似的任務(wù)時(shí),可以使用攔截器
開(kāi)發(fā)好攔截器,那么需要在 springmvc 的配置文件中配置
在 <mvc:interceptors> 可以有如果若干個(gè) <mvc:interceptor> ,即是配置若干個(gè)攔截器,配置的多個(gè)攔截器將會(huì)形成 攔截器鏈 ,如果配置多個(gè)攔截器對(duì)同一個(gè)路徑都會(huì)攔截,那么會(huì)按照配置的節(jié)點(diǎn)順序執(zhí)行。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java之jdbc連接mysql數(shù)據(jù)庫(kù)的方法步驟詳解
這篇文章主要介紹了Java之jdbc連接mysql數(shù)據(jù)庫(kù)的方法步驟詳解,JCBC技術(shù)是java開(kāi)發(fā)必備的只是,jdbc連接mysql數(shù)據(jù)庫(kù),這是一個(gè)比較簡(jiǎn)單的方法,有興趣的可以了解一下2020-07-07利用json2POJO with Lombok 插件自動(dòng)生成java類(lèi)的操作
這篇文章主要介紹了利用json2POJO with Lombok 插件自動(dòng)生成java類(lèi)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12java實(shí)現(xiàn)String類(lèi)型和Date類(lèi)型相互轉(zhuǎn)換
很多人表示,java將string類(lèi)型轉(zhuǎn)為date類(lèi)型不知道應(yīng)該怎樣做,本文就來(lái)介紹一下java實(shí)現(xiàn)String類(lèi)型和Date類(lèi)型相互轉(zhuǎn)換,具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10SpringBoot 快速實(shí)現(xiàn) api 加密的方法
在項(xiàng)目中,為了保證數(shù)據(jù)的安全,我們常常會(huì)對(duì)傳遞的數(shù)據(jù)進(jìn)行加密,常用的加密算法包括對(duì)稱(chēng)加密(AES)和非對(duì)稱(chēng)加密(RSA),本文給大家介紹SpringBoot 快速實(shí)現(xiàn) api 加密,感興趣的朋友一起看看吧2023-10-10java判斷用戶(hù)輸入的是否至少含有N位小數(shù)的實(shí)例
下面小編就為大家分享一篇java判斷用戶(hù)輸入的是否至少含有N位小數(shù)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12