首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Shiro 登出清空緩存實戰:自定義 LogoutFilter 實現 preHandle 釋放資源

     編輯:Java 相關知識

背景

Shiro 管理登入/登出/權限/Session。用戶登出時需清理緩存、關閉連接、釋放資源,防止垃圾數據堆積。

核心思路

  • 繼承 LogoutFilter
  • 重寫 preHandle():在登出邏輯前執行清理
  • 配置到 Shiro Filter 鏈中

1. 自定義登出過濾器

@Service
public class SystemLogoutFilter extends LogoutFilter {

    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        Subject subject = getSubject(request, response);
        String redirectUrl = getRedirectUrl(request, response, subject);

        try {
            // 1. 執行業務清理:清空緩存、關閉連接、刪除臨時文件等
            // cleanupCache(); closeConnections(); ...

            // 2. Shiro 內建登出:清除 Subject、Session、RememberMe Cookie
            subject.logout();
        } catch (SessionException e) {
            e.printStackTrace();
        }

        // 3. 重導向到登入頁
        issueRedirect(request, response, redirectUrl);

        // 返回 false:不繼續執行後續 Filter,直接結束
        return false;
    }
}

2. Spring-Shiro 整合配置

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager" />
    <property name="loginUrl" value="/b/login" />
    <property name="successUrl" value="/b" />

    <property name="filters">
        <map>
            <!-- 註冊自定義登出過濾器 -->
            <entry key="logout" value-ref="systemLogoutFilter" />
        </map>
    </property>

    <property name="filterChainDefinitions">
        <value>
            /b/login = authc
            /b/logout = logout
            /b/** = user
        </value>
    </property>
</bean>

關鍵點解析

點說明
@Service交由 Spring 容器管理,方便注入其他 Bean (如 CacheManager)
preHandle 返回 false阻斷 Filter 鏈,避免重複處理;issueRedirect 已完成導向
subject.logout()Shiro 核心登出:清除 Session、Subject 綁定、刪除 RememberMe Cookie
redirectUrl可配置登出後導向頁面,預設為 loginUrl
filterChainDefinitions/b/logout = logout 匹配自定義 filter name "logout"

擴展:常見登出清理項目

private void cleanup(Subject subject) {
    // 1. 清除業務緩存
    cacheManager.getCache("userCache").evict(subject.getPrincipal());

    // 2. 關閉資源連接
        // dbConnection.close(); redisConnection.close(); ...

    // 3. 刪除臨時文件
    // tempFileService.deleteByUser(subject.getPrincipal());

    // 4. 記錄登出日誌
    // auditLogService.logLogout(subject.getPrincipal());
}

注意事項

  • preHandle 異常不應阻礙登出流程,建議 try-catch 包裹清理邏輯
  • 若需在登出**後**執行邏輯,可重寫 postHandle (但 LogoutFilter 無此方法,可考慮 AOP 或監聽器)
  • 分佈式環境下,需配合 Redis 等集中式 Session 實現跨節點登出
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved