1. 程式人生 > >Spring Boot(二):從Session中獲取域物件的三種方法

Spring Boot(二):從Session中獲取域物件的三種方法

1. 利用@SessionAttribute進行獲取

這是最簡單直接的方法,可以直接在方法的引數中直接進行注入,如下:

//  可以直接從Session中抓取域物件
public Account login(@SessionAttribute Account account) {
    return account;
}

上面的方法雖然簡單,但是唯一的缺點是Spring Framework 4.3之前的版本不支援

2. 利用@SessionAttributes進行獲取

與@SessionAttribute不同的是,@SessionAttributes不僅多了一個複數“s”,而且從Spring Framework 2.5版本就開始支援,此外@SessionAttributes還必須註解在類上,這樣類裡面的所有方法就可以直接通過@ModelAttribute獲取域物件,所以總結起來,@SessionAttributes抓取域物件分為兩步;
1. 在類上添加註解@SessionAttributes;
2. 在方法的引數中通過@ModelAttribute獲取域物件;

@RestController
@SessionAttributes("account")
public class SecurityContextController {

    @RequestMapping("/account")
    public Account login(@ModelAttribute("account") Account account) {
        return account;
    }
}

此外,我們不妨把@SessionAttributes的官方說明重讀一遍,以瞭解它的真正含義,如下:

This will typically list
the names of model attributes which should be transparently stored in the session or some conversational storage, serving as form-backing beans. Declared at the type level, applying to the model attributes that the annotated handler class operates on.

大概意思是@SessionAttributes會列出儲存在Session或會話中的域物件,就像表單的後臺物件一樣提供服務,並且必須註解在型別上,並應用於此類的域物件上。

3. 直接通過Session獲取

這個更簡單,直接通過HttpSession獲取,但需要更多的型別判斷與轉換程式碼,如下:

@RequestMapping("/account")
public Account account(HttpSession session) {
    Object obj = session.getAttribute("account");
    if(obj instanceof Account) {
        Account account = (Account) obj;
        return account;
    }
    return null;
}

為了簡化Session的呼叫,充分利用@ModelAttribute方法的初始化特性,我們還可以改進為如下的形式:

public class SecurityContextController {

    ThreadLocal<Account> authContext = new ThreadLocal<>();

    //  此方法會在每次請求前呼叫(這個類的處理方法)
    @ModelAttribute
    public void initUser(HttpSession session) {
        Object obj = session.getAttribute("account");
        if(obj instanceof Account) {
            Account user = (Account) obj;
            authContext.set(user);
        }
    }

    //  現在可直接使用儲存的屬性
    @RequestMapping("/getUser")
    public AegisUser get() {
        return authContext.get();
    }

}

結論

在Spring Boot中,從Session中獲取域物件還是比較容易的,唯一可能引起誤解或較難使用的只有@SessionAttributes,一定要記住它的二個使用步驟。