美文网首页
5.用户管理模块

5.用户管理模块

作者: 惜小八 | 来源:发表于2020-05-20 21:28 被阅读0次

    该模块主要有十个子模块:注册、登陆、用户名/邮箱验证、获取登陆用户信息、登陆状态重置密码、登陆状态下更新用户信息、忘记密码、提交问题答案、重置密码、退出。

    1.MD5代码

    用户的密码使用MD5加密后存储在数据库当中

    package com.mall.util;
    
    import org.springframework.util.StringUtils;
    import java.security.MessageDigest;
    
    
    public class MD5Util {
    
        //内部使用的加密算法
        private static String byteArrayToHexString(byte b[]) {
            StringBuffer resultSb = new StringBuffer();
            for (int i = 0; i < b.length; i++)
                resultSb.append(byteToHexString(b[i]));
            return resultSb.toString();
        }
        //内部使用的加密算法
        private static String byteToHexString(byte b) {
            int n = b;
            if (n < 0)
                n += 256;
            int d1 = n / 16;
            int d2 = n % 16;
            return hexDigits[d1] + hexDigits[d2];
        }
    
    
        /**
         * 返回大写MD5,origin表示原密码
         */
        private static String MD5Encode(String origin, String charsetname) {
            String resultString = null;
            try {
                resultString = new String(origin);
                MessageDigest md = MessageDigest.getInstance("MD5");
                if (charsetname == null || "".equals(charsetname))
                    resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
                else
                    resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
            } catch (Exception exception) {
            }
            return resultString.toUpperCase();
        }
    
        public static String MD5EncodeUtf8(String origin) {
            /**
             * 使用下面的句子来进行加盐,直接返回则表示不加盐MD5
             */
            origin = origin + PropertiesUtil.getProperty("password.salt", "");
            return MD5Encode(origin, "utf-8");
        }
    
    
        private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
                "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
    
    }
    **********************PropertiesUtil*****************
    package com.mall.util;
    
    import org.apache.commons.lang3.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.Properties;
    
    /**
     * Created by geely
     */
    public class PropertiesUtil {
    
        private static Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);
    
        private static Properties props;
        /**
         * PropertiesUtil的实现:要求在Tomcat启动的时候读取到其中的内容
         * 所以此处使用静态块来实现,当该类被Java的类加载器加载的时候,就会首先执行static
         */
        static {
            String fileName = "mall.properties";
            props = new Properties();
            try {
                props.load(new InputStreamReader(PropertiesUtil.class.getClassLoader().getResourceAsStream(fileName),"UTF-8"));
            } catch (IOException e) {
                logger.error("配置文件读取异常",e);
            }
        }
    
        public static String getProperty(String key){
            String value = props.getProperty(key.trim());
            if(StringUtils.isBlank(value)){
                return null;
            }
            return value.trim();
        }
    
        public static String getProperty(String key,String defaultValue){
    
            String value = props.getProperty(key.trim());
            if(StringUtils.isBlank(value)){
                value = defaultValue;
            }
            return value.trim();
        }
    }
    *************mall.properties***********
    password.salt = geelysdafaqj23ou89ZXcj@#$@#$#@KJdjklj;D../dSF.,
    

    2.忘记密码,重置密码时回答问题的答案有效时间

    在忘记密码时,一般会有提示问题,通过回答提示问题进行密码的重置,一般在回答问题之后,这个答案在一段时间内时有效的,此处使用google的CacheLoader来存储问题答案的有效时间。

    package com.mall.common;
    
    import com.google.common.cache.CacheBuilder;
    import com.google.common.cache.CacheLoader;
    import com.google.common.cache.LoadingCache;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.util.concurrent.TimeUnit;
    
    public class TokenCache {
    
        //日志打印对象
        private static Logger logger= LoggerFactory.getLogger(TokenCache.class);
        public static final String TOKEN_PREFIX="token_";
        /**
         * maximumSize:当缓存大大小超过10000的时候会采用最少使用算法,将缓存移除,
         * expireAfterAccess:缓存的有效时间是12小时
         * build:缓存的实现,此处使用匿名实现
         */
        private static LoadingCache localCache= CacheBuilder.newBuilder().initialCapacity(1000).maximumSize(1000)
                .expireAfterAccess(12, TimeUnit.HOURS)
                .build(new CacheLoader<String, String>() {
                    //缓存默认的数据加载实现,当调用get取之的时候,如果key没有对应的值,就调用这个方法进行加载
                    @Override
                    public String load(String key) throws Exception {
                        return "null";
                    }
                });
        //提供外界的方法
        public static void setKey(String key,String value){
            localCache.put(key,value);
        }
        public static String getKey(String key){
            String value=null;
            try {
                value= (String) localCache.get(key);
                if("null".equals(value)){
                    return null;
                }
                return value;
            }catch (Exception e){
                logger.info("cache get error",e);
            }
            return null;
        }
    }
    

    3.用户管理模块接口(Controller)

    package com.mall.controller.portal;
    
    import com.mall.common.Const;
    import com.mall.common.ResponseCode;
    import com.mall.common.ServerResponse;
    import com.mall.pojo.User;
    import com.mall.service.IUserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.servlet.http.HttpSession;
    
    @Controller
    @RequestMapping("/user/")
    public class UserController {
        @Autowired
        private IUserService iUserService;
    
        @RequestMapping(value = "login.do",method = RequestMethod.POST)
        @ResponseBody
        public ServerResponse<User> login(String username, String password, HttpSession session){
            ServerResponse<User> serverResponse=iUserService.login(username, password);
            if(serverResponse.isSuccess()){
                session.setAttribute(Const.CURRENT_USER,serverResponse.getData());
            }
            return serverResponse;
        }
    
        @ResponseBody
        @RequestMapping(value = "logout.do")
        public ServerResponse logout(HttpSession session){
            session.removeAttribute(Const.CURRENT_USER);
            return ServerResponse.createBySuccess();
        }
    
        @ResponseBody
        @RequestMapping(value = "register.do",method = RequestMethod.POST)
        public ServerResponse<String> register(User user){
            return iUserService.register(user);
        }
    
        @ResponseBody
        @RequestMapping(value = "check_valid.do",method = RequestMethod.POST)
        public ServerResponse<String> checkValid(String str,String type){
            return iUserService.checkedValid(str, type);
        }
        //获取登陆用户的信息
        @ResponseBody
        @RequestMapping("get_user_information.do")
        public ServerResponse<User> getUserInformation(HttpSession session){
            User user=(User)session.getAttribute(Const.CURRENT_USER);
            if(user==null){
                return ServerResponse.createByErrorCodeMsg(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getMsg());
            }
            return ServerResponse.createBySuccess(user);
        }
        //更新用户信息,然后存放在session当中
        @ResponseBody
        @RequestMapping("update_user_information.do")
        public ServerResponse<User> updateUserInformation(HttpSession session,User updateUser){
            User user=(User)session.getAttribute(Const.CURRENT_USER);
            if(user==null){
                return ServerResponse.createByErrorCodeMsg(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getMsg());
            }
            updateUser.setId(user.getId());
            updateUser.setUsername(user.getUsername());
            ServerResponse serverResponse=iUserService.updateInformation(updateUser);
            if(serverResponse.isSuccess()){
                session.setAttribute(Const.CURRENT_USER,serverResponse.getData());
            }
            return serverResponse;
        }
    
        @ResponseBody
        @RequestMapping(value = "rest_password.do",method = RequestMethod.POST)
        public ServerResponse<User> restPassword(HttpSession session,String oldPassword,String newPassword){
            User user=(User)session.getAttribute(Const.CURRENT_USER);
            if(user==null){
                return ServerResponse.createByErrorCodeMsg(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getMsg());
            }
            return iUserService.restPassword(user.getUsername(),oldPassword,newPassword);
        }
    
    
        //忘记密码:第一步,获取重置密码问题
        @ResponseBody
        @RequestMapping(value = "forget_get_question.do",method = RequestMethod.POST)
        public ServerResponse<String> forgetGetQuestion(String username){
            return iUserService.forgetGetQuestion(username);
        }
        //忘记密码:第二步,检测问题的答案,返回token
        @ResponseBody
        @RequestMapping(value = "forget_checked_answer.do",method = RequestMethod.POST)
        public ServerResponse<String> forgetCheckedAnswer(String username,String question,String answer){
            return iUserService.forgetCheckedAnswer(username, question, answer);
        }
    
        //忘记密码:第三步,重置密码
        @ResponseBody
        @RequestMapping("forget_rest_password.do")
        public ServerResponse<String> forgetRestPassword(String username,String password,String token){
            return iUserService.forgetRestPassword(username, password, token);
        }
    }
    
    

    4.用户管理模块接口(service)

    package com.mall.service.impl;
    
    import com.mall.common.Const;
    import com.mall.common.ServerResponse;
    import com.mall.common.TokenCache;
    import com.mall.dao.UserMapper;
    import com.mall.pojo.User;
    import com.mall.service.IUserService;
    import com.mall.util.MD5Util;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.UUID;
    
    
    @Service("iUserService")
    public class UserServiceImpl implements IUserService {
    
        @Autowired
        private UserMapper userMapper;
        //校验用户名和密码
        public ServerResponse<User> login(String username, String password){
            int rowCount=userMapper.checkUsername(username);
            if(rowCount==0){
                return ServerResponse.createByErrorMsg("用户不存在");
            }
            //MD5
            password= MD5Util.MD5EncodeUtf8(password);
            User user = userMapper.checkUserPassword(username, password);
            if(user==null){
                return ServerResponse.createByErrorMsg("密码错误");
            }
            user.setPassword(StringUtils.EMPTY);
            return ServerResponse.createBySuccess(user);
        }
        //校验用户名和邮箱,然后查用User到数据库
        public ServerResponse<String>  register(User user){
            ServerResponse validResponse=this.checkedValid(user.getUsername(), Const.USERNAME);
            if(!validResponse.isSuccess()){
                return validResponse;
            }
            validResponse=this.checkedValid(user.getEmail(),Const.EMAIL);
            if(!validResponse.isSuccess()){
                return validResponse;
            }
            user.setRole(Const.Role.ROLE_CUSTOMER);
            //MD5
            user.setPassword(MD5Util.MD5EncodeUtf8(user.getPassword()));
            int rowCount=userMapper.insert(user);
            if(rowCount>0){
                return ServerResponse.createBySuccessMsg("注册成功");
            }
            return ServerResponse.createByErrorMsg("注册失败");
        }
        //检查用户名和邮箱的有效性,校验成功则用户名密码不存在
        public ServerResponse<String> checkedValid(String str,String type){
            if(StringUtils.isBlank(type)){
                return ServerResponse.createByErrorMsg("参数错误");
            }
            if(Const.USERNAME.equals(type)){
                int rowCount=userMapper.checkUsername(str);
                if(rowCount>0){
                    return ServerResponse.createByErrorMsg("用户已存在");
                }
            }
            if(Const.EMAIL.equals(type)){
                int rowCount=userMapper.checkEmail(str);
                if(rowCount>0){
                    return ServerResponse.createByErrorMsg("邮箱已存在");
                }
            }
            return ServerResponse.createBySuccessMsg("校验成功,用户名、邮箱不存在");
        }
        //检查用户和旧密码,更新新密码
        public ServerResponse<User> restPassword(String username,String oldPassword,String newPassword){
            User user=userMapper.checkUserPassword(username,MD5Util.MD5EncodeUtf8(oldPassword));
            if(user==null){
                return ServerResponse.createBySuccessMsg("旧密码错误");
            }
            user.setPassword(MD5Util.MD5EncodeUtf8(newPassword));
            int rowCount=userMapper.updateByPrimaryKeySelective(user);
            user.setPassword(StringUtils.EMPTY);
            if(rowCount>0){
                return ServerResponse.createBySuccess(user);
            }
            return ServerResponse.createByError();
        }
        //更新用户的个人信息
        public ServerResponse<User> updateInformation(User updateUser){
            int rowCount=userMapper.checkEmailByUserId(updateUser.getEmail(),updateUser.getId());
            if(rowCount>0){
                return ServerResponse.createByErrorMsg("email已存在");
            }
            User endUpdateUser=new User();
            endUpdateUser.setId(updateUser.getId());
            endUpdateUser.setUsername(updateUser.getUsername());
            endUpdateUser.setEmail(updateUser.getEmail());
            endUpdateUser.setQuestion(updateUser.getQuestion());
            endUpdateUser.setAnswer(updateUser.getAnswer());
            rowCount=userMapper.updateByPrimaryKeySelective(endUpdateUser);
            if (rowCount>0){
                return ServerResponse.createBySuccess("更新个人信息成功",endUpdateUser);
            }
            return ServerResponse.createByErrorMsg("更新用户信息失败");
        }
        //使用用户名获取问题,将问题返回给前端
        public ServerResponse<String> forgetGetQuestion(String username){
            ServerResponse validResponse=this.checkedValid(username,Const.USERNAME);
            if(validResponse.isSuccess()){
                return ServerResponse.createByErrorMsg("该用户不存在");
            }
            String question=userMapper.checkQuestionByUsername(username);
            if(StringUtils.isNotBlank(question)){
                return ServerResponse.createBySuccess(question);
            }
            return ServerResponse.createBySuccessMsg("找回密码的问题是空的");
        }
        //检查问题的答案是否正确,设置token并返回给前端
        public ServerResponse<String> forgetCheckedAnswer(String username,String question,String answer){
            int rowCount=userMapper.checkAnswerByUsernameAndQuestion(username,question,answer);
            if(rowCount==0){
                return ServerResponse.createByErrorMsg("问题答案错误");
            }
            //设置token:问题的答案的有效时间
            //key:"token_"+username    value:forgetToken
            String token= UUID.randomUUID().toString();
            TokenCache.setKey(TokenCache.TOKEN_PREFIX+username,token);
            return ServerResponse.createBySuccess("问题答案校验成功",token);
        }
    
        //检测用户名和token,检测token是否正确,更新密码
        public ServerResponse<String> forgetRestPassword(String username,String password,String token){
            ServerResponse response=this.checkedValid(username,Const.USERNAME);
            if(response.isSuccess()){
                ServerResponse.createByErrorMsg("该用户不存在");
            }
            if(StringUtils.isBlank(token)){
                return ServerResponse.createByErrorMsg("Token无效过着过期");
            }
            if(TokenCache.getKey(TokenCache.TOKEN_PREFIX+username).equals(token)){
    
                int rowCount=userMapper.updatePasswordByUsername(username,MD5Util.MD5EncodeUtf8(password));
                if(rowCount>0){
                    return ServerResponse.createBySuccessMsg("密码重置成功");
                }
                return ServerResponse.createByErrorMsg("密码重置失败");
            }
            return ServerResponse.createByErrorMsg("Token错误,重置密码失败");
        }
    
        public ServerResponse<String> checkUserRole(User user){
            if(user != null && user.getRole()==Const.Role.ROLE_ADMIN){
                return ServerResponse.createBySuccess("用户是管理员,登陆成功");
            }
            return ServerResponse.createByErrorMsg("用户不是管理员,登陆失败");
        }
    }
    

    5.用户管理模块(xml)

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="com.mall.dao.UserMapper" >
      <resultMap id="BaseResultMap" type="com.mall.pojo.User" >
        <constructor >
          <idArg column="id" jdbcType="INTEGER" javaType="java.lang.Integer" />
          <arg column="username" jdbcType="VARCHAR" javaType="java.lang.String" />
          <arg column="password" jdbcType="VARCHAR" javaType="java.lang.String" />
          <arg column="email" jdbcType="VARCHAR" javaType="java.lang.String" />
          <arg column="phone" jdbcType="VARCHAR" javaType="java.lang.String" />
          <arg column="question" jdbcType="VARCHAR" javaType="java.lang.String" />
          <arg column="answer" jdbcType="VARCHAR" javaType="java.lang.String" />
          <arg column="role" jdbcType="INTEGER" javaType="java.lang.Integer" />
          <arg column="create_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />
          <arg column="update_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />
        </constructor>
      </resultMap>
      <sql id="Base_Column_List" >
        id, username, password, email, phone, question, answer, role, create_time, update_time
      </sql>
      <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
        select 
        <include refid="Base_Column_List" />
        from mmall_user
        where id = #{id,jdbcType=INTEGER}
      </select>
      <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
        delete from mmall_user
        where id = #{id,jdbcType=INTEGER}
      </delete>
      <insert id="insert" parameterType="com.mall.pojo.User" >
        insert into mmall_user (id, username, password, 
          email, phone, question, 
          answer, role, create_time, 
          update_time)
        values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
          #{email,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR}, #{question,jdbcType=VARCHAR}, 
          #{answer,jdbcType=VARCHAR}, #{role,jdbcType=INTEGER}, now(),
          now())
      </insert>
      <insert id="insertSelective" parameterType="com.mall.pojo.User" >
        insert into mmall_user
        <trim prefix="(" suffix=")" suffixOverrides="," >
          <if test="id != null" >
            id,
          </if>
          <if test="username != null" >
            username,
          </if>
          <if test="password != null" >
            password,
          </if>
          <if test="email != null" >
            email,
          </if>
          <if test="phone != null" >
            phone,
          </if>
          <if test="question != null" >
            question,
          </if>
          <if test="answer != null" >
            answer,
          </if>
          <if test="role != null" >
            role,
          </if>
          <if test="createTime != null" >
            create_time,
          </if>
          <if test="updateTime != null" >
            update_time,
          </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides="," >
          <if test="id != null" >
            #{id,jdbcType=INTEGER},
          </if>
          <if test="username != null" >
            #{username,jdbcType=VARCHAR},
          </if>
          <if test="password != null" >
            #{password,jdbcType=VARCHAR},
          </if>
          <if test="email != null" >
            #{email,jdbcType=VARCHAR},
          </if>
          <if test="phone != null" >
            #{phone,jdbcType=VARCHAR},
          </if>
          <if test="question != null" >
            #{question,jdbcType=VARCHAR},
          </if>
          <if test="answer != null" >
            #{answer,jdbcType=VARCHAR},
          </if>
          <if test="role != null" >
            #{role,jdbcType=INTEGER},
          </if>
          <if test="createTime != null" >
            now(),
          </if>
          <if test="updateTime != null" >
            now(),
          </if>
        </trim>
      </insert>
      <update id="updateByPrimaryKeySelective" parameterType="com.mall.pojo.User" >
        update mmall_user
        <set >
          <if test="username != null" >
            username = #{username,jdbcType=VARCHAR},
          </if>
          <if test="password != null" >
            password = #{password,jdbcType=VARCHAR},
          </if>
          <if test="email != null" >
            email = #{email,jdbcType=VARCHAR},
          </if>
          <if test="phone != null" >
            phone = #{phone,jdbcType=VARCHAR},
          </if>
          <if test="question != null" >
            question = #{question,jdbcType=VARCHAR},
          </if>
          <if test="answer != null" >
            answer = #{answer,jdbcType=VARCHAR},
          </if>
          <if test="role != null" >
            role = #{role,jdbcType=INTEGER},
          </if>
          <if test="createTime != null" >
            create_time = #{createTime,jdbcType=TIMESTAMP},
          </if>
          <if test="updateTime != null" >
            update_time = now(),
          </if>
        </set>
        where id = #{id,jdbcType=INTEGER}
      </update>
      <update id="updateByPrimaryKey" parameterType="com.mall.pojo.User" >
        update mmall_user
        set username = #{username,jdbcType=VARCHAR},
          password = #{password,jdbcType=VARCHAR},
          email = #{email,jdbcType=VARCHAR},
          phone = #{phone,jdbcType=VARCHAR},
          question = #{question,jdbcType=VARCHAR},
          answer = #{answer,jdbcType=VARCHAR},
          role = #{role,jdbcType=INTEGER},
          create_time = #{createTime,jdbcType=TIMESTAMP},
          update_time = now()
        where id = #{id,jdbcType=INTEGER}
      </update>
    
      <select id="checkUsername" parameterType="string" resultType="int">
        select COUNT(1) from mmall_user where username = #{username}
      </select>
      <select id="checkEmail" parameterType="string" resultType="int">
        select count(1) from mmall_user where email=#{email}
      </select>
      <select id="checkUserPassword" parameterType="map" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from mmall_user
        where username = #{username} and password=#{password}
      </select>
    
      <select id="checkEmailByUserId" parameterType="map" resultType="int">
        select count(1) from mmall_user where id=#{userId} and email=#{email}
      </select>
    
      <select id="checkQuestionByUsername" parameterType="string" resultType="string">
        select question from mmall_user where username=#{username}
      </select>
    
      <select id="checkAnswerByUsernameAndQuestion" parameterType="map" resultType="int">
        select count(1) from mmall_user where username=#{username} and question=#{question} and answer=#{answer}
      </select>
    
      <update id="updatePasswordByUsername" parameterType="map">
        update mmall_user
        set password=#{password},update_time=now()
        where username=#{username}
      </update>
    </mapper>
    

    相关文章

      网友评论

          本文标题:5.用户管理模块

          本文链接:https://www.haomeiwen.com/subject/wewbohtx.html