springmvc-學習筆記(3)

異常處理思路
系統的dao、service、controller出現異常都通過throws Exception向上拋出,最後由springmvc的前端控制器交由異常處理器進行異常處理

自定義異常類
對不同的異常類型定義不同的異常類,每種異常都要定義異常類

public class CustomException extends Exception {

    //異常信息
    private String message;

    public CustomException(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

全局異常處理器
處理思路:如果該異常是系統自定義異常,直接取出異常信息,在錯誤頁面顯示,如果該異常類型不是系統自定義異常,構造一個系統自定義異常類型(信息爲”未知錯誤”)

springnvc提供了一個HandlerExceptionResolver接口:

public class CustomExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception exception) {
        //handler就是處理器適配器要執行的handler對象(只有method)
        //exception 系統拋出的異常

        //解析異常類型,如果是系統自定義異常,取出錯誤信息在頁面顯示
        /*String message = null;
        if(exception instanceof CustomException ) {
            message = ((CustomException)exception).getMessage();
        }
        else {
            //如果不是系統自定義異常,構建一個自定義的異常類型
            message = "未知錯誤";
        }*/

        CustomException customException = null;
        if(exception instanceof CustomException) {
            customException = (CustomException)exception;
        }
        else{
            customException = new CustomException("未知錯誤");
        }
        String message = customException.getMessage();

        ModelAndView modelAndView= new ModelAndView();
        modelAndView.addObject("message", message);
        modelAndView.setViewName("items/error");

        return modelAndView;
    }
}

全局異常處理器配置:

<!-- 只要實現了HandlerExceptionResolver接口就是全局異常處理器 -->
    <bean class="springmvc.exception.CustomExceptionResolver"></bean>

如果與業務處理功能相關的異常建議在service層拋出,與業務功能沒有關係的異常建議在Controller中拋出

pringnvc中對多部件類型的解析
在頁面form中提交enctype=”multipart/form-data”的數據時,需要springmvc對這種類型的數據進行解析。
需要在springmvc.xml中配置multipart解析器:

<!-- 文件上傳 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 設置上傳文件最大尺寸爲5MB -->
        <property name="maxUploadSize" value="5242880"></property>
    </bean>

Controller類:

@RequestMapping("/pic.action")
    public String ediItemsSubmit(Model model, MultipartFile pic) throws IllegalStateException, IOException {

        if(pic != null) {
            //存儲的物理路徑
            String path = "F:\\tomcat\\apache-tomcat-8.0.33\\webapps\\springmvc\\image\\";
            //圖片的原始名稱
            String fileName = pic.getOriginalFilename();
            System.out.println(fileName);

            //生成新的圖片名稱,避免文件衝突
            String newFileName = UUID.randomUUID() + fileName.substring(fileName.lastIndexOf("."));
            File newFile = new File(path + newFileName);

            pic.transferTo(newFile);
            model.addAttribute("image", newFileName);
        }
        return "items/images";

    }

注意:1.multipart解析器依賴於 commons-fileupload和commons-io這兩個jar包
2.文件上傳頁面中 :

 <form id="Items" enctype="multipart/form-data" method="post" action="/springmvc/pic.action">
        <input type="file" name="pic" /> 
        <input type="submit" name="提交">
      </form>

input標籤文件上傳(type=”file”)的name需要與Controller類形參MutipartFile的名稱一致,即都爲pic,文件才能傳入Controller類

攔截器
處理攔截器類似於Servlet的中的過濾器,用於對處理器進行預處理和後處理
spring攔截器針對HandlerMapping進行攔截設置,如果在某個HandlerMapping中配置攔截,經過該HandlerMapping映射成功的handler最終使用該攔截器。

springmvc配置類似全局的攔截器,springmvc框架將配置的類似全局的攔截器注入到每個handlerMapping中。

HandlerInterceptor類:

public class HandlerInterceptor1 implements HandlerInterceptor {

    @Override
    //執行handler方法之後
    //可以使用同一的異常處理,日誌處理
    public void afterCompletion(HttpServletRequest arg0,
            HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        System.out.println("1..afterCompletion");

    }

    @Override
    //進入handler方法之後返回ModelAndView之前
    //應用場景從modelAndView出發,將公用的模型數據(如菜單導航)在這裏傳到視圖,也可以在這裏統一指定視圖
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2, ModelAndView arg3) throws Exception {
        System.out.println("1..postHandle");

    }

    @Override
    //進入handler方法之前
    //可用於身份驗證、身份授權
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2) throws Exception {

        System.out.println("1.。preHandle");
        //true表示放行,false表示攔截
        return true;
    }
}

配置:

<!-- 攔截器  -->
    <mvc:interceptors>
        <!-- 多個攔截器,順序執行 -->
        <mvc:interceptor>
            <!-- /**表示所有url包括子路徑
            /*表示包含所有的跟路徑 -->
            <mvc:mapping path="/**"/>
            <bean class="springmvc.interceptor.HandlerInterceptor1"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

preHandle方法按攔截器的順序執行,postHandle和afterCompletion方法按攔截器的逆序執行,所以日誌處理的攔截器一般放在首位。

攔截器1放行了攔截器2纔會放行,只要有一個攔截器不放行,postHandle方法不會執行。

發佈了69 篇原創文章 · 獲贊 20 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章