請(qǐng)求轉(zhuǎn)發(fā)
forward
: 請(qǐng)求
redirect
: 重定向
在框架中都是關(guān)鍵字寞宫,有一個(gè)共同的特點(diǎn)幔睬,不和視圖解析器一起工作背亥。
語(yǔ)法: setViewName("forward:視圖完整路徑")般眉。
setViewName("redirect:視圖完整路徑") // 框架會(huì)把簡(jiǎn)單類型數(shù)據(jù)轉(zhuǎn)化為string放到url中我纪。此時(shí)用取數(shù)據(jù)要${request.getParameter("")}取數(shù)據(jù)慎宾。
并且重定向不能訪問(wèn)WEB-INF下的資源
mv.addObject("msg", "data");
@RequestMapping(value = "/forward.do", method = RequestMethod.POST)
public ModelAndView doForward(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("msg", "hhhhhhhhhh");
modelAndView.setViewName("forward:/WEB-INF/view/show.jsp");
return modelAndView;
}
異常處理
- 集中異常處理(aop設(shè)計(jì)思想,代理處理)
springmvc采用統(tǒng)一浅悉,全局異常處理趟据。
把controller中的所有異常都集中到一個(gè)地方。采用的是aop的思想术健,把業(yè)務(wù)邏輯和異常處理代碼分開(kāi)汹碱,解耦合。
- @ExceptionHandler
- @ControlerAdvice
- 處理異常步驟:
- 新建maven 項(xiàng)目
- 加入依賴
- 自定義異常類
- 在controller拋出NameException荞估,AgeException
- 創(chuàng)建一個(gè)普通類咳促, 作用全局異常處理類
在類上面載入@ControllerAdvice
在類中定義方法稚新,方法上面加入@ExceptionHandler- 創(chuàng)建處理異常的視圖頁(yè)面
- springmvc配置文件
組件掃描器,掃描@Controller注解
組件掃描器跪腹,掃描@ControllerAdvice所在包名
聲明注解驅(qū)動(dòng)
//必須讓springmvc知道你在哪
// 聲明組件掃描器
@ControllerAdvice
public class GlobalExceptionHandler {
// 定義方法褂删, 處理發(fā)生的異常
// 處理異常的方法和控制器方法定義地點(diǎn)一樣
// @ExceptionHandler(異常的class)標(biāo)識(shí)發(fā)生此異常時(shí)用此方法處理
@ExceptionHandler(value = NameException.class)
public ModelAndView doNameException(Exception ex){
// 通過(guò)形參獲取異常信息
// 異常發(fā)生時(shí)的處理邏輯
// 1. 需要把異常記錄下來(lái), 記錄到數(shù)據(jù)庫(kù)尺迂, 日志文件
// 記錄日志發(fā)生的時(shí)間笤妙,哪個(gè)方法發(fā)生的冒掌,異常錯(cuò)誤內(nèi)容
// 2. 發(fā)送通知噪裕,把一場(chǎng)信息通過(guò)郵件等等
// 3. 給用戶提示
ModelAndView mv = new ModelAndView();
mv.addObject("msg","姓名必須是zs");
mv.addObject("ex", ex);
mv.setViewName("nameError");
return mv;
}
@ExceptionHandler(value = AgeException.class)
public ModelAndView doAgeException(Exception ex){
// 通過(guò)形參獲取異常信息
// 異常發(fā)生時(shí)的處理邏輯
// 1. 需要把異常記錄下來(lái), 記錄到數(shù)據(jù)庫(kù)股毫, 日志文件
// 記錄日志發(fā)生的時(shí)間膳音,哪個(gè)方法發(fā)生的,異常錯(cuò)誤內(nèi)容
// 2. 發(fā)送通知铃诬,把一場(chǎng)信息通過(guò)郵件等等
// 3. 給用戶提示
ModelAndView mv = new ModelAndView();
mv.addObject("msg","年齡不能大于80");
mv.addObject("ex", ex);
mv.setViewName("ageError");
return mv;
}
// 處理其他異常 NameException 祭陷,age 以外的異常
// 不加value時(shí), 不是以上兩種時(shí) 趣席, 由此方法執(zhí)行
@ExceptionHandler
public ModelAndView doOtherException(Exception ex){
ModelAndView mv = new ModelAndView();
mv.addObject("msg","其他異常");
mv.addObject("ex", ex);
mv.setViewName("defaultError");
return mv;
}
}
攔截器
- 攔截器是springmvc中的一種兵志,需要實(shí)現(xiàn)HandlerInterceptor接口。
- 攔截器和過(guò)濾器類似宣肚,功能方向側(cè)重點(diǎn)不同想罕,過(guò)濾器是用來(lái)過(guò)濾請(qǐng)求參數(shù),設(shè)置編碼集等工作霉涨。
攔截器是攔截用戶請(qǐng)求按价, 做請(qǐng)求做判斷處理的 - 攔截器是全局的,可以對(duì)多個(gè)Controller做攔截
一個(gè)項(xiàng)目中可以有0個(gè)或者多個(gè)攔截器笙瑟,他們一起攔截用戶的請(qǐng)求楼镐。攔截器常用在:用戶登錄處理,權(quán)限檢查往枷,記錄日志框产。 - 攔截器的使用步驟:
- 定義類實(shí)現(xiàn)HandlerInterceptor接口
實(shí)現(xiàn)接口中的三個(gè)方法- 在springmvc配置文件中,聲明攔截器错洁,讓框架知道攔截器的存在秉宿。
組件掃描器掃描@Controller注解,聲明攔截器并指定攔截的請(qǐng)求uri地址
-
攔截器執(zhí)行時(shí)間
在請(qǐng)求處理之前墓臭,也就是controller類中的方法執(zhí)行之前先被攔截蘸鲸。
在控制器方法執(zhí)行之后也會(huì)執(zhí)行攔截器
在請(qǐng)求處理完成后也會(huì)執(zhí)行攔截器
- 攔截器類
// 攔截器類 , 攔截用戶請(qǐng)求窿锉。
public class MyHandlerInterceptor implements HandlerInterceptor {
Long bigtime ;
Long etime ;
/**
* preHandle:預(yù)處理方法
* 整個(gè)項(xiàng)目的入口
* true酌摇,false 表示是否通過(guò)
* Object handler: 被攔截的控制器對(duì)象
* 返回的boolean
* 特點(diǎn)在: 方法在控制器MyController的dosome之前先執(zhí)行的
* 在這個(gè)方法中可以獲取請(qǐng)求信息膝舅,驗(yàn)證請(qǐng)求是否符合要求。
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
bigtime = System.currentTimeMillis();
System.out.println("先處理方法");
// request.getRequestDispatcher("/tips.jsp").forward(request,response);
return true;
}
/**
* modelAndView : 處理器方法的返回值
* 特點(diǎn):
* 1. 在處理器方法之后執(zhí)行的窑多。
* 2. 能夠獲取處理器方法的返回值ModelAndView
* 3. 主要是可以對(duì)原來(lái)的執(zhí)行結(jié)果做二次修正
*
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mv) throws Exception {
etime = System.currentTimeMillis();
System.out.println("postHandler");
System.out.println(etime - bigtime);
// 對(duì)原來(lái)的結(jié)果進(jìn)行調(diào)整
if(mv != null){
mv.addObject("mydate", new Date());
mv.setViewName("other");
}
}
/**
*
* exL程序中發(fā)生的異常
*
* 特點(diǎn):
* 在請(qǐng)求處理完成后執(zhí)行的仍稀,框架中規(guī)定當(dāng)你的視圖處理完成后,對(duì)視圖執(zhí)行了forward
* 一般做資源回收工作的埂息,程序請(qǐng)求過(guò)程中創(chuàng)建了一些對(duì)象技潘, 在這里創(chuàng)建了一些對(duì)象,在理可以先刪除千康,把占用的內(nèi)存回收
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("after");
}
}
- springmvc配置文件
<mvc:interceptors>
<mvc:interceptor>
<!-- 請(qǐng)求攔截的uri地址
** : 標(biāo)識(shí)任意字符享幽,多級(jí)目錄和目錄中的文件
-->
<mvc:mapping path="/**"/>
<!-- 聲明攔截器對(duì)象-->
<bean class="com.lz.handler.MyHandlerInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
-
一個(gè)攔截器處理過(guò)程
- 多個(gè)攔截器
配置文件中先聲明先執(zhí)行, 框架中保存多個(gè)攔截器是ArrayList拾弃, 按照聲明順序放入ArrayList中
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.lz.handler.MyHandlerInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.lz.handler.MyHandlerInter2"/>
</mvc:interceptor>
</mvc:interceptors>
執(zhí)行順序 preHandler1 --> preHandler2 ---> controller犯法---> postHandler2 --- > postHandler1 ----> after2 ----> after1
-
攔截器執(zhí)行鏈
攔截器和過(guò)濾器的區(qū)別
- 過(guò)濾器是servlet中的對(duì)象值桩, 攔截器是框架中的對(duì)象。
- 過(guò)濾器實(shí)現(xiàn)Filter接口的對(duì)象豪椿,攔截器是實(shí)現(xiàn)HandlerInterceptor
- 過(guò)濾器是用來(lái)設(shè)置request奔坟,response參數(shù),屬性的搭盾,側(cè)重對(duì)數(shù)據(jù)過(guò)濾的咳秉。攔截器是用來(lái)驗(yàn)證請(qǐng)求的,能階段請(qǐng)求鸯隅。
- 過(guò)濾器是在攔截器之前先執(zhí)行的澜建。
- 過(guò)濾器是tomcat撫慰群毆?jiǎng)?chuàng)建的對(duì)象。
攔截器是springmvc容器中創(chuàng)建的對(duì)象- 過(guò)濾器是一個(gè)執(zhí)行時(shí)間點(diǎn)滋迈, 攔截器三個(gè)
- 過(guò)濾器可以處理jsp霎奢,js,html
過(guò)濾器是側(cè)重?cái)r截對(duì)Controller的對(duì)象饼灿,如果你的請(qǐng)求不能被DispathcherServlet接受幕侠。- 攔截器攔截普通類方法執(zhí)行,過(guò)濾器過(guò)濾servlet請(qǐng)求響應(yīng)碍彭。
攔截器實(shí)現(xiàn)登錄驗(yàn)證
步驟
- 創(chuàng)建maven
- 修改web.xml 注冊(cè)中央調(diào)度器
- 創(chuàng)建jsp發(fā)起請(qǐng)求
- 創(chuàng)建controller處理請(qǐng)求
- 創(chuàng)建結(jié)果show.jsp
- 創(chuàng)建login.jsp,模擬登陸(把用戶信息放到session)
創(chuàng)建jsp晤硕,loginout.jsp模擬退出(從session中刪除) - 創(chuàng)建攔截器,從session中獲取用戶登錄數(shù)據(jù)庇忌,驗(yàn)證能否訪問(wèn)系統(tǒng)舞箍。
- 創(chuàng)建一個(gè)驗(yàn)證的jsp,如果驗(yàn)證視圖皆疹,給出提示
- 創(chuàng)建springmvc配置文件
組件掃描器疏橄, 聲明攔截器。
springmvc執(zhí)行流程
- 用戶發(fā)起請(qǐng)求
- DispatcherServlet 接收請(qǐng)求some.do, 把請(qǐng)求轉(zhuǎn)交給處理器映射器捎迫。
- 框架把找到的處理器對(duì)象放到一個(gè)叫處理器對(duì)象的處理器執(zhí)行鏈的類保存晃酒。
HandlerExecutionChain: 保存著 處理器對(duì)象(controller), 項(xiàng)目中所有攔截器對(duì)象 - HandlerExecutionChain返回個(gè)中央調(diào)度器窄绒,中央調(diào)度器把HandlerExecutionChain交給處理器適配器(HandlerAdapter)贝次, 處理器適配器執(zhí)行放法,然后返回視圖給中央調(diào)度器
- 中央調(diào)度器在將視圖交給視圖解析器(InternalResourceViewResolver)彰导,
實(shí)現(xiàn)了ViewResolver接口蛔翅,
視圖解析器作用: 組成視圖完整路徑,使用前綴后綴位谋,并創(chuàng)建view對(duì)象山析。返回給中央調(diào)度器 - DispatcherServlet把view對(duì)象獲取到后,調(diào)用view方法倔幼,把model數(shù)據(jù)放大request作用域中盖腿,執(zhí)行對(duì)象視圖的forward,請(qǐng)求結(jié)束损同。
處理器映射器(應(yīng)該用RequestMappingHandlerMapping)
作用:處理器映射器: springmvc框架中的一種對(duì)象, 框架把實(shí)現(xiàn)了HandlerMapping接口的類叫做映射器(多個(gè))鸟款。
根據(jù)請(qǐng)求膏燃,從springmvc容器對(duì)象中獲取處理器對(duì)象。
完結(jié)何什。组哩。。处渣。伶贰。。罐栈。