baihua1113
2021-06-30 17:11
采纳率: 100%
浏览 127
已采纳

学习龙虾三少springboot+mybatis 一切运行顺畅但数据库不增加数据

开发环境 IntelliJ IDEA 2021.1.2 mysql 5.7 本机安装 前端 andriod sudio4.21

问题:注册成功但是数据库不增加记录,搞不清楚问题在哪 #代码全程copy,一点点学的,springboot正常启动,数据库连接正常 前端注册电话号码,数据库中有一样的号码,正常显示了重复注册

img 证明前端可以联络到数据库,并且查询到了数据库中有重复数据,返回了不能注册

#更换电话号码,填写信息后,点击注册,页面正常跳转通过,但是数据库没有增加新的注册数据

idea debug启动

img 前端数据传回后端正常

img 到这一步开始出现问题,age和gender数据出现问题

img 到这一步 小白 就不太懂了,数据没传过来

下面是数据库的截图

img

img

package org.example.controller;

import com.alibaba.druid.util.StringUtils;
import org.example.controller.viewobject.RegisterVO;
import org.example.controller.viewobject.UserVO;
import org.example.error.BusinessException;
import org.example.error.EmBusinessError;
import org.example.response.CommonReturnType;
import org.example.response.OtpCode;
import org.example.service.UserService;
import org.example.service.model.UserModel;
import org.example.util.CommonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

/*
@Controller的作用在类级上,用来标记该类,让Spring可以扫描到
这一部分知识属于基础知识,可以参考《Spring实战(任意一版)》
*/
@Controller("user")
@RequestMapping("/user")
/**
 * 继承BaseController,
 * 父类的方法子类不重新,就会引用父类的方法,
 * 若子类重写父类的方法,则引用子类的方法
 * 这里不需要进行重写handlerException
 *
 *   @CrossOrigin解决跨域请求问题
 *   No 'Access-Control-Allow-Origin' header is present on the requested resource
 *   加上这个注解后,就会让response对象返回'Access-Control-Allow-Origin' header 为 通配符*
 *   但是单纯的加注解,只是让跨域互通了,还不能实现互信
 *   需要再加两个参数,才能实现前后端互信
 *
 * @author littlecurl
 */
@CrossOrigin(allowCredentials = "true", allowedHeaders = "*")
public class UserController extends BaseController {
    private static Logger Log = LoggerFactory.getLogger(UserController.class);
    /**
     * 带@Autowired的都是Bean,默认用单例模式创建
     */
    @Autowired
    private UserService userService;

    @Autowired
    private HttpServletRequest httpServletRequest;

    /**
     *
     */
    private HttpSession session;

    /**
     * **************** 对前两个注解的解释:****************
     * 1、这里的@RequestMapping作用在方法级,
     * 告诉我们不只有类级可以使用此注解,
     * 同时也提现了SpringMVC可以映射URL到具体方法的优秀设计
     * 2、这里需要指定@ResponseBody,
     * 具体理解可以参考[博客园](https://www.cnblogs.com/qiankun-site/p/5774325.html#4263851)
     * 这样返回的数据才会以JSON的格式写入到HttpServletResponse对象的body区
     * 浏览器才能呈现body区的JSON数据
     * 如果忘记指定@ResponseBody,则response对象为空,会报404错误
     * (具体response对象是个啥?这是JavaEE基础Servlet里面的知识点,可以回头补习一下)
     * 另外,JSON格式的数据,推荐是否Firefox浏览器查看,会自动格式化
     * <p>
     * **************** 对返回值类型CommonReturnType的解释:****************
     * 虽然我们在Service层,将dataobject整合成了UserModel
     * 但那是给Controller层诸如密码验证之类的,需要两张表的数据的业务准备的
     * 单纯的getUser()业务没必要返回UserModel,将用户敏感信息诸如加密密码,登录方式等等也透传给前端
     * 因此返回值应该再独立出一个viewobject层
     * 但是,仅仅返回viewobject对象的JSON序列化,这样设计没有通用性
     * 比如说,不知道返回值的状态到底是成功还是失败
     * 因此,应该再构造一个response层,对viewobject进行封装,返回CommonReturnType
     * <p>
     * **************** 对@RequestParam注解的解释:****************
     *
     * @param id 用户id
     * @return 通用返回对象
     * @RequestParam用来获取URL中?后面的arg=value对应的参数值 当然SpringMVC不只提供了这一种获取参数的方式,只不过这一注解最常用,其他注解还有好多
     * 具体可以参考[博客园](https://www.cnblogs.com/selinamee/p/5266266.html)
     */
    @RequestMapping("/get")
    @ResponseBody
    public CommonReturnType getUser(@RequestParam(name = "id") Integer id) throws BusinessException {
        /* 调用Service服务,获取id对应的用户信息UserModel
           将model转为viewobject
           再将viewobject进行封装成CommonReturnType
           返回CommonReturnType
        */
        UserModel userModel = userService.getUserById(id);
        /*
         若用户不存在,则抛出异常,抛到了Tomcat的容器层,
         如果把异常抛到Tomcat容器层后就不管了,那就只是会在控制台Tomcat日志中打印异常信息,
         无法返回到前端。
         好在SpringBoot有给出解决办法,就是再定义一个handlerException方法,
         写在了BaseController中。
         */
        if (userModel == null) {
            /*
            如果把下面的代码注释掉,并且再引用一下userModel对象
             比如:
             userModel.setEncryptPassword("123");
             因为userModel是null,引用空指针进行set,Java虚拟机会抛出java.lang.NullPointException
             这时候就会触发BaseController里面SpringBoot的注解@ExceptionHandler(Exception.class)
             然后判断到if (ex instanceof BusinessException)条件不成立
             继而返回UNKNOWN_ERROR的CommonReturnType
             从这里可以看出来UserController继承BaseController实现代码复用机制
             */
            throw new BusinessException(EmBusinessError.USER_NOT_EXIST);
        }
        UserVO userVO = convertFromModel(userModel);
        /*
           如果没有异常跑出,就表示返回的是正确的结果
           同时,因为有加@ResponseBody注解,该对象会被解析为JSON格式,呈现到前端
         */
        return CommonReturnType.create(userVO);
    }

    /**
     * 将UserModel转为UserVO
     *
     * @param userModel Model
     * @return UserVO
     */
    private UserVO convertFromModel(UserModel userModel) {
        if (userModel == null) {
            return null;
        }
        UserVO userVO = new UserVO();
        /* 调用BeanUtils提供的复制属性方法,userVO不存在的属性会被自动丢弃 */
        BeanUtils.copyProperties(userModel, userVO);
        return userVO;
    }

    /**
     * 获取otp验证码
     * 三步走
     * 1、生成验证码
     * 2、存到 Session 中
     * 3、返回验证码
     *
     * 注意这里POST请求要求传递请求头 content-type:application/x-www-form-urlencoded
     *
     * @param telephone
     * @return
     * @throws BusinessException
     */
    @RequestMapping(value = "/getOtp", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
    @ResponseBody
    public CommonReturnType getOtp(@RequestParam(name = "telephone") String telephone) throws BusinessException {
        /* 0、用户获取验证码时,检测是否已存在注册用户 */
        boolean hasRegistered = userService.getUserByTelephone(telephone);
        if (hasRegistered) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "手机号已重复注册");
        }
        // 1、按照一定规则生成OTP验证码(6位)
        Random random = new Random();
        int randomInt = random.nextInt(99999);
        randomInt += 100000;
        String otpCode = String.valueOf(randomInt);

        // 2、将OTP验证码与用户手机号进行绑定
        session = httpServletRequest.getSession();
        session.setAttribute(telephone, otpCode);

        // 3、将OTP验证码通过短信通道发给用户,省略
        Log.info("telephone: " + telephone + "&otpCode: " + otpCode);

        // 4、将信息抽象为类
        OtpCode otpCodeObj = new OtpCode(telephone, otpCode);
        // 5、返回正确信息,方便前端获取
        return CommonReturnType.create(otpCodeObj, "successGetOtpCode");
    }

    /**
     * 用户注册接口
     * 接收参数统一使用字符串,接收后再进行类型转换
     *
     * @param telephone 手机号
     * @param otpCode   验证码
     * @param name      姓名
     * @param ageStr    年龄
     * @param genderStr 性别
     * @param password  密码
     * @return 通用返回对象
     */
    @RequestMapping(value = "/register", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
    @ResponseBody
    public CommonReturnType register(
            @RequestParam(name = "telephone") String telephone,
            @RequestParam(name = "otpCode") String otpCode,
            @RequestParam(name = "name") String name,
            @RequestParam(name = "age") String ageStr,
            @RequestParam(name = "gender") String genderStr,
            @RequestParam(name = "password") String password
    ) throws UnsupportedEncodingException, NoSuchAlgorithmException, BusinessException {
        boolean hasRegistered = userService.getUserByTelephone(telephone);
        if (hasRegistered) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "手机号已重复注册");
        }

        // 从Session中获取对应手机号的验证码
        // otpCode是用户填写的,inSessionOtpCode是系统生成的
        if (session == null) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "无效的验证码,请重新获取");
        }

        String inSessionOtpCode = (String) session.getAttribute(telephone);


        Log.info("telephone: " + telephone + " inSessionOtpCode: " + inSessionOtpCode + " otpCode: " + otpCode);
        if (!StringUtils.equals(otpCode, inSessionOtpCode)) {
            Log.info("短信验证码错误");
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "短信验证码错误");
        }

        // 类型转换,适配数据库
        int age = Integer.valueOf(ageStr);
        int gender = Integer.parseInt(genderStr);
        // 验证码通过后,进行注册流程
        UserModel userModel = new UserModel();
        userModel.setName(name);
        userModel.setGender(gender);
        userModel.setAge(age);
        userModel.setTelephone(telephone);
        userModel.setEncryptPassword(this.EncodeByMd5(password));

        // 注册成功,只返回success即可
        return CommonReturnType.create(userModel);
    }

    /**
     * 用户注册接口
     * 接收参数统一使用字符串,接收后再进行类型转换
     *
     * @return 通用返回对象
     */
    @RequestMapping(value = "/registerjson", method = {RequestMethod.POST})
    @ResponseBody
    public CommonReturnType registerJson(
            @Valid
            @RequestBody RegisterVO registerVO,
            BindingResult bindingResult
    ) throws UnsupportedEncodingException, NoSuchAlgorithmException, BusinessException {
        if (bindingResult.hasErrors()) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, CommonUtil.processErrorString(bindingResult));
        }
        // 从Session中获取对应手机号的验证码
        // otpCode是用户填写的,inSessionOtpCode是系统生成的
        String inSessionOtpCode = (String) session.getAttribute(registerVO.getTelephone());
        Log.info("telephone: " + registerVO.getTelephone() + " inSessionOtpCode: "
                + inSessionOtpCode + " otpCode: " + registerVO.getOtpCode());
        if (!StringUtils.equals(registerVO.getOtpCode(), inSessionOtpCode)) {
            Log.info("短信验证码错误");
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "短信验证码错误");
        }
        // 类型转换,适配数据库
        int age = Integer.parseInt(registerVO.getAge());
        int gender = Integer.parseInt(registerVO.getGender());
        // 验证码通过后,进行注册流程
        UserModel userModel = new UserModel();
        userModel.setName(registerVO.getName());
        userModel.setGender(gender);
        userModel.setAge(age);
        userModel.setTelephone(registerVO.getTelephone());

        userModel.setEncryptPassword(this.EncodeByMd5(registerVO.getTelephone()));


        // 注册成功,只返回success即可
        return CommonReturnType.create(null);
    }

    /**
     * 用户登录接口
     *
     * @param telephone 手机号
     * @param password  原生密码
     * @return 通用返回对象
     */
    @RequestMapping(value = "/login", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
    @ResponseBody
    public CommonReturnType login(
            @RequestParam(value = "telephone", required = true) String telephone,
            @RequestParam(value = "password", required = true) String password,
            @RequestParam(value = "type", required = true) String type
    ) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
        // 入参校验
        if (org.apache.commons.lang3.StringUtils.isEmpty(telephone)
                || org.apache.commons.lang3.StringUtils.isEmpty(password)
                || org.apache.commons.lang3.StringUtils.isEmpty(type)
        ) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
        }

        boolean hasRegistered = userService.getUserByTelephone(telephone);
        if (!hasRegistered) {
            throw new BusinessException(EmBusinessError.USER_NOT_EXIST);
        }

        UserModel userModel = null;
        // 登录
        if (StringUtils.equals(type, "login")) {
            userModel = userService.validateLogin(telephone, this.EncodeByMd5(password));
        }
        // 自动登录
        else if (StringUtils.equals(type, "autoLogin")) {
            userModel = userService.validateLogin(telephone, password);
        } else {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
        }

        // 将登陆凭证加入到用户登录成功的Session中
        // 切换web页面的时候,可以不用重复登录
        session = httpServletRequest.getSession();
        session.setAttribute("IS_LOGIN", true);
        session.setAttribute("LOGIN_USER", userModel);

        // 登录成功,只返回success即可
        return CommonReturnType.create(userModel);
    }

    /**
     * MD5加密+BASE64编码
     *
     * @return 加密后字符串
     */
    public String EncodeByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        BASE64Encoder base64en = new BASE64Encoder();
        String newstr = base64en.encode(md5.digest(str.getBytes("utf-8")));
        return newstr;
    }
}

另外,数据库中 id 两张表都设置了自增, mapper表中也写了

请大佬们指点

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

6条回答 默认 最新

  • li.siyuan 2021-06-30 17:28
    已采纳

    远程看吧 这代码有点多,用肉眼筛选的话 不方便,你私聊我

    点赞 评论
  • IT学习日记 2021-06-30 17:33

    是否有报错?

    点赞 评论
  • baihua1113 2021-06-30 17:45

    mapper表中也写了

    点赞 评论
  • Iot-Mr.Qu 2021-06-30 17:47

    如果你是之前已经用可视化工具打开表数据了,然后再用代码去操作插入、删除、修改数据,此时需要刷新表才行;不然界面还是之前的查询数据; 你刷新一下表试试

    点赞 评论
  • 珠峰下的沙砾 2021-07-01 08:33
    点赞 评论
  • 雨云21 2021-07-02 09:59

    怎么都把代码整这么复杂,281行之后,你没有把获取到的数据添加到数据库,意思是你没写添加数据到数据库的代码

    点赞 评论

相关推荐 更多相似问题