ehCache

 1、最近在做一個貸款項目是城市分站的 分爲貸款前臺和貸款機構後臺,這個兩個平臺的二級域名不一樣,一個前臺是cityname.xx.com,cityname是會地區的不同而變化的,如在 北京就是bj.xx.com,機構後臺是loan.xx.com,在機構登錄的時候 ,如果把登錄信息放在session,會有一個問題,就是當切換到前臺的時候,由於域名改變了,此時session就會改變,之前session保存的信 息就不存在了,也就是session跨域問題,最後想到了使用緩存才存儲在線用戶信息,這樣就不存在session跨域的問題。

        2、ehCache介紹

       EhCache 是一個純Java的進程內緩存框架,具有快速、精幹等特點,是Hibernate中默認的CacheProvider。

      下圖是 Ehcache 在應用程序中的位置:

       ehCache+spring的簡單實用

     

     主要的特性有:

      1. 快速.
      2. 簡單.
      3. 多種緩存策略
      4. 緩存數據有兩級:內存和磁盤,因此無需擔心容量問題
      5. 緩存數據會在虛擬機重啓的過程中寫入磁盤
      6. 可以通過RMI、可插入API等方式進行分佈式緩存
      7. 具有緩存和緩存管理器的偵聽接口
      8. 支持多緩存管理器實例,以及一個實例的多個緩存區域
      9. 提供Hibernate的緩存實現

下面說ehcache的使用

  ①下載ehcache.jar,自己去google下載地址

  ②隨後,開始配置ehCache的屬性,ehCache需要一個xml文件來設置ehCache相關的一些屬性,如最大緩存數量、cache刷新的時間等等

ehcache.xml放在你的classpath下.
 
01 <ehcache>
02 <!--<diskStore path="c:\\myapp\\cache"/> -->
03       
04     <defaultCache
05         maxElementsInMemory="1000"
06         eternal="false"
07         timeToIdleSeconds="120"
08         timeToLiveSeconds="120"
09         overflowToDisk="false"
10         />
11   <cache name="DEFAULT_CACHE"
12         maxElementsInMemory="10000"
13         eternal="false"
14         timeToIdleSeconds="300000"
15         timeToLiveSeconds="600000"
16         overflowToDisk="false"
17         />
18 </ehcache>
19 <!-- 
20 1.必須要有的屬性: 
21 name: cache的名字,用來識別不同的cache,必須惟一。 
22 maxElementsInMemory: 內存管理的緩存元素數量最大限值。 
23 maxElementsOnDisk: 硬盤管理的緩存元素數量最大限值。默認值爲0,就是沒有限制。 
24 eternal: 設定元素是否持久話。若設爲true,則緩存元素不會過期。 
25 overflowToDisk: 設定是否在內存填滿的時候把數據轉到磁盤上。 
26 2.下面是一些可選屬性: 
27 timeToIdleSeconds: 設定元素在過期前空閒狀態的時間,只對非持久性緩存對象有效。默認值爲0,值爲0意味着元素可以閒置至無限長時間。 
28 timeToLiveSeconds: 設定元素從創建到過期的時間。其他與timeToIdleSeconds類似。 
29 diskPersistent: 設定在虛擬機重啓時是否進行磁盤存儲,默認爲false.(我的直覺,對於安全小型應用,宜設爲true)。 
30 diskExpiryThreadIntervalSeconds: 訪問磁盤線程活動時間。 
31 diskSpoolBufferSizeMB: 存入磁盤時的緩衝區大小,默認30MB,每個緩存都有自己的緩衝區。 
32 memoryStoreEvictionPolicy: 元素逐出緩存規則。共有三種,Recently Used (LRU)最近最少使用,爲默認。 First In First Out (FIFO),先進先出。Less Frequently Used(specified as LFU)最少使用
33  -->
③用spring3攔截器檢查緩存中是否有用戶信息
01 package com.woaika.loan.front.common.filter;
02   
03 import javax.annotation.Resource;
04 import javax.servlet.http.HttpServletRequest;
05 import javax.servlet.http.HttpServletResponse;
06 import javax.servlet.http.HttpSession;
07   
08 import net.sf.ehcache.Cache;
09 import net.sf.ehcache.Element;
10   
11 import org.apache.log4j.Logger;
12 import org.springframework.web.servlet.HandlerInterceptor;
13 import org.springframework.web.servlet.ModelAndView;
14   
15 import com.woaika.loan.front.loanuser.vo.LoginOrganVo;
16 import com.woaika.loan.ip.IPUtil;
17 import com.woaika.loan.po.LoanOrgan;
18   
19 public class OrgMgtInterceptor implements HandlerInterceptor {
20   
21     private Logger log = Logger.getLogger(OrgMgtInterceptor.class);
22       
23     private Cache  ehCache;
24       
25     @Resource(name="ehCache")
26     public void setEhCache(Cache ehCache) {
27         this.ehCache = ehCache;
28     }
29       
30     public void afterCompletion(HttpServletRequest arg0,
31             HttpServletResponse arg1, Object arg2, Exception arg3)
32             throws Exception {
33         //log.info("==============執行順序: 3、afterCompletion================");  
34   
35     }
36   
37       
38     public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
39             Object arg2, ModelAndView arg3) throws Exception {
40         //log.info("==============執行順序: 2、postHandle================");  
41   
42     }
43   
44       
45     public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
46             Object handler) throws Exception {
47         // log.info("==============執行順序: 1、preHandle================");
48   
49           String ip =  IPUtil.getRemortIP(request);
50           Element elementIp = ehCache.get(ip);   
51           if(null==elementIp){
52               response.sendRedirect(com.woaika.loan.commons.constants.SiteConstant.JIGOU_URL+"/tologin");
53               return false;
54           }else{
55               LoginOrganVo vo =(LoginOrganVo)elementIp.getObjectValue();
56               if(vo!=null){
57                   Element elementId = ehCache.get(vo.getId().toString());
58                   if(elementId!=null){
59                       String tempIp = (String)elementId.getObjectValue();
60                       if(tempIp!=null && !"".equals(tempIp) && ip.equals(tempIp)){
61                           request.setAttribute("currentOrgan", vo);
62                           return true
63                       }
64                       
65                   }else{
66                       response.sendRedirect(com.woaika.loan.commons.constants.SiteConstant.JIGOU_URL+"/tologin");
67                       return false
68                         
69                   }
70               }
71           }
72           return true;
73             
74         /* String url=request.getRequestURL().toString();  
75             // if(url.matches(mappingURL)){
76                     HttpSession session = request.getSession();
77                     LoanOrgan org = (LoanOrgan)session.getAttribute("currentOrgan");
78                     if(org!=null){
79                         return true;
80                     }else{
81                         response.sendRedirect(com.woaika.loan.commons.constants.SiteConstant.JIGOU_URL+"/tologin");
82                     }
83                     return false;   
84               //  }    
85              //   return true;
86          */    
87   
88     }
89   
90 }
④將ehcache進行注入的配置applicationContext-ehCache.xml
 
01 <beans xmlns="http://www.springframework.org/schema/beans"
02  xmlns:context="http://www.springframework.org/schema/context"
03  xmlns:p="http://www.springframework.org/schema/p"
04  xmlns:mvc="http://www.springframework.org/schema/mvc"
05  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
06  xmlns:aop="http://www.springframework.org/schema/aop"
07  xmlns:tx="http://www.springframework.org/schema/tx"
08  xsi:schemaLocation="http://www.springframework.org/schema/beans
09       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
10       http://www.springframework.org/schema/context
11       http://www.springframework.org/schema/context/spring-context.xsd
12       http://www.springframework.org/schema/tx 
13       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
14       http://www.springframework.org/schema/aop
15       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
16       http://www.springframework.org/schema/mvc
17       http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
18     <!-- 引用ehCache的配置 -->   
19     <bean id="defaultCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">   
20       <property name="configLocation">   
21         <value>classpath:ehcache.xml</value>   
22      </property>   
23     </bean>
24       
25       <!-- 定義ehCache的工廠,並設置所使用的Cache name -->   
26     <bean id="ehCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">   
27       <property name="cacheManager">   
28         <ref local="defaultCacheManager"/>   
29       </property>   
30       <property name="cacheName">   
31           <value>DEFAULT_CACHE</value>   
32       </property>   
33     </bean>  
34       
35 </beans>
⑤登錄的時候,驗證用戶名密碼,正確放入緩存,這裏只是提供一個簡單的方法(用的spring的mvc)
 
01 @RequestMapping(value="/login")
02     public String login(String organname, String pwd, HttpServletRequest request, HttpServletResponse response){
03          judgmentCity.getCityInfo(request);
04         LoanOrgan organ = loanOrganService.login(organname, pwd);
05         if(organ==null){
06             request.setAttribute("msg", "用戶名或密碼錯誤");
07             return "forward:/jigou/tologin";
08         }else{
09             //將機構信息存在cache中,來進行跨域
10             String ip =  IPUtil.getRemortIP(request);
11              LoginOrganVo vo = new LoginOrganVo();
12              vo.setId(organ.getId());
13              vo.setOrganname(organ.getOrganname());
14              Element elementip  = new  Element(ip, (Serializable) vo);   
15              Element elementid  = new  Element(organ.getId().toString(), ip);
16              //Element elementvo  = new  Element(organ.getId().toString(), (Serializable) vo);
17              ehCache.put(elementip);//添加到緩存
18              ehCache.put(elementid);
19             // ehCache.put(elementvo);
20             //request.getSession().setAttribute("currentOrgan", organ);
21             return "redirect:/organmgt/index";
22         }
23     }
註銷操作(用的spring的mvc):
 
01 //註銷登錄
02    @RequestMapping(value="/logout")
03    public String logout(HttpServletRequest request){
04        String ip =  IPUtil.getRemortIP(request);
05        Element elementIp = ehCache.get(ip); 
06        if(elementIp!=null){
07            LoginOrganVo vo =(LoginOrganVo)elementIp.getObjectValue();
08            if(vo!=null){
09                ehCache.remove(vo.getId());
10            }
11        }
12        ehCache.remove(ip);
13        //request.getSession().removeAttribute("currentOrgan");
14        return "redirect:/jigou/tologin";
15    }
⑥spring3攔截器的配置文件
 
1 <mvc:interceptors>  
2        <mvc:interceptor>  
3           <mvc:mapping path="/organmgt/**" /><!-- 如果不配置或/*,將攔截所有的Controller -->  
4           <bean class="com.woaika.loan.front.common.filter.OrgMgtInterceptor">
5           </bean>  
6        </mvc:interceptor>  
7    </mvc:interceptors>
這樣所有的/organmgt/開頭的請求都會被攔截,在這個攔截器進行檢查是否登錄就可以,這裏我採用的是用戶客戶端ip和用戶id兩個key存儲了用戶信息保證用戶的唯一信。


事實上到了這裏,一個簡單的Spring + ehCache Framework基本完成了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章