本文开发一用户注册与登录的后端java平台。开发完后的网页效果:http://user-front.66bond.com/
后端主要提供用户的注册、查询、删除等操作。使用到的开发工具:
- IDEA2021; 关注公众号”青椒工具”,发送”IDEA”,获取windows下的IDEA安装包
- mysql 5.7;关注公众号”青椒工具”,发送”mysql”,获取windows下的mysql5.7安装包;
1、注册逻辑
写代码之前,我们先罗列下用户的注册逻辑:
1、用户输入的账户和密码不能为空;
2、校验用户的账户、密码是否符合要求:
- 账户字符不能少于4个;
- 密码不能小于8位;
- 账户不能与已有的重复;
- 账户不能包含特殊字符;
- 密码和校验密码相同;
3、对密码进行加密;保证后端工作人员不能看到用户密码;
4、向数据库插入数据;
2、代码框架:
书写注册业务代码涉及到文件:
在service中的接口UserService.java中定义注册方法:
1 2 3
| public interface UserService extends IService<User> { long userRegister(String userAccount, String userPassword, String checkPassword); }
|
在service的实现类中UserServiceImpl.java实现userRegister的代码:
1 2 3 4 5 6 7 8
| public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Override public long userRegister(String userAccount, String userPassword, String checkPassword) { return 0; } }
|
在test/java/com.tfzhang.backend/service/UserServiceTest.java中创建测试文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class UserServiceTest {
@Resource private UserService userService;
@Test public void testAddUser(){ User user = new User(); }
@Test void userRegister() { } }
|
3、业务代码实现:
接下来主要在UserServiceImpl.java中实现各种逻辑的代码;
1、用户输入的账户和密码不能为空;
我们可以这么写:
1 2 3
| if(userAccount==null || userPassword==null || checkPassword==null){ return -1; }
|
但如果变量太多上述的写法很不方便,我们采用一个common lang类库;怎么引入?访问maven repository官网:
1
| https://mvnrepository.com/
|
输入关键词commons lang查找,找到用户量最大的那个,然后点击,如图1所示,获取其maven配置,并复制到我们的pom.xml文件中,图2所示,刷新maven完成安装。
图1 maven库查找common lang

图2 common-lang参数加载到pom.xml文件
我们重写检查非空的代码:
1 2 3
| if(StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)){ return -1; }
|
现在的代码就比较简洁;
账户字符不能少于4个;
密码不能小于8位;
1 2 3 4 5 6 7
| if(userAccount.length() < 4){ return -1; }
if(userPassword.length() < 8 || checkPassword.length() < 8){ return -1; }
|
账户不能与已有的重复;
要比较重复,我们要查询数据库;
1 2 3 4 5 6
| QueryWrapper<User> queryWrapper=new QueryWrapper<>(); queryWrapper.eq("userAccount", userAccount); long count = this.count(queryWrapper); if(count > 0){ return -1; }
|
对于这段代码的解释:这段代码使用了MyBatis-Plus库中的QueryWrapper
类来构建一个数据库查询条件,并查询符合这些条件的记录数量。
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
- 这一行创建了一个新的
QueryWrapper
对象,该对象用于构建数据库查询条件。这里,User
是泛型参数,表示这个QueryWrapper
是用来构建针对User
表或实体的查询条件的。
queryWrapper.eq("userAccount", userAccount);
- 使用
eq
方法给queryWrapper
添加了一个等于条件,即查询User
表中userAccount
字段值等于userAccount
变量值的记录。
long count = this.count(queryWrapper);
- 调用
count
方法(可能是MyBatis-Plus提供的BaseMapper
接口中的方法)来查询符合queryWrapper
构建的条件的记录数量,并将结果保存在count
变量中。
账户不能包含特殊字符;
不能包含特殊字符串,可以使用正则表达式:
1 2 3 4 5 6
| String regex = "^[a-zA-Z0-9]+$"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(userAccount); if(!matcher.matches()){ return -1; }
|
上述的正则表达式表示除了数字和英文大小写,其他的都属于特殊字符;
密码和校验密码相同;
1 2 3
| if(!userPassword.equals(checkPassword)){ return -1; }
|
对密码进行加密(数据脱敏)
不能让后台看到密码的原文,所以要对密码进行加密后再插入到数据库;而且加密方法最好采用非对称加密;
1 2
| final String SALT = "tfzhang"; String encrptedPassword = DigestUtils.md5DigestAsHex((SALT+userPassword).getBytes());
|
代码中,我们采用md5加密,然后同时加了点”盐”,tfzhang,所谓的盐就是加了点杂质,混淆视听的作用;
注意:密码永远不要明文保存;
4、向数据库插入数据;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| User user = new User(); user.setUserAccount(userAccount); user.setUserPassword(encrptedPassword);
user.setUserRole(0); user.setIsDelete(0);
boolean result=this.save(user); if(!result) return -1;
return user.getId();
|
4、业务代码的性能优化及测试
将上述所有的业务代码片段整合后,得到如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Override public long userRegister(String userAccount, String userPassword, String checkPassword) {
if(StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)){ return -1; }
if(userAccount.length() < 4){ return -1; }
if(userPassword.length() < 8 || checkPassword.length() < 8){ return -1; }
QueryWrapper<User> queryWrapper=new QueryWrapper<>(); queryWrapper.eq("userAccount", userAccount); long count = this.count(queryWrapper); if(count > 0){ return -1; }
String regex = "^[a-zA-Z0-9]+$"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(userAccount); if(!matcher.matches()){ return -1; }
if(!userPassword.equals(checkPassword)){ return -1; }
final String SALT = "tfzhang"; String encrptedPassword = DigestUtils.md5DigestAsHex((SALT+userPassword).getBytes());
User user = new User(); user.setUserAccount(userAccount); user.setUserPassword(encrptedPassword);
user.setUserRole(0); user.setIsDelete(0);
boolean result=this.save(user); if(!result) return -1; return user.getId(); } }
|
上述代码会存在”性能浪费”的问题,因为数据库查询比较耗资源,所以将查询数据库的代码放在下面两个逻辑之后:
接下来我们写测试代码,在test/java/com.tfzhang.backend/service/UserServiceTest.java中书写代码:
我们需要针对每个业务点书写测试代码;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| void userRegister() {
String userAccount="tfzhang2"; String userPassword=""; String checkPassword="123456"; long result=userService.userRegister(userAccount, userPassword, checkPassword); Assertions.assertEquals(-1, result);
userAccount = "tf"; result=userService.userRegister(userAccount, userPassword, checkPassword); Assertions.assertEquals(-1, result);
userAccount = "tfzhang2"; String userPassowrd = "123456"; result=userService.userRegister(userAccount, userPassword, checkPassword); Assertions.assertEquals(-1, result);
userAccount="tf zhang"; result=userService.userRegister(userAccount, userPassword, checkPassword); Assertions.assertEquals(-1, result);
userAccount="tfzhang2"; userPassowrd="123456789"; checkPassword="12345678"; result=userService.userRegister(userAccount, userPassword, checkPassword); Assertions.assertEquals(-1, result);
userAccount="tfzhang"; userPassowrd="12345678"; checkPassword="12345678"; result=userService.userRegister(userAccount, userPassword, checkPassword); Assertions.assertEquals(-1, result); }
|
点击测试方法运行,所有测试都通过。最后我们再做一个测试,往数据库中添加一个新用户:
1 2 3 4 5
| userAccount="tfzhang2"; userPassword="12345678"; checkPassword="12345678"; result=userService.userRegister(userAccount, userPassword, checkPassword); assertNotEquals(-1, result);
|
测试成功,result返回的数值还是2,说明插入数据成功,我们查看数据库的确可以发现新插入的tfzhang2用户。
至此我们完成注册逻辑,后续完成登录逻辑。
5、参考资料:
本文参考自如下知识星球中的视频教程,更多的完整的相关视频教程,见如下的收费知识星球,近3万人的学习社区,
编程有人同行,学习不再迷茫:
