ssm+log+redis登录小demo

本练习场景

  • 用户输入手机号,申请验证码
  • 后台生成验证码,存入redis,设置5分钟自动过期,返回给用户
  • 用户提交手机号和验证码给后台验证
  • 后台验证登录信息,验证通过后
    • 先查询redis是否保存有该用户信息,没有则查数据库
    • 数据库如无记录,说明为新用户,自动注册
    • 将用户信息存入redis,返回handler
    • controller将用户信息存入session,返回

handler代码

@Controller
@RequestMapping("login")
public class LoginHandler {
    @Resource
    private LoginService loginService;

    /**
     * 获取登录验证码
     *
     * @param phone 手机号
     * @return
     */
    @GetMapping("valCode")
    public ResponseEntity getValidateCode(String phone) {
        String valCode = loginService.getValCode(phone);
        return ResponseEntity.ok(new ResponseBean(StatusEnum.OPE_SUC, valCode));
    }

    /**
     * 通过手机号和验证码验证登录
     *
     * @param phone   手机号
     * @param valCode 验证码
     * @return
     */
    @PostMapping("doLogin")
    public ResponseEntity doLogin(String phone, String valCode, HttpSession session) {
        Myuser myuser = loginService.doLogin(phone, valCode);
        if (myuser == null) {
            throw new MyExceptin(StatusEnum.OPE_ERR);
        }
        session.setAttribute("LOGIN_USER", myuser);
        myuser.setUpass("");
        return ResponseEntity.ok(new ResponseBean(StatusEnum.LOGIN_SUC, myuser));
    }

}

serviceImpl代码

@Service
public class LoginServiceImpl implements LoginService {

    private Logger logger = LoggerFactory.getLogger(LoginServiceImpl.class);

    @Resource
    private ShardedJedisPool jedisPool;

    @Resource
    private LoginMapper loginMapper;

    /**
     * 获取验证码
     *
     * @param phone 手机号
     * @return
     */
    @Override
    public String getValCode(String phone) {
        if (phone == null) {
            throw new MyExceptin(StatusEnum.PHONE_EMPTY);
        }
        String valCode = StringRandom.getValCode();
        // 打印日志
        logger.info("获取到了验证码,验证码为:" + valCode);

        ShardedJedis resource = jedisPool.getResource();
        // 5分钟自动过期
        resource.setex(RedisHeadInfo.CODE_HEAD + phone, 5 * 60, valCode);
        resource.close();

        return valCode;
    }

    /**
     * 验证登录信息,返回用户信息
     *
     * @param phone   登录手机号
     * @param valCode 登录验证码
     * @return
     */
    @Override
    public Myuser doLogin(String phone, String valCode) {
        if (phone == null) {
            throw new MyExceptin(StatusEnum.PHONE_EMPTY);
        }
        // 验证码验证
        boolean checked = checkValidateCode(phone, valCode);
        // 验证不通过
        if (!checked) {
            throw new MyExceptin(StatusEnum.OPE_ERR);
        }
        // 验证通过
        return getMyuserByPhone(phone);
    }

    /**
     * 进行验证码校验
     *
     * @param phone
     * @param valCode
     * @return
     */
    private boolean checkValidateCode(String phone, String valCode) {
        ShardedJedis resource = jedisPool.getResource();
        String code = resource.get(RedisHeadInfo.CODE_HEAD + phone);
        if (code == null || valCode == null || !code.equals(valCode.trim())) {
            logger.info("验证码为空或验证码输入错误,操作账户为:" + phone + ",正确验证码为:" + code + ",用户输入的验证码为:" + valCode);
            resource.close();
            return false;
        }
        resource.close();
        return true;
    }

    /**
     * 检测是否是已注册用户。
     * 是的话,合法账户登录。执行登录逻辑
     * 否的话,注册新用户,并加标志表示这是一个新用户,执行登录逻辑,返回
     *
     * @param phone
     * @return
     */
    private Myuser getMyuserByPhone(String phone) {
        ShardedJedis resource = jedisPool.getResource();
        // 先查缓存中是否存有用户信息
        String userStr = resource.hget(RedisHeadInfo.LOGIN_KEY, phone);
        if (userStr != null) {
            logger.info("缓存中存有该用户信息");
            resource.close();
            return JSON.parseObject(userStr, Myuser.class);
        }
        // 缓存中没有用户信息,去数据库查找
        Myuser myuser = loginMapper.selectByPhone(phone);
        if (myuser == null) { // 说明是新用户,新插入一条数据,以默认值自动注册
            logger.info("数据库无此用户信息,自动注册");
            myuser = new Myuser();
            myuser.setUname("游客");
            myuser.setUpass("1234");
            myuser.setUphone(phone);
            loginMapper.insertMyuser(myuser);
            myuser.setNewuser("yes"); // 非数据库字段
        }
        // 将用户的登录信息存入redis
        resource.hset(RedisHeadInfo.LOGIN_KEY, phone, JSON.toJSONString(myuser));
        logger.info("将用户的登录信息存入了redis");
        resource.close();
        return myuser;
    }
}

RedisHeadInfo字段头

public interface RedisHeadInfo {
    String CODE_HEAD = "code:";
    String LOGIN_KEY = "loginUser";
}

总结

  • jedisPool总是需要关闭,可以引入redis的工具类,对每个方法做了简单封装,避免了繁琐的获取resource、关闭的操作;
  • 验证通过后的登录账户信息先查redis,练习时忘记了这一步;
  • 验证码暂存redis时候,value存为string类型,key为XXX:手机号,此格式会将验证码信息整理在XXX的文件夹下,便于统一管理;
  • 用户信息存redis时,value存为map类型,统一管理,同时取值可以根据key值取。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值