tomcat配置context的crossContext屬性應用案例


在tomcat下,context元素有一個crossContext屬性,如果配置為true,則可以實現在同一個tomcat下的多個web應用之間實現ServletContext對象訪問。該屬性主要用於跨應用訪問數據

在實際項目中遇到一個奇葩需求:在同一個頁面框架下嵌套了2套應用!!!
app1和app2部署在同一個tomcat,且session超時時間使用tomcat全局配置。
app2存在定時ajax刷新,導致app2不會存在session超時的問題;因此,如果用戶長期停留在app2某個定時刷新的頁面,就會出現如下情況;
app2不會出現session超時,但是app1在指定時間之后就會session超時,這時訪問app2頁面不會跳轉到登錄頁面,而點擊app1頁面元素就會退出登錄,重新跳轉到登錄頁面。
給用於一種很不自然的體驗!

為了解決這個問題,做如下調整:
1. 首先,必須明確一個現實:app1和app2是2個獨立的應用,所以對於瀏覽器訪問都會在服務器端各自生成獨立的session。
2. tomcat支持配置context元素的crossContext屬性為true,使得在app2中可以訪問到app1應用的ServletContext對象。
利用這個特性,可以在app2中知道app1應用下對應的session是否已經超時。如果已經超時,則在訪問app2時就退出登錄,跳轉到登錄頁面。


1. tomcat配置

<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
    <Context path="/app1" debug="0" reloadable="true" crossContext="true" />
    <Context path="/app2" debug="0" reloadable="true" crossContext="true" />
</Host>

2. app1端

public void login(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException{
    ...
    HttpSession session = req.getSession();
    req.getSession().getServletContext().setAttribute(session.getId(), session);
    resp.sendRedirect("app2?app1sid=" + session.getId()); // 將app1對應的sessonid傳遞給app2
    ...
}

3. app2端

public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
    ...
    if (pageType == 1) {// 從app1跳轉到app2
        // 獲取在app1應用中對應的session id並保存到app2會話中
        if(req.getSession().getAttribute(req.getSession().getId()) == null) {
            String app1SesionId = request.getParameter("app1sid");
            req.getSession().setAttribute(req.getSession().getId(), app1SesionId);
        }
    }else {
        // 獲取app1應用上下文
        ServletContext app1Context = req.getSession().getServletContext().getContext("/app1");
String app1SessionId = req.getSession().getAttribute(req.getSession().getId()).toString(); HttpSession app1Session
= (HttpSession)app1Context.getAttribute(app1SessionId); try { app1Session.getAttribute("login_user"); } catch (IllegalStateException e) { e.printStackTrace(); // app1會話已經超時, 直接在訪問app2時就退出登錄 // 另外,還應該在app2定時刷新的地方檢測app1會話是否已經超時,如果已經超時,則不再返回數據 req.getSession().invalidate(); resp.sendRedirect("/app1/login.do"); return; } } ... }


關於context配置crossContext屬性詳見:http://tomcat.apache.org/tomcat-7.0-doc/config/context.html
切記:該特性只適用於多個應用程序部署在同一個tomcat下的情形!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM