用户模型管理——用户注册功能实现
1.实现方法:在UserController 用户注册接口
//用户注册接口
@RequestMapping(value = "/register", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
@ResponseBody
public CommonReturnType register(@RequestParam(name = "telphone") String telphone,
@RequestParam(name = "otpCode") String otpCode,
@RequestParam(name = "name") String name,
@RequestParam(name = "gender") String gender,
@RequestParam(name = "age") String age,
@RequestParam(name = "password") String password) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
//验证手机号和对应的otpCode相符合
String inSessionOtpCode = (String) this.httpServletRequest.getSession().getAttribute(telphone);
if (!com.alibaba.druid.util.StringUtils.equals(otpCode, inSessionOtpCode)) {
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "短信验证码不符合");
}
//用户的注册流程
UserModel userModel = new UserModel();
userModel.setName(name);
userModel.setAge(Integer.valueOf(age));
userModel.setGender(Byte.valueOf(gender));
userModel.setTelphone(telphone);
userModel.setRegisitMode("byphone");
//密码加密
userModel.setEncrptPassword(this.EncodeByMd5(password));
userService.register(userModel);
return CommonReturnType.create(null);
}
//密码加密
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;
}
问题:sun.misc.BASE64Encoder找不到jar包
翻看博文:Eclipse 解决sun.misc.BASE64Encoder找不到jar包的解决方法
2.引入做输入校验的依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
3.UserServiceImpl的register方法
@Override
@Transactional//声明事务
public void register(UserModel userModel) throws BusinessException {
//校验
if (userModel == null) {
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
}
if (StringUtils.isEmpty(userModel.getName())
|| userModel.getGender() == null
|| userModel.getAge() == null
|| StringUtils.isEmpty(userModel.getTelphone())) {
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
}
//实现model->dataobject方法
UserDO userDO = convertFromModel(userModel);
//insertSelective相对于insert方法,不会覆盖掉数据库的默认值
userDOMapper.insertSelective(userDO);
userModel.setId(userDO.getId());
userPasswordDO userPasswordDO = convertPasswordFromModel(userModel);
userPasswordDOMapper.insertSelective(userPasswordDO);
return;
}
private userPasswordDO convertPasswordFromModel(UserModel userModel) {
if (userModel == null) {
return null;
}
userPasswordDO userPasswordDO = new userPasswordDO();
userPasswordDO.setEncrptPassword(userModel.getEncrptPassword());
userPasswordDO.setUserId(userModel.getId());
return userPasswordDO;
}
private UserDO convertFromModel(UserModel userModel) {
if (userModel == null) {
return null;
}
UserDO userDO = new UserDO();
BeanUtils.copyProperties(userModel, userDO);
return userDO;
}
4.前端界面
首先在getotp界面添加注册成功的跳转界面
success:function (data) {
if (data.status=="success") {
alert("otp已经发送到了您的手机,请注意查收");
window.location.href="register.html";
}else {
alert("otp发送失败,原因为" + data.data.errMsg);
}
},
5.新建一个register.html
<body class="login">
<div class="content">
<h3 class="form-title">用户注册</h3>
<div class="form-group">
<label class="control-label">手机号</label>
<div>
<input class="form-control" type="text" placeholder="手机号" name="telphone" id="telphone"/>
</div>
</div>
<div class="form-group">
<label class="control-label">验证码</label>
<div>
<input class="form-control" type="text" placeholder="验证码" name="otpCode" id="otpCode"/>
</div>
</div>
<div class="form-group">
<label class="control-label">用户昵称</label>
<div>
<input class="form-control" type="text" placeholder="用户昵称" name="name" id="name"/>
</div>
</div>
<div class="form-group">
<label class="control-label">性别</label>
<div>
<input class="form-control" type="text" placeholder="性别" name="gender" id="gender"/>
</div>
</div>
<div class="form-group">
<label class="control-label">年龄</label>
<div>
<input class="form-control" type="text" placeholder="年龄" name="age" id="age"/>
</div>
</div>
<div class="form-group">
<label class="control-label">密码</label>
<div>
<input class="form-control" type="password" placeholder="密码" name="password" id="password"/>
</div>
</div>
<div class="form-actions">
<button class="btn blue" id="register" type="submit">
提交注册
</button>
</div>
</div>
</body>
<script>
jQuery(document).ready(function () {
//绑定otp的click事件用于向后端发送获取手机验证码的请求
$("#register").on("click",function () {
var telphone=$("#telphone").val();
var otpCode=$("#otpCode").val();
var password=$("#password").val();
var age=$("#age").val();
var gender=$("#gender").val();
var name=$("#name").val();
if (telphone==null || telphone=="") {
alert("手机号不能为空");
return false;
}
if (otpCode==null || otpCode=="") {
alert("验证码不能为空");
return false;
}
if (name==null || name=="") {
alert("用户名不能为空");
return false;
}
if (gender==null || gender=="") {
alert("性别不能为空");
return false;
}
if (age==null || age=="") {
alert("年龄不能为空");
return false;
}
if (password==null || password=="") {
alert("密码不能为空");
return false;
}
//映射到后端@RequestMapping(value = "/register", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
$.ajax({
type:"POST",
contentType:"application/x-www-form-urlencoded",
url:"http://localhost:8080/user/register",
data:{
"telphone":telphone,
"otpCode":otpCode,
"password":password,
"age":age,
"gender":gender,
"name":name
},
//允许跨域请求
xhrFields:{withCredentials:true},
success:function (data) {
if (data.status=="success") {
alert("注册成功");
}else {
alert("注册失败,原因为" + data.data.errMsg);
}
},
error:function (data) {
alert("注册失败,原因为"+data.responseText);
}
});
return false;
});
});
</script>
6.调试
发现报错,获取不到验证码
跨域请求问题
在UserController上添加如下注解:
//跨域请求中,不能做到session共享
@CrossOrigin(allowCredentials = "true",allowedHeaders = "*")
在UserDOMapper和passwordDOMapper的insertSelective方法中添加如下代码:
keyProperty="id" useGeneratedKeys="true"
调试:
注册成功,但是查看数据库,发现password表中并没有user_id
7.修改UserServiceImpl
UserDO userDO = convertFromModel(userModel);
//insertSelective相对于insert方法,不会覆盖掉数据库的默认值
userDOMapper.insertSelective(userDO);
userModel.setId(userDO.getId());//自增id取出之后复制给对应的UserDO
userPasswordDO userPasswordDO = convertPasswordFromModel(userModel);
userPasswordDOMapper.insertSelective(userPasswordDO);
return;
重新测试成功。
8.上面并没有做手机号的唯一性验证
首先,在数据库中添加索引:
索引名称为:telphone_unique_index,索引字段选择telphone,索引类型为UNIQUE,索引方法为BTREE
然后修改以下代码:
try {
userDOMapper.insertSelective(userDO);
} catch (DuplicateKeyException ex) {
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "手机号已注册");
}