天天看點

ssh2+注解+filter+cookie實作自動登入功能。

把這些内容記錄下來,以後可以拿過來就用。

我做的這個功能是在登入時點選自動登入的checkbox,當登入成功能後會在本地生成一個cookie記錄使用者資料,以便下次使用者不用再次登入。

項目整體的架構才用的是ssh2,這裡我還用到了filter,每一個網頁請求都會被filter攔截到,這樣在filter中把cookie從本地取出,然後把取出的使用者資料和資料庫驗證傳回結果,如果驗證成功,将使用者資料儲存到seession中,如果沒有驗證成功就執行chain.doFilter(request, response);往下繼續執行。

還有很多實作的filter方法,spring security這個架構很好的實作了對使用者登入權限的管理。但我唯一隻用到了filter實作成功了,以後在研究其他的吧。

首先,加入filter的話就要在web.xml中配置filter。

<filter>
		<filter-name>MySpringFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class><!--這是一個代理filter的類-->
		<init-param>
			<param-name>targetBeanName</param-name>
			<param-value>cookieLoginFilter</param-value><!--代理類代理了filter之後會通過<span style="font-family: Arial, Helvetica, sans-serif;">cookieLoginFilter去spring中找到對應的bean</span>-->
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>MySpringFilter</filter-name>
		<url-pattern>*.jsp</url-pattern>
<p>	</filter-mapping></p>
           

這裡要講一下,web.xml中為什麼filter的資訊要這麼配置呢,這樣配置是為了讓spring來管理這個filter,這樣filter在執行時service也被spring注入了,如果不用spring管理的話,當filter執行時spring管理的bean像service啊,sessionFactory啊都沒有被注入,這樣就無法通路資料庫來驗證使用者。 這裡要說filter是依賴于servlet容器的。

@Override
	public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		// 擷取到session中使用者對象
		Object object = request.getSession().getAttribute(CommonConstants.SESSION_USER);

		String email = null;
		String password = null;
		String autoStatus = null;

		// 判斷如果object等于空 session中沒有使用者
		if (object == null) {
			Cookie[] cookies = request.getCookies();
			if (cookies != null && cookies.length > 0) {
				for (int i = 0; i < cookies.length; i++) {
					Cookie cookie = cookies[i];

					// 判斷Cookie的郵箱名是否等于"HKPhotoUserEmail"
					if (CommonConstants.BROWSER_COOKIE_EMAIL.equals(cookie.getName())) {
						email = cookie.getValue().trim();
					}

					// 判斷Cookie的密碼名是否等于"HKPhotoUserPassword"
					if (CommonConstants.BROWSER_COOKIE_PASSWORD.equals(cookie.getName())) {
						password = cookie.getValue().trim();
					}

					// 判斷Cookie的自動登入狀态名是否等于"HKPhotoAutoLoginStatus"
					if (CommonConstants.BROWSER_COOKIE_AUTO_STATUS_NAME
							.equals(cookie.getName())) {
						autoStatus = cookie.getValue().trim();
					}
				}
				if (autoStatus != null && autoStatus.equals("1")) {
					if (email != null && password != null && email.length() > 0
							&& password.length() > 0) {
						vlUser = new VLUser();
						vlUser.setUEmail(email);
						vlUser.setUPwd(password);
						vlUser = vlUserServiceImpl.searchUser(vlUser).get(0);

						if (vlUser != null) {
							// 将該user放入到session中
							request.getSession().setAttribute(CommonConstants.SESSION_USER, vlUser);
							chain.doFilter(request, response);//這句是繼續執行下面的filter
						} else {
							chain.doFilter(request, response);
						}
					} else {
						chain.doFilter(request, response);
					}
				} else {
					chain.doFilter(request, response);
				}

			} else {
				chain.doFilter(request, response);
			}
		} else {
			chain.doFilter(request, response);
		}
	}
           

給出filter中doFilter的代碼,init()和destroy()中沒有内容。

public void addCookieingUserToResponse(VLUser vlUser) {  
  
        // 設定cookie郵箱名值對  
        Cookie cookieEmail = new Cookie(CommonConstants.BROWSER_COOKIE_EMAIL,vlUser.getUEmail());  
        cookieEmail.setMaxAge(CommonConstants.BROWSER_COOKIE_MAX_AGE);  
        cookieEmail.setPath("/");  
        RequestAndResponse.getResponse().addCookie(cookieEmail);  
  
        // 設定cookie密碼名值對  
        Cookie cookiePassword = new Cookie(CommonConstants.BROWSER_COOKIE_PASSWORD, vlUser.getUPwd());      
        cookiePassword.setMaxAge(CommonConstants.BROWSER_COOKIE_MAX_AGE);  
        cookiePassword.setPath("/");  
        RequestAndResponse.getResponse().addCookie(cookiePassword);  
          
          
        // 設定cookie自動登入狀态名值對  
        Cookie autoLoginStatusCookie = new Cookie(  
                CommonConstants.BROWSER_COOKIE_AUTO_STATUS_NAME,  
                "1");  
        autoLoginStatusCookie  
                .setMaxAge(CommonConstants.BROWSER_COOKIE_MAX_AGE);  
        autoLoginStatusCookie.setPath("/");  
        RequestAndResponse.getResponse().addCookie(autoLoginStatusCookie);  
          
        // 設定cookie登出名值對  
        Cookie loginOutCookie = new Cookie(CommonConstants.BROWSER_COOKIE_LOGIN_OUT_NAME,"0");  
        loginOutCookie.setMaxAge(CommonConstants.BROWSER_COOKIE_MAX_AGE);  
        loginOutCookie.setPath("/");  
        RequestAndResponse.getResponse().addCookie(loginOutCookie);  
    }
    
    public void removeCookieingUserInResponse(){ 
    	System.out.println("removeCookie");
        // 設定cookie郵箱名值對  
        Cookie cookieEmail = new Cookie(CommonConstants.BROWSER_COOKIE_EMAIL,null);  
        cookieEmail.setMaxAge(CommonConstants.BROWSER_COOKIE_MAX_AGE);  
        cookieEmail.setPath("/");  
        RequestAndResponse.getResponse().addCookie(cookieEmail);  
  
        // 設定cookie密碼名值對  
        Cookie cookiePassword = new Cookie(CommonConstants.BROWSER_COOKIE_PASSWORD, null);   
        cookiePassword.setMaxAge(CommonConstants.BROWSER_COOKIE_MAX_AGE);  
        cookiePassword.setPath("/");  
        RequestAndResponse.getResponse().addCookie(cookiePassword);  
          
          
        // 設定cookie自動登入狀态名值對  
        Cookie autoLoginStatusCookie = new Cookie(CommonConstants.BROWSER_COOKIE_AUTO_STATUS_NAME,"0");  
        autoLoginStatusCookie.setMaxAge(CommonConstants.BROWSER_COOKIE_MAX_AGE);  
        autoLoginStatusCookie.setPath("/");  
        RequestAndResponse.getResponse().addCookie(autoLoginStatusCookie);  
          
        // 設定cookie登出名值對  
        Cookie loginOutCookie = new Cookie(CommonConstants.BROWSER_COOKIE_LOGIN_OUT_NAME,"0");  
        loginOutCookie.setMaxAge(CommonConstants.BROWSER_COOKIE_MAX_AGE);  
        loginOutCookie.setPath("/");  
        RequestAndResponse.getResponse().addCookie(loginOutCookie);  
    }
           

cookie的代碼也很簡單

我覺得主要是web.xml那塊需要記錄下來,因為spring管理filter的配置那塊和以前的filter不太一樣,讓我找了好一段時間。

繼續閱讀