• 2、点评搜索服务&推荐系统 -用户模块


    一、用户服务搭建
    用户业务模型后端服务:

    1. 用户注册,由于手机号的唯一性,最靠谱的就是使用数据库的唯一索引保证,同时catch duplicatedkey异常,抛出有意义的手机号已注册异常
    2. 用户注册,使用密码加密的方式以秘文方式入库,保证用户信息的安全性
    3. 用户登录,通过无状态的http session机制,通过cookie传递sessionId信息并保存登录凭证

    实现用户的登录注册登出服务

    点评dianpingdb数据库 用户表user

    /*
     Navicat Premium Data Transfer
    
     Source Server         : 本地测试
     Source Server Type    : MySQL
     Source Server Version : 50728
     Source Host           : localhost:3306
     Source Schema         : dianpingdb
    
     Target Server Type    : MySQL
     Target Server Version : 50728
     File Encoding         : 65001
    
     Date: 05/05/2020 12:53:23
    */
    
    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;
    
    -- ----------------------------
    -- Table structure for user
    -- ----------------------------
    DROP TABLE IF EXISTS `user`;
    CREATE TABLE `user`  (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `created_at` datetime(0) NOT NULL,
      `updated_at` datetime(0) NOT NULL,
      `telphone` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
      `password` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
      `nick_name` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
      `gender` int(11) NOT NULL DEFAULT 0,
      PRIMARY KEY (`id`) USING BTREE,
      UNIQUE INDEX `telphone_unique_index`(`telphone`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Records of user
    -- ----------------------------
    INSERT INTO `user` VALUES (1, '2020-02-01 11:46:46', '2020-05-05 11:46:56', '10987654321', '123456', '菜鸡文', 1);
    
    SET FOREIGN_KEY_CHECKS = 1;
    
    

    实现用户的登录注册服务

    • 用户服务

    • 用户模型

    • 用户行为 - 登录注册

    • 用户登录态管理

    可用代码生成器mybatis-generator自动生成,生成PO类,生成mapper映射文件(其中包括基本的增删改查功能)、生成mapper接口等。要做些修改,添加下自己需要的功能或删除自己不需要的功能即可。mybatis-generator.xml

    实现用户的登录注册服务

    在src/main/java目录下,创建一个com.awen.dianping.service包,并在包中创建接口UserService,接口中定义一系列方法,代码如下所示。

    interface UserService.java

    public interface UserService {
    
        UserModel getUser(Integer id);
    
        UserModel register(UserModel registerUser) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException;
    
        UserModel login(String telphone,String password) throws UnsupportedEncodingException, NoSuchAlgorithmException, BusinessException;
    
        Integer countAllUser();
    }
    
    

    在src/main/java目录下,创建一个com.awen.dianping.dal包,并在包中创建接口UserModelMapper,接口中定义一系列方法,代码如下所示。

    UserModelMapper.java

    public interface UserModelMapper {
       
        int deleteByPrimaryKey(Integer id);
    
        int insert(UserModel record);
       
        int insertSelective(UserModel record);
        
        UserModel selectByPrimaryKey(Integer id);
    
        UserModel selectByTelphoneAndPassword(@Param("telphone") String telphone, @Param("password")String password);
       
        int updateByPrimaryKeySelective(UserModel record);
        
        int updateByPrimaryKey(UserModel record);
    
        Integer countAllUser();
    }
    

    在src/main/resources/mapping目录下,UserModelMapper.xml 代码生成就不写了,加了点添自己需要的功能,最后有源码。

    在com.awen.dianping.service包下,创建UserService接口的实现类UserServiceImpl,该类需要实现接口中的所有方法,代码如下所示。

    @Service
    public class UserServiceImpl implements UserService {
    
        @Autowired
        private UserModelMapper userModelMapper;
    
    
        @Override
        public UserModel getUser(Integer id) {
            return userModelMapper.selectByPrimaryKey(id);
        }
    
        @Override
        @Transactional
        public UserModel register(UserModel registerUser) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
            registerUser.setPassword(encodeByMd5(registerUser.getPassword()));
            registerUser.setCreatedAt(new Date());
            registerUser.setUpdatedAt(new Date());
    
            try{
                userModelMapper.insertSelective(registerUser);
            }catch (DuplicateKeyException ex){
                throw new BusinessException(EmBusinessError.REGISTER_DUP_FAIL);
            }
    
            return getUser(registerUser.getId());
        }
    
        @Override
        public UserModel login(String telphone, String password) throws UnsupportedEncodingException, NoSuchAlgorithmException, BusinessException {
            UserModel userModel = userModelMapper.selectByTelphoneAndPassword(telphone,encodeByMd5(password));
            if(userModel == null){
                throw new BusinessException(EmBusinessError.LOGIN_FAIL);
            }
            return userModel;
        }
    
        @Override
        public Integer countAllUser() {
            return userModelMapper.countAllUser();
        }
    
        private String encodeByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
            //确认计算方法MD5
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            BASE64Encoder base64Encoder = new BASE64Encoder();
            return base64Encoder.encode(messageDigest.digest(str.getBytes("utf-8")));
    
        }
    }
    
    

    在com.awen.dianping.request包下,创建LoginReq,RegisterReq封装登录、注册请求数据,代码如下所示。

    RegisterReq

    public class RegisterReq {
    
        @NotBlank(message = "手机号不能为空")
        private String telphone;
        @NotBlank(message = "密码不能为空")
        private String password;
        @NotBlank(message = "昵称不能为空")
        private String nickName;
    
        @NotNull(message = "性别不能为空")
        private Integer gender;
    
        public String getTelphone() {
            return telphone;
        }
    
        public void setTelphone(String telphone) {
            this.telphone = telphone;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getNickName() {
            return nickName;
        }
    
        public void setNickName(String nickName) {
            this.nickName = nickName;
        }
    
        public Integer getGender() {
            return gender;
        }
    
        public void setGender(Integer gender) {
            this.gender = gender;
        }
    }
    
    

    LoginReq.java

    public class LoginReq {
        @NotBlank(message = "手机号不能为空")
        private String telphone;
        @NotBlank(message = "密码不能为空")
        private String password;
    
        public String getTelphone() {
            return telphone;
        }
    
        public void setTelphone(String telphone) {
            this.telphone = telphone;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    }
    
    

    在com.awen.dianping.controller包下,创建UserController,代码如下所示。

    UserController.java

    @Controller("/user")
    @RequestMapping("/user")
    public class UserController {
    
        public static final String CURRENT_USER_SESSION = "currentUserSession";
    
        @Autowired
        private HttpServletRequest httpServletRequest;
    
        @Autowired
        private UserService userService;
    
        //get用户信息
        @RequestMapping("/get")
        @ResponseBody
        public CommonRes getUser(@RequestParam(name="id")Integer id) throws BusinessException {
            UserModel userModel = userService.getUser(id);
            if(userModel == null){
                //return CommonRes.create(new CommonError(EmBusinessError.NO_OBJECT_FOUND),"fail");
                throw new BusinessException(EmBusinessError.NO_OBJECT_FOUND);
            }else{
                return CommonRes.create(userModel);
            }
    
        }
    
        //注册
        @RequestMapping("/register")
        @ResponseBody
        public CommonRes register(@Valid @RequestBody RegisterReq registerReq, BindingResult bindingResult) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
            if(bindingResult.hasErrors()){
                throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, CommonUtil.processErrorString(bindingResult));
            }
    
            UserModel registerUser = new UserModel();
            registerUser.setTelphone(registerReq.getTelphone());
            registerUser.setPassword(registerReq.getPassword());
            registerUser.setNickName(registerReq.getNickName());
            registerUser.setGender(registerReq.getGender());
    
            UserModel resUserModel = userService.register(registerUser);
    
            return CommonRes.create(resUserModel);
        }
        //登录
        @RequestMapping("/login")
        @ResponseBody
        public CommonRes login(@RequestBody @Valid LoginReq loginReq,BindingResult bindingResult) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
            if(bindingResult.hasErrors()){
                throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,CommonUtil.processErrorString(bindingResult));
            }
            UserModel userModel = userService.login(loginReq.getTelphone(),loginReq.getPassword());
            httpServletRequest.getSession().setAttribute(CURRENT_USER_SESSION,userModel);
    
            return CommonRes.create(userModel);
        }
        //注销
        @RequestMapping("/logout")
        @ResponseBody
        public CommonRes logout() throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
            httpServletRequest.getSession().invalidate();
            return CommonRes.create(null);
        }
    
        //获取当前用户信息
        @RequestMapping("/getcurrentuser")
        @ResponseBody
        public CommonRes getCurrentUser(){
            UserModel userModel = (UserModel) httpServletRequest.getSession().getAttribute(CURRENT_USER_SESSION);
            return CommonRes.create(userModel);
        }
    }
    
    

    运行测试

    在这里插入图片描述

    GET http://localhost:8010/user/get?id=1

    在这里插入图片描述

    POST 注册 http://localhost:8080/user/register

    在这里插入图片描述

    POST 登录 http://localhost:8080/user/login

    在这里插入图片描述

    GET 获取当前用户信息 http://localhost:8080/user/getcurrentuser

    在这里插入图片描述

    GET 退出 http://localhost:8080/user/logout

    在这里插入图片描述

    代码 Github:https://github.com/liuawen/dianping

    SpringBoot、ElasticSearch、Spark 完成一个点评搜索推荐项目 用户服务

  • 相关阅读:
    【linux基础err】bash: cannot create temp file for here-document: No space left on device
    【python基础】argparse模块
    第23课 优先选用make系列函数
    第22课 weak_ptr弱引用智能指针
    第21课 shared_ptr共享型智能指针
    第20课 unique_ptr独占型智能指针
    第19课 lambda vs std::bind
    第18课 捕获机制及陷阱
    第17课 lambda表达式
    第16课 处理万能引用和重载的关系
  • 原文地址:https://www.cnblogs.com/liuawen/p/12854020.html
Copyright © 2020-2023  润新知