剛才寫了一篇文章關於圖形驗證碼的,感覺沒有考慮集群情況。其實集群無非加一個集群緩存 將session換成redis或者memcache。
今天記錄一下 使用 redis做集群圖形驗證碼的相關方案。
基於文章:
http://www.cnblogs.com/owenma/p/7375540.html
添加redis:
在獲取和存儲的地方使用的是redis封裝好的cacheManager。
@RequestMapping(value = "/getKaptchaImage", method = RequestMethod.GET) public ModelAndView getImage(HttpServletRequest request, HttpServletResponse response) throws Exception{ HttpSession session = request.getSession(); Cache<String, String> kaptcha = cacheManager.getCache("kaptcha"); String code = kaptcha.get(Constants.KAPTCHA_SESSION_KEY); System.out.println("******************驗證碼是: " + code + "******************"); Producer captchaProducer = (Producer)SpringContextUtils.getBean("captchaProducer"); response.setDateHeader("Expires", 0); // Set standard HTTP/1.1 no-cache headers. response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); // Set IE extended HTTP/1.1 no-cache headers (use addHeader). response.addHeader("Cache-Control", "post-check=0, pre-check=0"); // Set standard HTTP/1.0 no-cache header. response.setHeader("Pragma", "no-cache"); // return a jpeg response.setContentType("image/jpeg"); // create the text for the image String capText = captchaProducer.createText(); // store the text in the session session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText); kaptcha.put(Constants.KAPTCHA_SESSION_KEY, capText); // create the image with the text BufferedImage bi = captchaProducer.createImage(capText); ServletOutputStream out = response.getOutputStream(); // write the data out ImageIO.write(bi, "jpg", out); try { out.flush(); } finally { out.close(); } return null; } @RequestMapping(value = "/checkKaptchaImage", method = RequestMethod.POST) public @ResponseBody Map<String, String> checkKaptchaImage(HttpServletRequest request, HttpServletResponse response) throws Exception{ Map<String, String> returnMap = new HashMap<>(); Cache<String, String> kaptcha = cacheManager.getCache("kaptcha"); //從session中取出servlet生成的驗證碼text值 String kaptchaExpected = kaptcha.get(Constants.KAPTCHA_SESSION_KEY); //獲取用戶頁面輸入的驗證碼 String kaptchaReceived = request.getParameter("kaptcha"); //校驗驗證碼是否正確 returnMap.put("code", "100"); if (kaptchaExpected == null){ returnMap.put("status", "expire"); return returnMap; } if (!kaptchaReceived.equalsIgnoreCase(kaptchaExpected)){ returnMap.put("status", "false"); return returnMap; } returnMap.put("status", "true"); return returnMap; }
2. cacheManager代碼
package com.nc.shiro.cache; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.CacheException; import org.apache.shiro.cache.CacheManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; public class RedisCacheManager implements CacheManager { private static final Logger logger = LoggerFactory .getLogger(RedisCacheManager.class); @Autowired private JedisConnectionFactory connectionFactory; private static RedisRealOPT redisRealOPT; // fast lookup by name map private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>(); /** * The Redis key prefix for caches */ private String keyPrefix = "shiro_redis_cache:"; /** * Returns the Redis session keys * prefix. * @return The prefix */ public String getKeyPrefix() { return keyPrefix; } /** * Sets the Redis sessions key * prefix. * @param keyPrefix The prefix */ public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; } @Override public <K, V> Cache<K, V> getCache(String name) throws CacheException { logger.debug("獲取名稱為: " + name + " 的RedisCache實例"); Cache c = caches.get(name); if (c == null) { redisRealOPT = new RedisRealOPT(); redisRealOPT.setJedis(connectionFactory.getShardInfo().createResource()); redisRealOPT.setExpire(getTTL(name)); keyPrefix = name + ":"; // create a new cache instance c = new RedisCache<K, V>(redisRealOPT, keyPrefix); // add it to the cache collection caches.put(name, c); } // else { // ((RedisCache) c).getCache().setJedis(connectionFactory.getShardInfo().createResource()); // } return c; } public JedisConnectionFactory getConnectionFactory() { return connectionFactory; } public void setConnectionFactory(JedisConnectionFactory connectionFactory) { this.connectionFactory = connectionFactory; } private int getTTL(String name){ //獲得路徑 File classPath = new File(this.getClass().getResource("/").getPath()); File properties = new File(classPath.getPath() + "/cacheManager.properties"); Properties prop = new Properties(); try { prop.load(new FileInputStream(properties)); String propertyNames = prop.stringPropertyNames().toString(); if (propertyNames.contains(name)){ String value = prop.getProperty(name).trim(); return Integer.parseInt(value); } } catch (Exception e) { e.printStackTrace(); } return 0; } }
如果覺得有疑問或者對你有幫助 歡迎評論。
作者:森林木馬
如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的“推薦”將是我最大的寫作動力!歡迎各位轉載,但是未經作者本人同意
轉載文章之后必須在 文章頁面明顯位置給出作者和原文連接否則保留追究法律責任的權利。