SpringMVC-03

SpringMVC

1.在SpringMVC中使用Session

當需要向Session中存入數據時,可以使用【ModelMap】對象將數據進行封裝,操作方式與封裝轉發的數據完全相同,例如:

modelMap.addAttribute("username", username);

然後,需要在當前控制器類之前添加@SessionAttributes註解,並且,在註解中顯式的指定ModelMap中封裝的哪些數據是需要存儲在Session中的,例如:

@Controller 
@RequestMapping(value="user")
@SessionAttributes("username")
public class UserController {
    // ...
}

當添加了以上註解後,如果【ModelMap中被存入了名爲【username的數據,該數據就在Session中,而【ModelMap中的其它數據依然只能用於轉發,也就是數據的作用域只在【Request】級別。

關於【@SessionAttributes註解,其屬性的配置可以參考該註解的源代碼:

@AliasFor("names")
String[] value() default {};

@AliasFor("value")
String[] names() default {};

Class<?>[] types() default {};

通過以上源代碼可以看到:【value和【names屬性的作用是完全相同,用於指定【ModelMap中的哪些名稱對應的數據需要存放到【Session】中,可以使用字符串數組表示多個屬性,另外,還可以配置【types屬性用於指定【Session】的數據的數據類型,也可以是數組類型,與配置的【names保持一致即可。

使用這種做法操作Session非常簡單,但是,也存在一系列的問題:
      1.默認情況下,重定向時會把Session中的數據暴露在URL中;
      2.通過ModelMap存放的數據一定會在Request的作用域中,所以,通過這種方式存放到Session中的數據,其實在Request中也是存在的;
      3.通過這種方式存放到Session中的數據,不可以通過Session對象的【invalidate()方法清除!只能通過SessionStatus類的【setComplete()方法進行清除!

更加簡單的操作Session的方式就是直接在處理請求的方法中添加【HttpSession類型的參數,在方法體中直接操作即可。

@RequestMapping("handle_login.do") 
public String handleLogin(String username, String password,
        ModelMap modelMap, HttpSession session) {
    // 日誌
    System.out.println("UserController.handleLogin()");
    System.out.println("\tusername=" + username);
    System.out.println("\tpassword=" + password);

    // 判斷用戶名是否正確
    if ("root".equals(username)) {
        // 是:判斷密碼是否正確
        if ("1234".equals(password)) {
            // 是:登錄成功,將用戶名存入到Session
            // modelMap.addAttribute("username", username);
            session.setAttribute("username", username);
            // 重定向到主頁
            return "redirect:../index.do";
        } else {
            // 否:密碼錯誤
            modelMap.addAttribute("errorMessage", "ModelMap:密碼錯誤");
            return "error";
        }
    } else {
        // 否:用戶名錯誤
        modelMap.addAttribute("errorMessage", "ModelMap:用戶名錯誤");
        return "error";
    }
}

使用這種做法並不存在以上使用@SessionAttributes時的各種問題,操作也非常簡單,缺點就是不易於執行單元測試!

但有時可以忽略這個缺點,甚至“不使用@SessionAttributes”,原因可能是:可以使用專門的測試工具去測試控制器,所以,在控制器中的方法本身是不需要執行單元測試的,甚至在大型項目中根本就不會使用Session,那各種使用方式都是不需要的!

2.在SpringMVC中統一處理異常

   在Java中,異常的繼承體系是:

Throwable
    Error
        OutOfMemoryError
    Exception
        SQLException
        IOEException
            FileNotFoundException
        RuntimeException
            NullPointException
            ClassNotFoundException
            AirthmeticException
            NumberFormatException
            IndexOutOfBoundsException
                ArrayIndexOutOfBoundsException
                StringIndexOutOfBoundsException

       常見異常處理的做法爲捕獲【try...catch】或者聲明拋出【throw/throws】,在實際處理時,如果當前類適合處理該異常,則捕獲,如果不適合,則聲明並向上層拋出,由上層調用者決定是否處理該異常,通常適合處理異常的都是【控制器】,但是異常可能在多個功能中都會出現,在處理不同的請求時,採用相同代碼處理,則會造成代碼冗餘,不便於統一管理,所以在SpringMVC框架中提供了統一處理異常的機制。
       可以在控制器類中添加統一處理異常的方法,關於該方法:
1.使用【public】權限;
2.返回值的意義與處理請求的方法完全相同;
3.方法名稱可以自定義;
4.方法中必須包含異常類型的參數,且參數的類型能包括所有可能需要處理的異常;
5.與處理請求的方法不同,不可以使用【ModelMap】等對象,只能添加【HttpServletRequest】參數;
6.必須添加【@ExceptionHandler】註解,所以,處理i請求的方法可以是:

@ExceptionHandler
public String handleException(Throwable ex, HttpServletRequest request) {
    if (ex instanceof NullPointerException) {
        request.setAttribute("errorMessage", "空指針異常!");
    } else if (ex instanceof ArrayIndexOutOfBoundsException) {
        request.setAttribute("errorMessage", "數據下標越界異常異常!");
    } else {
        request.setAttribute("errorMessage", "未知異常:" + ex.getClass().getName());
    }
    return "error";
}

       一旦添加了該方法,當前類中任何處理請求的方法都不需要處理相關異常,等同於這些方法把異常拋出了,所有拋出的異常將由該方法統一處理,需要注意的是,該方法只能處理該控制器出現的異常,其他控制器類拋出的異常不做處理。所以可以把該處理異常的方法放在所有控制器類公共的父類中,如【BaseController】!

關於@ExceptionHandler的源代碼:

public @interface ExceptionHandler {

    /**
     * Exceptions handled by the annotated method. If empty, will default to any
     * exceptions listed in the method argument list.
     */
    Class<? extends Throwable>[] value() default {};

}

       該註解可以指定需要被處理的異常的種類,允許定義多個異常處理方法,單獨處理同一類型異常,其參數可以是數組,即同時指定多種異常都將被該方法進行處理!

SpringMVC重點內容:

  1. 理解SpringMVC執行核心流程;
  2. 掌握獲取請求參數的方式;
  3. 理解轉發與重定向;
  4. 瞭解轉發時如何轉發數據;
  5. 掌握@RequestMapping、@RequestParam註解的使用;
  6. 掌握攔截器的使用;
  7. 掌握處理異常的使用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章