SpringMVC核心

請求轉(zhuǎn)發(fā)

forward : 請求
redirect: 重定向
在框架中都是關鍵字,有一個共同的特點,不和視圖解析器一起工作。
語法: setViewName("forward:視圖完整路徑")。
setViewName("redirect:視圖完整路徑") // 框架會把簡單類型數(shù)據(jù)轉(zhuǎn)化為string放到url中。此時用取數(shù)據(jù)要${request.getParameter("")}取數(shù)據(jù)。
并且重定向不能訪問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設計思想,代理處理)
    springmvc采用統(tǒng)一,全局異常處理。
    把controller中的所有異常都集中到一個地方。采用的是aop的思想,把業(yè)務邏輯和異常處理代碼分開,解耦合。
  1. @ExceptionHandler
  2. @ControlerAdvice
  • 處理異常步驟:
  1. 新建maven 項目
  2. 加入依賴
  3. 自定義異常類
  4. 在controller拋出NameException,AgeException
  5. 創(chuàng)建一個普通類, 作用全局異常處理類
    在類上面載入@ControllerAdvice
    在類中定義方法,方法上面加入@ExceptionHandler
  6. 創(chuàng)建處理異常的視圖頁面
  7. springmvc配置文件
    組件掃描器,掃描@Controller注解
    組件掃描器,掃描@ControllerAdvice所在包名
    聲明注解驅(qū)動
//必須讓springmvc知道你在哪
// 聲明組件掃描器

@ControllerAdvice
public class GlobalExceptionHandler {
    // 定義方法, 處理發(fā)生的異常
//    處理異常的方法和控制器方法定義地點一樣
//    @ExceptionHandler(異常的class)標識發(fā)生此異常時用此方法處理
    @ExceptionHandler(value = NameException.class)
    public ModelAndView doNameException(Exception ex){
        // 通過形參獲取異常信息
        // 異常發(fā)生時的處理邏輯
        // 1. 需要把異常記錄下來, 記錄到數(shù)據(jù)庫, 日志文件
//        記錄日志發(fā)生的時間,哪個方法發(fā)生的,異常錯誤內(nèi)容
//        2. 發(fā)送通知,把一場信息通過郵件等等
//        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){
        // 通過形參獲取異常信息
        // 異常發(fā)生時的處理邏輯
        // 1. 需要把異常記錄下來, 記錄到數(shù)據(jù)庫, 日志文件
//        記錄日志發(fā)生的時間,哪個方法發(fā)生的,異常錯誤內(nèi)容
//        2. 發(fā)送通知,把一場信息通過郵件等等
//        3. 給用戶提示
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","年齡不能大于80");
        mv.addObject("ex", ex);
        mv.setViewName("ageError");
        return mv;
    }

    // 處理其他異常  NameException ,age  以外的異常
    // 不加value時, 不是以上兩種時 , 由此方法執(zhí)行
    @ExceptionHandler
    public ModelAndView doOtherException(Exception ex){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","其他異常");
        mv.addObject("ex", ex);
        mv.setViewName("defaultError");
        return mv;
    }
}

攔截器

  • 攔截器是springmvc中的一種,需要實現(xiàn)HandlerInterceptor接口。
  • 攔截器和過濾器類似,功能方向側重點不同,過濾器是用來過濾請求參數(shù),設置編碼集等工作。
    攔截器是攔截用戶請求, 做請求做判斷處理的
  • 攔截器是全局的,可以對多個Controller做攔截
    一個項目中可以有0個或者多個攔截器,他們一起攔截用戶的請求。攔截器常用在:用戶登錄處理,權限檢查,記錄日志。
  • 攔截器的使用步驟:
  1. 定義類實現(xiàn)HandlerInterceptor接口
    實現(xiàn)接口中的三個方法
  2. 在springmvc配置文件中,聲明攔截器,讓框架知道攔截器的存在。
    組件掃描器掃描@Controller注解,聲明攔截器并指定攔截的請求uri地址
  • 攔截器執(zhí)行時間
    在請求處理之前,也就是controller類中的方法執(zhí)行之前先被攔截。
    在控制器方法執(zhí)行之后也會執(zhí)行攔截器
    在請求處理完成后也會執(zhí)行攔截器


  • 攔截器類

// 攔截器類 , 攔截用戶請求。

public class MyHandlerInterceptor implements HandlerInterceptor {
    Long bigtime ;
    Long etime ;
    /**
     * preHandle:預處理方法
     *      整個項目的入口
     *      true,false 表示是否通過
     * Object handler: 被攔截的控制器對象
     * 返回的boolean
     * 特點在: 方法在控制器MyController的dosome之前先執(zhí)行的
     * 在這個方法中可以獲取請求信息,驗證請求是否符合要求。
     */
    @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 : 處理器方法的返回值
     * 特點:
     *   1. 在處理器方法之后執(zhí)行的。
     *   2. 能夠獲取處理器方法的返回值ModelAndView
     *   3. 主要是可以對原來的執(zhí)行結果做二次修正
     *
     */
    @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);
        // 對原來的結果進行調(diào)整
        if(mv != null){
            mv.addObject("mydate", new Date());
            mv.setViewName("other");
        }
    }

    /**
     *
     *  exL程序中發(fā)生的異常
     *
     *  特點:
     *  在請求處理完成后執(zhí)行的,框架中規(guī)定當你的視圖處理完成后,對視圖執(zhí)行了forward
     *  一般做資源回收工作的,程序請求過程中創(chuàng)建了一些對象, 在這里創(chuàng)建了一些對象,在理可以先刪除,把占用的內(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>
<!--            請求攔截的uri地址
                ** : 標識任意字符,多級目錄和目錄中的文件
    -->
            <mvc:mapping path="/**"/>
<!--            聲明攔截器對象-->
            <bean class="com.lz.handler.MyHandlerInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
  • 一個攔截器處理過程


  • 多個攔截器

配置文件中先聲明先執(zhí)行, 框架中保存多個攔截器是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í)行鏈



攔截器和過濾器的區(qū)別

  1. 過濾器是servlet中的對象, 攔截器是框架中的對象。
  2. 過濾器實現(xiàn)Filter接口的對象,攔截器是實現(xiàn)HandlerInterceptor
  3. 過濾器是用來設置request,response參數(shù),屬性的,側重對數(shù)據(jù)過濾的。攔截器是用來驗證請求的,能階段請求。
  4. 過濾器是在攔截器之前先執(zhí)行的。
  5. 過濾器是tomcat撫慰群毆創(chuàng)建的對象。
    攔截器是springmvc容器中創(chuàng)建的對象
  6. 過濾器是一個執(zhí)行時間點, 攔截器三個
  7. 過濾器可以處理jsp,js,html
    過濾器是側重攔截對Controller的對象,如果你的請求不能被DispathcherServlet接受。
  8. 攔截器攔截普通類方法執(zhí)行,過濾器過濾servlet請求響應。

攔截器實現(xiàn)登錄驗證

步驟

  1. 創(chuàng)建maven
  2. 修改web.xml 注冊中央調(diào)度器
  3. 創(chuàng)建jsp發(fā)起請求
  4. 創(chuàng)建controller處理請求
  5. 創(chuàng)建結果show.jsp
  6. 創(chuàng)建login.jsp,模擬登陸(把用戶信息放到session)
    創(chuàng)建jsp,loginout.jsp模擬退出(從session中刪除)
  7. 創(chuàng)建攔截器,從session中獲取用戶登錄數(shù)據(jù),驗證能否訪問系統(tǒng)。
  8. 創(chuàng)建一個驗證的jsp,如果驗證視圖,給出提示
  9. 創(chuàng)建springmvc配置文件
    組件掃描器, 聲明攔截器。

springmvc執(zhí)行流程

  1. 用戶發(fā)起請求
  2. DispatcherServlet 接收請求some.do, 把請求轉(zhuǎn)交給處理器映射器。
  3. 框架把找到的處理器對象放到一個叫處理器對象的處理器執(zhí)行鏈的類保存。
    HandlerExecutionChain: 保存著 處理器對象(controller), 項目中所有攔截器對象
  4. HandlerExecutionChain返回個中央調(diào)度器,中央調(diào)度器把HandlerExecutionChain交給處理器適配器(HandlerAdapter), 處理器適配器執(zhí)行放法,然后返回視圖給中央調(diào)度器
  5. 中央調(diào)度器在將視圖交給視圖解析器(InternalResourceViewResolver),
    實現(xiàn)了ViewResolver接口,
    視圖解析器作用: 組成視圖完整路徑,使用前綴后綴,并創(chuàng)建view對象。返回給中央調(diào)度器
  6. DispatcherServlet把view對象獲取到后,調(diào)用view方法,把model數(shù)據(jù)放大request作用域中,執(zhí)行對象視圖的forward,請求結束。

處理器映射器(應該用RequestMappingHandlerMapping)

作用:處理器映射器: springmvc框架中的一種對象, 框架把實現(xiàn)了HandlerMapping接口的類叫做映射器(多個)。
根據(jù)請求,從springmvc容器對象中獲取處理器對象。

完結。。。。。。。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容