SpringBoot学习之旅(四)---MVC设计模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lupengfei1009/article/details/88020551

导读

本文基于以下文章开发:
SpringBoot学习之旅(二)—整合MyBatis(MyBatis Generator)
可优先读取该文章,快速搭建一个基于整合了mybatis的SpringBoot项目

源码地址

点击下载

前言

  • 何为MVC
    可参考mvc设计模式
  • 本文简介
    使用MVC设计模式,实现对用户注册及登录操作,从而演示整个业务的流程

目录结构完善

  • src/main/java/com.lupf.springboottest
    • controller
      控制器层
      • viewobject
        该目录为用于定义响应给前端的数据对象;由于业务对象中的数据可能存在部分敏感或者不需要返回给前端的对象,那么在该对象中将其剔除掉
    • dataobject
      数据模型对象,直接映射数据库的表的对象,这里的数据不会展示给用户;说通俗一点例子,这里就是我们裤衩子了,直接贴近我们的隐私部位(数据库数据),所以是不能给人看的;需要通过饰品(model)装饰之后,穿上衣服(View),才能展示个别人
    • service
      服务层
      • impl
        用于具体的service接口的实现
      • model
        业务模型对象
        与上面的dataobject对象不同的是,这里的对象是涉及到部分业务相关的业务对象,其中可能存在业务逻辑从而导致业务对象的结构与DO成的结构不一致的情况;如,用户和密码在DO成是2个对象,但是在业务层需要将其合并,因为用户信息和密码均属于用户相关信息

编码

Service层实现
  • service接口

    package com.lupf.springboottest.service;
    
    import com.lupf.springboottest.service.model.UserModel;
    
    /**
     * 用户的service接口
     */
    public interface UserService {
        /**
         * 根据用户id获取用户对象
         *
         * @param id
         */
        UserModel getUserBuId(Integer id)  throws BusiException;
    
        /**
         * 获取手机验证码
         *
         * @param phoneNum 用户手机号码
         */
        void getUserPhoneCode(String phoneNum)  throws BusiException;
    
        /**
         * 注册
         *
         * @param userModel
         * @return
         */
        UserModel register(UserModel userModel)  throws BusiException;
    
        /**
         * 登录
         *
         * @param phoneNum 电话
         * @param pwd      密码
         * @return
         */
        UserModel login(String phoneNum, String pwd)  throws BusiException;
    }
    
    
    • service实现需要做的事情
    package com.lupf.springboottest.service.impl;
    
    import com.lupf.springboottest.dao.UserDOMapper;
    import com.lupf.springboottest.dao.UserPasswordDOMapper;
    import com.lupf.springboottest.dataobject.UserDO;
    import com.lupf.springboottest.dataobject.UserPasswordDO;
    import com.lupf.springboottest.service.UserService;
    import com.lupf.springboottest.service.model.UserModel;
    import org.springframework.beans.BeanUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    @Service
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDOMapper userDOMapper;
    
        @Autowired
        private UserPasswordDOMapper userPasswordDOMapper;
    
        @Override
        @Transactional
        public UserModel getUserBuId(Integer id)  throws BusiException {
            //根据用户id获取用户信息
    
            //根据用户的id获取到用户的密码信息
    
            //将数据模型对象转换为领域模型对象
    
            //返回用户信息
            return null;
        }
    
        @Override
        public void getUserPhoneCode(String phoneNum)  throws BusiException {
            //校验手机号码的有效性
    
            //生成验证码
    
            //发送验证码
    
            //保存验证码
        }
    
        @Override
        public UserModel register(UserModel userModel)  throws BusiException {
            //校验前端上传的用户信息
    
            //校验验证码
    
            //校验密码的合法性
    
            //保存用户
    
            //保存密码
    
            //返回注册的用户信息
    
            //生成登录的唯一标识
    
            //返回用户信息
            return null;
        }
    
        @Override
        public UserModel login(String phoneNum, String pwd)  throws BusiException {
            //获取用户信息
    
            //校验用户密码
    
            //校验成功
    
            //生成登录的唯一标识
    
            //返回用户信息
            return null;
        }
    
  • Pom文件添加Lang包配置

            <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.7</version>
            </dependency>
    
  • Dao层添加根据电话号码获取用户信息(用于登录)
    UserDOMapper添加以下方法

        /**
         * 根据用户电话号码查询用户信息
         *
         * @param phoneNum
         * @return
         */
        UserDO selectByPhoneNum(String phoneNum);
    

    UserDOMapper.xml下添加以下配置

        <select id="selectByPhoneNum" parameterType="java.lang.String" resultMap="BaseResultMap">
            <!--
              WARNING - @mbg.generated
              This element is automatically generated by MyBatis Generator, do not modify.
              This element was generated on Thu Feb 28 16:27:46 CST 2019.
            -->
            select
            <include refid="Base_Column_List"/>
            from user_info
            where telphone = #{phoneNum,jdbcType=VARCHAR}
        </select>
    
  • service具体实现

    package com.lupf.springboottest.service.impl;
    
    import com.alibaba.druid.util.StringUtils;
    import com.lupf.springboottest.dao.UserDOMapper;
    import com.lupf.springboottest.dao.UserPasswordDOMapper;
    import com.lupf.springboottest.dataobject.UserDO;
    import com.lupf.springboottest.dataobject.UserPasswordDO;
    import com.lupf.springboottest.error.BusiErrCodeEm;
    import com.lupf.springboottest.error.BusiException;
    import com.lupf.springboottest.service.UserService;
    import com.lupf.springboottest.service.model.UserModel;
    import org.springframework.beans.BeanUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.dao.DuplicateKeyException;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import javax.servlet.http.HttpServletRequest;
    import java.util.Random;
    
    @Service
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDOMapper userDOMapper;
    
        @Autowired
        private UserPasswordDOMapper userPasswordDOMapper;
    
        @Autowired
        private HttpServletRequest httpServletRequest;
    
        @Override
        public UserModel getUserBuId(Integer id) throws BusiException {
            //根据用户id获取用户信息
            UserDO userDO = userDOMapper.selectByPrimaryKey(id);
    
            //根据用户的id获取到用户的密码信息
            UserPasswordDO userPasswordDO = null;
            if (null != userDO) {
                userPasswordDO = userPasswordDOMapper.selectByUserId(userDO.getId());
            }
    
            //将数据模型对象转换为领域模型对象
            UserModel userModel = userDOAndPasswordDO2UserModel(userDO, userPasswordDO);
    
            //返回用户信息
            return userModel;
        }
    
        @Override
        public void getUserPhoneCode(String phoneNum) throws BusiException {
            //校验手机号码的有效性
            //这里就不演示具体的校验规则了,网上很多
    
            //生成验证码
            Random random = new Random();
            //生个6位的随机数
            int code = random.nextInt(899999) + 100000;
    
            //发送验证码
            //这里发送验证码;可以使用三方的接口将验证码发送给用户
            //演示使用,这里就只做个打印
            System.out.println("验证码为:" + code);
    
            //保存验证码
            //为了方便测试,这里将验证码放在session里面
            //实际的开发过程中,可以将这个数据保存到redis中并且给这个数据设置一个有效期
            httpServletRequest.getSession().setAttribute(phoneNum, code);
        }
    
        @Override
        @Transactional
        public UserModel register(UserModel userModel) throws BusiException {
            //校验前端上传的用户信息
            if (null == userModel) {
                throw new BusiException(BusiErrCodeEm.REQ_PARAM_10001);
            }
    
            //校验密码的合法性
            //这里按各自的规则进行校验即可
            //这里不做演示
    
            UserDO userDO = userModel2UserDO(userModel);
            try {
                //保存用户
                //在mapper对应的方法下添加以下参数
                //这里很重要,否则添加之后userDO对象里面的id没有数据
                //keyProperty="id" useGeneratedKeys="true"
                userDOMapper.insertSelective(userDO);
    
                //保存密码
                //组装用户密码相关的对象
                UserPasswordDO userPasswordDO = new UserPasswordDO();
                //用户的索引ID
                userPasswordDO.setUserId(userDO.getId());
                //加密后的密码
                userPasswordDO.setEncrptPassword(userModel.getEncrptPassword());
                //添加用户密码数据
                userPasswordDOMapper.insertSelective(userPasswordDO);
            } catch (DuplicateKeyException e) {
                //用户号码是唯一键,如果存在,说明用户已经注册过了
                e.printStackTrace();
                throw new BusiException(BusiErrCodeEm.USER_20003);
            }
    
            //根据ID,重新获取一遍注册的用户信息并返回
            UserModel inserUserModel = this.getUserBuId(userDO.getId());
    
            //返回用户信息
            return inserUserModel;
        }
    
        @Override
        public UserModel login(String phoneNum, String encrptPassword) throws BusiException {
            //获取用户信息
            //根据用户的电话号码获取用户ID
            UserDO userDO = userDOMapper.selectByPhoneNum(phoneNum);
    
            //定义用户密码信息数据对象
            UserPasswordDO userPasswordDO = null;
    
            //判断该用户是否已经
            if (null != userDO) {
                userPasswordDO = userPasswordDOMapper.selectByUserId(userDO.getId());
            } else {
                throw new BusiException(BusiErrCodeEm.USER_20004);
            }
    
            //校验用户密码
            if (null == userPasswordDO || !StringUtils.equals(encrptPassword, userPasswordDO.getEncrptPassword())) {
                //这里提示用户名或者密码不正确是为了防止用户去不停尝试帐号密码
                throw new BusiException(BusiErrCodeEm.USER_20001, "用户名或者密码不正确");
            }
    
            //校验成功
            //将数据对象转换为领域模型对象
            UserModel userModel = this.userDOAndPasswordDO2UserModel(userDO, userPasswordDO);
            //返回用户信息
            return userModel;
        }
    
        /**
         * 将用户的DO对象和密码DO对象转换为用户业务对象
         *
         * @param userDO
         * @param userPasswordDO
         * @return
         */
        protected UserModel userDOAndPasswordDO2UserModel(UserDO userDO, UserPasswordDO userPasswordDO) {
            if (null == userDO)
                return null;
    
            UserModel userModel = new UserModel();
            BeanUtils.copyProperties(userDO, userModel);
            if (null != userPasswordDO) {
                userModel.setEncrptPassword(userPasswordDO.getEncrptPassword());
            }
            return userModel;
        }
    
        /**
         * 将领域模型对象转换为数据对象
         *
         * @param userModel
         * @return
         */
        public UserDO userModel2UserDO(UserModel userModel) {
            UserDO userDO = new UserDO();
            BeanUtils.copyProperties(userModel, userDO);
            return userDO;
        }
    }
    
    
  • Controller代码实现

    package com.lupf.springboottest.controller;
    
    
    import com.lupf.springboottest.controller.viewobject.UserVO;
    import com.lupf.springboottest.dao.UserDOMapper;
    import com.lupf.springboottest.error.BusiErrCodeEm;
    import com.lupf.springboottest.error.BusiException;
    import com.lupf.springboottest.response.BaseRespObj;
    import com.lupf.springboottest.service.UserService;
    import com.lupf.springboottest.service.model.UserModel;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.BeanUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import sun.misc.BASE64Encoder;
    
    import javax.servlet.http.HttpServletRequest;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    @RestController
    @RequestMapping("/user")
    public class UserController extends BaseController {
    
        @Autowired
        UserDOMapper userDOMapper;
    
    
        @Autowired
        private UserService userService;
    
        @Autowired
        private HttpServletRequest httpServletRequest;
    
        /**
         * 获取用户验证码
         *
         * @param phoneNum 用户号码
         * @return
         * @throws BusiException
         */
        @RequestMapping(value = "/getPhoneCode", method = RequestMethod.POST)
        public BaseRespObj getUserByID(@RequestParam(name = "phoneNum") String phoneNum) throws BusiException {
            userService.getUserPhoneCode(phoneNum);
            return BaseRespObj.create(null);
        }
    
        /**
         * 注册
         *
         * @param name     用户昵称
         * @param phoneNum 用户号码
         * @param code     用户验证码
         * @param age      年龄
         * @param sex      性别
         * @param email    邮箱
         * @param pwd      密码
         * @return
         * @throws Exception
         */
        @RequestMapping(value = "/register", method = RequestMethod.POST)
        public BaseRespObj register(
                @RequestParam(name = "name") String name,
                @RequestParam(name = "phoneNum") String phoneNum,
                @RequestParam(name = "phoneCode") Integer code,
                @RequestParam(name = "age") Integer age,
                @RequestParam(name = "sex") String sex,
                @RequestParam(name = "email") String email,
                @RequestParam(name = "pwd") String pwd) throws Exception {
    
            //将前端数据转换为领域模型对象
            UserModel userModel = new UserModel();
            userModel.setAge(age);
            userModel.setSex(Byte.valueOf(sex));
            userModel.setEmail(email);
            userModel.setName(name);
            userModel.setTelphone(phoneNum);
    
            //在session中取出前面发送的验证码
            Integer sessCode = (Integer) httpServletRequest.getSession().getAttribute(phoneNum);
    
            if (null == sessCode || sessCode.intValue() != code.intValue()) {
                throw new BusiException(BusiErrCodeEm.REQ_PARAM_10001, "短信验证码信息有误!");
            }
    
            userModel.setEncrptPassword(this.encodeByMD5(pwd));
            userModel.setRegisterMode("bytelphone");
            UserModel insertUserModel = userService.register(userModel);
            UserVO userVO = userModel2UserVO(insertUserModel);
    
            return BaseRespObj.create(userVO);
        }
    
        /**
         * 登录
         *
         * @param phoneNum 用户电话号码
         * @param pwd      用户密码
         * @return
         * @throws Exception
         */
        @RequestMapping(value = "/login", method = RequestMethod.POST)
        public BaseRespObj login(
                @RequestParam(name = "phoneNum") String phoneNum,
                @RequestParam(name = "pwd") String pwd) throws Exception {
    
            if (StringUtils.isEmpty(phoneNum) || StringUtils.isEmpty(pwd)) {
                throw new BusiException(BusiErrCodeEm.REQ_PARAM_10001);
            }
    
            UserModel userModel = userService.login(phoneNum, this.encodeByMD5(pwd));
            UserVO userVO = userModel2UserVO(userModel);
            return BaseRespObj.create(userVO);
        }
    
    
        /**
         * 将用户业务对象转为前端的视图对象
         *
         * @param userModel 业务模型对象
         * @return 前端视图对象
         */
        protected UserVO userModel2UserVO(UserModel userModel) {
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(userModel, userVO);
            return userVO;
        }
    
        /**
         * MD5加密
         *
         * @param va 待加密的数据
         * @return 加密后的数据
         * @throws NoSuchAlgorithmException
         */
        protected String encodeByMD5(String va) throws NoSuchAlgorithmException {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            BASE64Encoder base64Encoder = new BASE64Encoder();
            String newVa = base64Encoder.encode(md5.digest(va.getBytes()));
            return newVa;
        }
    }
    
    

测试

  • 获取验证码
    127.0.0.1:8082/user/getPhoneCode?phoneNum=13888888888

  • 用户注册

    • 成功
    • 失败
  • 用户登录

    • 成功
    • 失败

到此一个基础的基于SpringMvc的项目即搭建完成

猜你喜欢

转载自blog.csdn.net/lupengfei1009/article/details/88020551