在分布式环境中使用kapcha和redis完成登录功能。
1.添加jar包
<!-- kaptcha -->
<dependency>
<groupId>com.google.code.kaptcha</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
2.在spring-mvc-servlet.xml中添加拦截器和captchaProducer bean
<mvc:status-controller status-code="200" path="/status"/>
<mvc:view-controller path="/" view-name="redirect:/login" />
<!-- 对静态资源文件的访问 restful-->
<mvc:resources mapping="/static/**" location="/static/" cache-period="31556926"/>
<mvc:resources location="/favicon.ico" mapping="/favicon.ico" />
<mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/" />
<mvc:resources mapping="/swagger-ui.html" location="classpath:/META-INF/resources/" />
<!-- 访问拦截 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/static/**" />
<mvc:exclude-mapping path="/favicon.ico"/>
<mvc:exclude-mapping path="/status"/>
<mvc:exclude-mapping path="/webjars/**" />
<mvc:exclude-mapping path="/*/api-docs" />
<mvc:exclude-mapping path="/swagger-ui.html" />
<mvc:exclude-mapping path="/configuration/**" />
<bean class="com.buoumall.common.web.interceptor.EventInterceptor">
<property name="nextInterceptor">
<array>
<!-- 登录拦截器 -->
<bean class="com.buoumall.front.interceptor.LoginInterceptor">
<property name="loginUrl" value="/login"/>
</bean>
</array>
</property>
</bean>
</mvc:interceptor>
</mvc:interceptors>
<!-- 验证码 -->
<bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">
<property name="config">
<bean class="com.google.code.kaptcha.util.Config">
<constructor-arg>
<props>
<prop key="kaptcha.border">no</prop>
<prop key="kaptcha.border.color">105,179,90</prop>
<prop key="kaptcha.textproducer.font.color">red</prop>
<prop key="kaptcha.image.width">250</prop>
<prop key="kaptcha.textproducer.font.size">90</prop>
<prop key="kaptcha.image.height">120</prop>
<prop key="kaptcha.session.key">code</prop>
<prop key="kaptcha.textproducer.char.length">4</prop>
<prop key="kaptcha.textproducer.font.names">宋体,楷体,微软雅黑</prop>
</props>
</constructor-arg>
</bean>
</property>
</bean>
3.生成验证码的controller
//生成验证码
@RequestMapping("/captcha-image")
public void captchaImageCode(@RequestParam Integer bizType,HttpServletRequest request, HttpServletResponse response) throws BizException {
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/png");
// create the text for the image
String capText = captchaProducer.createText();
//bizType为业务类型,这里为LOGIN
BizTypeEnum bizTypeEnum = BizTypeEnum.findByBizType(bizType);
if (bizTypeEnum == null) {
logger.error("The bizType is illegal!");
return;
}
//客户端保存一个验证码的cookie,GlobalConst.BOM_CAPTCHA_KEY为cookie的name,value为一个随机数
String captcha_key = CookieUtil.getCookieValue(request,GlobalConst.BOM_CAPTCHA_KEY);
//如果取出来的为空,这表示是一个新用户,客户端没有这个cookie,就新建一个
if(StringUtils.isBlank(captcha_key)){
captcha_key = UuidUtil.get32UUID();
logger.info("New user coming,captcha_key = {}", captcha_key);
CookieUtil.addCookie(response, GlobalConst.BOM_CAPTCHA_KEY, captcha_key, CaptchaCodeUtil.CAPTCHA_TIME_OUT);
}
//将验证码和客户端cookie的信息存在redis中
CaptchaCodeUtil.addCaptchaCode(captcha_key,redisService, bizTypeEnum, capText);
OutputStream out = null;
try {
// create the image with the text
BufferedImage bi = captchaProducer.createImage(capText);
out = response.getOutputStream();
// write the data out
ImageIO.write(bi, "png", out);
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(out);
}
}
//判断验证码是否正确
//一般是先判断验证码是否正确,如果正确再进行登录判断,不然提示验证码错误。
@RequestMapping(value = "/checkCaptchaCode")
@ResponseBody
public Result<Boolean> checkCaptchaCode(HttpServletRequest request,
@RequestParam Integer bizType, @RequestParam String captchaCode) {
//bizType表示业务类型,这里是LOGIN
BizTypeEnum bizTypeEnum = BizTypeEnum.findByBizType(bizType);
if (bizTypeEnum == null) {
logger.error("The bizType is illegal!");
return super.buildBizErrorResult("验证码bizType不合法");
}
//得到客户端cookie的value,redis里的key就是通过这个value生成的
String captchaKey = CookieUtil.getCookieValue(request, GlobalConst.BOM_CAPTCHA_KEY);
//在redis中判断验证码是否正确
boolean captchaCodeOk = CaptchaCodeUtil.captchaCodeOk(captchaKey,redisService, bizTypeEnum, captchaCode);
if (captchaCodeOk) {
return super.buildOk(true);
} else {
return super.buildBizErrorResult("验证码不正确");
}
}
4.图形验证码工具类
/**
* 图形验证码工具类,目前主要是未登录,基于Cookie的方式。用户已登录的情况,暂时没有。
*/
public class CaptchaCodeUtil {
private static final Logger logger = LoggerFactory.getLogger(CaptchaCodeUtil.class);
public static final String CAPTCHA_NAMESPACE = "captcha";
//验证码在redis中保存的时间
public static final int CAPTCHA_TIME_OUT = 10 * 60;
//captcha_key为一个随机数,captchaCode为验证码
//captchaKey为redis中的key,captchaCode为value
//添加验证码信息到redis
public static void addCaptchaCode(String captcha_key,RedisService redisService, BizTypeEnum bizType, String captchaCode) throws BizException {
String captchaKey = buildCaptchaKey(captcha_key, captchaCode, bizType);
if (StringUtils.isNotBlank(captchaKey)) {
redisService.add(captchaKey, captchaCode, CAPTCHA_TIME_OUT, TimeUnit.SECONDS);
}
}
// 验证某个业务的验证码,是否正确
public static boolean captchaCodeOk(String captcha_key,RedisService redisService, BizTypeEnum bizType, String captchaCode) {
try {
String captchaKey = buildCaptchaKey(captcha_key,captchaCode, bizType);
if(StringUtils.isNotBlank(captchaKey)){
// 验证码
String captchaCodeRedis = redisService.getString(captchaKey);
if (StringUtils.equalsIgnoreCase(captchaCodeRedis, captchaCode)) {
return true;
}
}
} catch (Exception e) {
logger.error(e.getMessage());
return false;
}
return false;
}
//重新构建redis中的key
private static String buildCaptchaKey(String captcha_key,String captchaCode, BizTypeEnum bizType) {
if(StringUtils.isBlank(captcha_key)){
return null;
}
String captchaKey = CAPTCHA_NAMESPACE + ":" + bizType.getDir() + ":" + captcha_key + ":" + captchaCode;
return captchaKey;
}
//删除redis中验证码的信息
public static void deleteCaptchaCode(String captcha_key,RedisService redisService, String captchaCode, BizTypeEnum bizType) throws BizException {
String captchaKey = buildCaptchaKey(captcha_key, captchaCode, bizType);
if (StringUtils.isNotBlank(captchaKey)) {
redisService.delete(captchaKey);
}
}
}
5.登录和登出
@ApiOperation(value = "登录", produces = MediaType.APPLICATION_JSON_VALUE)
@RequestMapping(value = "/doLogin",produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Result<Boolean> doLogin(
@ApiParam(required = true, value = "登录名") @RequestParam String loginName,
@ApiParam(required = true, value = "登录密码") @RequestParam String password,
@ApiParam(required = true, value = "验证码") @RequestParam String captchaCode,
HttpServletResponse response,
HttpServletRequest request
){
try {
BizTypeEnum bizType = BizTypeEnum.LOGIN;
//从客户端cookie中得到redis的value
String captcha_Key = CookieUtil.getCookieValue(request, GlobalConst.BOM_CAPTCHA_KEY);
boolean captchaCodeOk = CaptchaCodeUtil.captchaCodeOk(captcha_Key, redisService, bizType, captchaCode);
if(!captchaCodeOk){
return buildBizErrorResult("验证码错误!");
}
// 删除验证码
CaptchaCodeUtil.deleteCaptchaCode(captcha_Key, redisService, captchaCode, bizType);
Member member = memberSecurityBizService.login(loginName, password);
if(member == null){
logger.info("Login failed,loginName=" + loginName);
return buildBizErrorResult("用户名和密码信息输入有误!");
}
if(!RoleTypeEnum.DESIGNER.getCode().equals(member.getRoleType()) && !RoleTypeEnum.EDITOR.equals(member.getRoleType())){
return buildBizErrorResult("你无权登录本系统!");
}
//用户token的key值
String login_ut_key = UuidUtil.get32UUID();
//在客户端添加有关用户信息的Cookie
CookieUtil.addCookie(response, GlobalConst.BOM_FRONT_UT, login_ut_key, GlobalConst.KEEP_BOM_FRONT_UT_TIME);
//在redis中添加用户信息
redisService.add(login_ut_key, member,1,TimeUnit.HOURS);
return buildOk(true);
} catch (Exception e) {
return buildExceptionResult(e);
}
}
@ApiOperation(value = "登出", produces = MediaType.TEXT_HTML_VALUE)
@RequestMapping(value = "/logout", produces = MediaType.TEXT_HTML_VALUE)
public String logout(HttpServletRequest request, HttpServletResponse response) {
try {
logger.info("Logout");
String accessTokenKey = CookieUtil.getCookieValue(request,GlobalConst.BOM_FRONT_UT);
if(StringUtils.isNotBlank(accessTokenKey)){
CookieUtil.removeCookie(response, GlobalConst.BOM_FRONT_UT);
redisService.delete(accessTokenKey);
}
} catch (Exception e) {
logger.error("Logout failed");
e.printStackTrace();
}
return "login/login";
}
6.登录拦截器LoginInterceptor
package com.front.interceptor;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import com.alibaba.fastjson.JSON;
import com.common.web.interceptor.BaseInterceptor;
import com.common.web.util.CommonUtil;
import com.common.web.util.CookieUtil;
import com.common.web.util.RequestUtils;
import com.common.web.util.ResponseUtils;
import com.commonService.service.RedisService;
import com.front.result.Result.ResultCodeEnum;
import com.front.util.FrontLoginUtil;
import com.front.util.GlobalConst;
import com.front.util.NeedRole;
import com.userService.enums.RoleTypeEnum;
import com.userService.model.Member;
import com.userService.model.MemberDetail;
import com.userService.service.MemberDetailService;
import com.google.common.collect.Maps;
public class LoginInterceptor extends BaseInterceptor {
private String loginUrl;
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private MemberDetailService memberDetailService;
@Autowired
private RedisService redisService;
@Override
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
//将线程中的用户信息清空
FrontLoginUtil.setCurrentUser(null);
// User项目也需要响应图片
boolean b = handler instanceof HandlerMethod;
if (!b) {
return true;
}
//客户端cookie用户的value
String accessToken = CookieUtil.getCookieValue(request,GlobalConst.BOM_FRONT_UT);
Member member =null;
try {
if(StringUtils.isNotEmpty(accessToken)){
member = (Member) redisService.getValue(accessToken);
}
} catch (Exception e) {
logger.info(e.getMessage());
CookieUtil.removeCookie(response, GlobalConst.BOM_FRONT_UT);
}
boolean exist = CommonUtil.hasNeedLogin(handler);
if (!exist) {
return true;
}
boolean isAjaxRequest = RequestUtils.isAjaxRequest(request);
// 需要登录的
if (member != null) {
//刷新redis中用户信息保存的时间,只要操作就不会掉线
redisService.expire(accessToken, 1, TimeUnit.HOURS);
if(!RoleTypeEnum.DESIGNER.getCode().equals(member.getRoleType()) && !RoleTypeEnum.EDITOR.equals(member.getRoleType())){
logger.error("你无权操作本系统!");
jump(response, isAjaxRequest);
return false;
}
MemberDetail detail = memberDetailService.getByMemberId(member.getId());
//保存用户信息
FrontLoginUtil.initCurrentUser(member, detail);
//判断“角色”
NeedRole needRole=hasNeedRole(handler);
if(needRole==null){
return true;
}else{
Integer roleType = member.getRoleType();
boolean needDesigner=needRole.designer();
boolean needEditor=needRole.editor();
//需要设计师权限,但是没有
if(needDesigner && !RoleTypeEnum.DESIGNER.getCode().equals(roleType)){
logger.error("权限不足,没有设计师权限");
jump(response, isAjaxRequest);
return false;
}
//需要编辑权限,但是没有
if(needEditor && !RoleTypeEnum.EDITOR.getCode().equals(roleType)){
logger.error("权限不足,没有服务者权限");
jump(response, isAjaxRequest);
return false;
}
}
return true;
} else {
jump(response, isAjaxRequest);
return false;
}
}
// 需要登录,但是没有登录
private void jump(HttpServletResponse response, boolean isAjaxRequest) throws IOException {
if (isAjaxRequest) {
// 异步
jsonLogin(response);
}else {
// 同步
response.sendRedirect(loginUrl);
}
}
private static void jsonLogin(HttpServletResponse response) {
Map<String, Object> map = Maps.newHashMap();
map.put("code", ResultCodeEnum.NEED_LOGIN.getCode());
map.put("msg", "会话超时,请重新登录");
ResponseUtils.renderJson(response, JSON.toJSONString(map));
}
public String getLoginUrl() {
return loginUrl;
}
public void setLoginUrl(String loginCenterUrl) {
this.loginUrl = loginCenterUrl;
}
public static NeedRole hasNeedRole(Object handler) {
if(!(handler instanceof HandlerMethod)){
return null;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
Class<?> type = handlerMethod.getBeanType();
// 判断是否有NeedRole注解
NeedRole needRole = type.getAnnotation(NeedRole.class);
if (needRole == null) {
needRole = type.getSuperclass().getAnnotation(NeedRole.class);
}
if (needRole == null) {
needRole = handlerMethod.getMethodAnnotation(NeedRole.class);
}
return needRole;
}
}
7.前端用的登录工具,保存用户信息
package com.front.util;
import com.front.model.UserInfo;
import com.userService.model.Member;
import com.userService.model.MemberDetail;
public class FrontLoginUtil {
private static ThreadLocal<UserInfo> currentUser = null;
private FrontLoginUtil(){
}
public static void setCurrentUser(UserInfo userInfo) {
if(currentUser == null){
currentUser = new ThreadLocal<UserInfo>();
}
currentUser.set(userInfo);
}
public static UserInfo getCurrentUser() {
return currentUser.get();
}
public static void initCurrentUser(Member member,MemberDetail memberDetail) {
if (member != null) {
UserInfo userInfo = new UserInfo();
userInfo.setId(member.getId());
userInfo.setName(member.getName());
userInfo.setMobile(member.getMobile());
userInfo.setRoleType(member.getRoleType());
userInfo.setNickname(memberDetail.getNickname());
userInfo.setAvatar(memberDetail.getAvatar());
setCurrentUser(userInfo);
}
}
}
8.cookie工具类CookieUtil
package com.common.web.util;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;
import com.google.common.collect.Maps;
public class CookieUtil {
/**
* 写入一个Cookie
* @param response
* @param name
* @param path
* @param value
* @param maxAge
*/
public static void addCookie(HttpServletResponse response, String name, String value, String path, int maxAge) {
Cookie cookie = new Cookie(name, value);
if(StringUtils.isNotBlank(path)){
cookie.setPath(path);
}
if (maxAge>0) {
cookie.setMaxAge(maxAge);
}
response.addCookie(cookie);
}
/**
* 写入一个Cookie
* @param response
* @param name
* @param value
* @param maxAge
*
*/
public static void addCookie(HttpServletResponse response, String name, String value, int maxAge) {
addCookie(response, name, value,"/", maxAge);
}
/**
* 根据名称获得value
* @param request
* @param name
* @return
*/
public static String getCookieValue(HttpServletRequest request, String name) {
Cookie[] cookies=request.getCookies();
if(cookies != null){
for (Cookie cookie : cookies) {
if(cookie.getName().equalsIgnoreCase(name)){
return cookie.getValue();
}
}
}
return null;
}
/**
* 删除某个cookie
*
* @param response
* @param name
* @param path
*/
public static void removeCookie(HttpServletResponse response,String name,String path) {
Cookie cookie = new Cookie(name,null);
cookie.setMaxAge(0);
cookie.setPath(path);
response.addCookie(cookie);
}
/**
* 删除某个cookie
*
* @param response
* @param name
*
*/
public static void removeCookie(HttpServletResponse response,String name) {
removeCookie(response, name, "/");
}
/**
* 读取全部Cookie到Map
* @param request
* @return
*/
public static Map<String, Cookie> readCookieToMap(HttpServletRequest request) {
Map<String, Cookie> cookieMap = Maps.newHashMap();
Cookie[] cookies = request.getCookies();
if (null != cookies) {
for (Cookie cookie : cookies) {
cookieMap.put(cookie.getName(), cookie);
}
}
return cookieMap;
}
/**
* 清除所有Cookie
* @param request
* @param response
*/
public static void clear(HttpServletRequest request,HttpServletResponse response) {
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for(Cookie cookie:cookies) {
cookie.setValue(null);
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
}
/**
* 获得cookie
*
* @param request
* HttpServletRequest
* @param name
* cookie name
* @return if exist return cookie, else return null.
*/
public static Cookie getCookie(HttpServletRequest request, String name) {
Assert.notNull(request);
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
if (cookie.getName().equalsIgnoreCase(name)) {
return cookie;
}
}
}
return null;
}
}
9.redis的工具类
一、接口
package com.commonService.service;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import com.commonService.exception.BizException;
/**
* 缓存数据服务
*/
public interface RedisService {
/**
* 加入缓存
*
* @param key 加入缓存
* @param value 缓存的数据
* @return
* @throws BizException
*/
public abstract void add(String key, Serializable value) throws BizException;
/**
* 加入缓存,并设置缓存时间
*
* @param key 缓存的key
* @param value 缓存的值
* @param timeout 缓存时间
* @param unit 缓存时间类型枚举
* @throws BizException
*
*/
public abstract void add(String key, Serializable value, long timeout,
TimeUnit unit) throws BizException;
/**
* 如果这个key不在缓存中就设置
*
* @param key 缓存的key
* @param value 缓存的对象
* @return true/false
* @throws BizException
*
*/
public abstract boolean setIfAbsent(String key, Serializable value) throws BizException;
/**
* 获取缓存字符串
*
* @param key 缓存的key
* @return 缓存的字符串
* @throws BizException
*
*/
public String getString(String key) throws BizException;
/**
* 获取缓存的对象
*
* @param key 缓存的key
* @return 缓存的对象
* @throws BizException
*
*/
public abstract Serializable getValue(String key) throws BizException;
/**
* 获取指定时间之内redis自增序列
*
* @param key 缓存的key
* @param timeout 时间
* @param timeUnit 时间类型
* @return 自增值
* @throws BizException
*
*/
public abstract Long getSequence(String key, long timeout, TimeUnit timeUnit) throws BizException;
/**
* 删除缓存的对象
*
* @param key 缓存的key
* @return
* @throws BizException
*/
public abstract void delete(String key) throws BizException;
/**
* 批量删除缓存对象
*
* @param keys 缓存的key集合
* @return
* @throws BizException
*/
public abstract void delete(Collection<String> keys) throws BizException;
/**
* 判断key是否存在
*
* @param key 缓存的key
* @return 是否存在
* @throws BizException
*/
public abstract boolean exists(String key) throws BizException;
/**
* 设置指定key的过期时间
*
* @param key 参数key
* @param timeout 时间
* @param unit 时间类型
* @return 是否成功
* @throws BizException
*
*/
public abstract boolean expire(String key, long timeout, TimeUnit unit) throws BizException;
/**
* 设置指定key的过期日期
*
* @param key 参数key
* @param date 日期
* @return 是否成功
* @throws BizException
*
*/
public abstract boolean expireAt(String key, Date date) throws BizException;
/**
* 获取key过期剩余时间,单位是秒
*
* @param key 缓存的key
* @return 时间
* @throws BizException
*
*/
public abstract Long getExpire(String key) throws BizException;
/**
* 获取key过期剩余时间
*
* @param key 获取过期
* @param unit 时间类型
* @return 时间
* @throws BizException
*
*/
public abstract Long getExpire(String key, TimeUnit unit) throws BizException;
/**
* 获取所有匹配的key对象列表
*
* @param pattern 例如 KEYS w3c* 获取以 w3c 为开头的 key的值
* @return 对象列表
* @throws BizException
*
*/
public <T> List<T> getByPattern(String pattern) throws BizException;
}
二、实现类
package com.commonService.service.impl;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.StringUtils;
import com.commonService.exception.BizException;
import com.commonService.service.RedisService;
import com.google.common.collect.Lists;
public class RedisServiceImpl implements RedisService {
private RedisTemplate<String, Serializable> redisTemplate;
public RedisTemplate<String, Serializable> getRedisTemplate() {
return redisTemplate;
}
public void setRedisTemplate(RedisTemplate<String, Serializable> redisTemplate) {
this.redisTemplate = redisTemplate;
}
private String redisKeyNamespace;
public String getRedisKeyNamespace() {
return redisKeyNamespace;
}
public void setRedisKeyNamespace(String redisKeyNamespace) {
this.redisKeyNamespace = redisKeyNamespace;
}
// 加入缓存
@Override
public void add(String key, Serializable value) throws BizException {
key = buildKey(key);
ValueOperations<String, Serializable> valueops = redisTemplate.opsForValue();
valueops.set(key, value);
}
// 加入缓存,并设置缓存时间
@Override
public void add(String key, Serializable value, long timeout, TimeUnit unit) throws BizException {
key = buildKey(key);
ValueOperations<String, Serializable> valueops = redisTemplate.opsForValue();
valueops.set(key, value, timeout, unit);
}
// 如果这个key不在redis中就设置
@Override
public boolean setIfAbsent(String key, Serializable value) throws BizException {
key = buildKey(key);
ValueOperations<String, Serializable> valueops = redisTemplate.opsForValue();
boolean result = valueops.setIfAbsent(key, value);
return result;
}
// 获取缓存的对象
@Override
public String getString(String key) throws BizException {
key = buildKey(key);
ValueOperations<String, Serializable> valueops = redisTemplate.opsForValue();
String value = (String) valueops.get(key);
return value;
}
// 获取缓存的对象
@Override
public Serializable getValue(String key) throws BizException {
key = buildKey(key);
ValueOperations<String, Serializable> valueops = redisTemplate.opsForValue();
Serializable value = valueops.get(key);
return value;
}
//获取所有匹配的key 例如 KEYS w3c* 获取以 w3c 为开头的 key 的值
@Override
public <T> List<T> getByPattern(String pattern) throws BizException {
pattern = buildKey(pattern);
Set<String> keys = redisTemplate.keys(pattern);
ValueOperations<String, Serializable> valueops = redisTemplate.opsForValue();
@SuppressWarnings("unchecked")
List<T> list = (List<T>) valueops.multiGet(keys);
return list;
}
// 获取一段时间自增序列
@Override
public Long getSequence(String key, long timeout, TimeUnit timeUnit) throws BizException {
key = buildKey(key);
ValueOperations<String, Serializable> valueOperations = redisTemplate.opsForValue();
Long sequence = null;
if(redisTemplate.hasKey(key)){
sequence = valueOperations.increment(key, 1l);
}else{
sequence = valueOperations.increment(key, 1l);
redisTemplate.expire(key, timeout, timeUnit);
}
return sequence;
}
// 单个删除
@Override
public void delete(String key) throws BizException {
key = buildKey(key);
redisTemplate.delete(key);
}
@Override
public void delete(Collection<String> keys) throws BizException {
if (CollectionUtils.isEmpty(keys)) {
throw new BizException("key 不能为空!");
}
List<String> list = Lists.newArrayList();
for (String key : keys) {
list.add(buildKey(key));
}
redisTemplate.delete(list);
}
// 判断key是否存在
@Override
public boolean exists(String key) throws BizException {
key = buildKey(key);
Boolean b = redisTemplate.hasKey(key);
return b.booleanValue();
}
// 设置指定key的过期时间
@Override
public boolean expire(String key, long timeout, TimeUnit unit) throws BizException {
key = buildKey(key);
return redisTemplate.expire(key, timeout, unit);
}
// 设置指定key的过期时间
@Override
public boolean expireAt(String key, Date date) throws BizException {
key = buildKey(key);
return redisTemplate.expireAt(key, date);
}
// 获取key过期剩余时间,单位是秒
@Override
public Long getExpire(String key) throws BizException {
key = buildKey(key);
return redisTemplate.getExpire(key);
}
// 获取key过期剩余时间
@Override
public Long getExpire(String key, TimeUnit unit) throws BizException {
key = buildKey(key);
return redisTemplate.getExpire(key, unit);
}
private String buildKey(String key) throws BizException {
if (StringUtils.isEmpty(key)) {
throw new BizException("key 不能为空!");
}
if (StringUtils.hasText(redisKeyNamespace)) {
key = redisKeyNamespace + ":" + key;
}
return key;
}
}
kaptcha验证码组件的使用可以参考http://chenzhou123520.iteye.com/blog/1987636
http://www.open-open.com/lib/view/open1395238908947.html