1. 程式人生 > >session.invalidate()無效的原因

session.invalidate()無效的原因

起因

  今天做畢設的時候,寫到了登入模組,同時用到了session來在前端展示使用者名稱,因為用的是Springmvc做為Controller層的框架,所以設計到session的問題,想了想有沒有簡單的方法可以把模型取到的物件直接放入session中,網上查了一下用到了@SessionAttribute註解,這個註解我是直接如下使用的:

@Controller
@RequestMapping("/foodshare")
@SessionAttributes("user")
public class UserController {
..................
//上下省略程式碼
    model.
addAttribute("user", user); .................. }

  這樣在前端使用起來非常方便可以跨頁面取到使用者的值:

${sessionScope.user.name}

問題

  於是也是這個註解惹的鍋,我在寫登出session的方法時怎麼也無效,前端點退出登入按鈕,跳轉到如下的方法中,但是session並沒有被銷燬。。。。。解決了一下午才明白原來是@SessionAttribute的問題,所以你如果和我一樣遇到了session.invalidate()方法無效的時候,看看是不是也是自己用了這個註解導致的呢?

//在Controller層裡對應跳轉的頁面寫了如下方法
session.invalidate()

解決方案

  先來講一下@SessionAttributes原理:
  Springmvc在呼叫處理方法前,在請求執行緒中自動一個隱含的模型物件,呼叫所有在方法級別標註了@ModelAttribute的方法,並將方法返回值新增到隱含模型中,檢視Session中是否存@SessionAttributes(“xxx”)所指定的xxx屬性,如果有,將其新增到隱含模型中,如果隱含模型已經存在xxx屬性,該步驟會覆蓋隱含模型中已有的屬性值。對應標註了@ModelAttribute(“xxx”)方法的入參按如下流程如果隱含模型包含了xxx屬性,將其賦給該入參,再用請求訊息填充該入參物件直接返回,否則如果xxx是會話屬性,即處理類定義出標註了@SessionAttributes(“xxx”),則嘗試從該會話中獲取該屬性,並將其值賦給入參,然後再用請求填充該入參物件,如會話中找不到xxx屬性,則丟擲HttpSessionRequiredException,如果隱含模型不存在xxx屬性,且xxx也不是會話屬性,則建立入參的物件例項,在用請求填充該入參。
  @SessionAttributes引數
  1、names:這是一個字串陣列。裡面應寫需要儲存到session中資料的名稱。
  2、types:根據指定引數的型別,將模型中對應型別的引數儲存到session中。
  3、value:其實和names是一樣的。
  
 

  而要想清除@SessionAttributes,必須使用SessionStatus.setComplete();來清除。注意,它只清除@SessionAttributes的session,不會清除HttpSession的資料。
  
  而要想清除@SessionAttributes,必須使用SessionStatus.setComplete();來清除。注意,它只清除@SessionAttributes的session,不會清除HttpSession的資料。

  而要想清除@SessionAttributes,必須使用SessionStatus.setComplete();來清除。注意,它只清除@SessionAttributes的session,不會清除HttpSession的資料。
  重要的事情說三遍- -!!!看到這裡大家應該知道問題的所在,@SessionAttributes 自動又把user屬性添加回session裡面去了。
  所以我們只需要在登出session的方法中這樣寫即可:

    public String outLogin(HttpSession session,SessionStatus sessionStatus){
        session.removeAttribute("user");//我這裡是先取出httpsession中的user屬性
        session.invalidate();  //然後是讓httpsession失效
        sessionStatus.setComplete();//最後是呼叫sessionStatus方法
        return "index";
    }

參考文章