当用户输入用户名和密码将数据提交给后台数据库进行查询。如果存在对应的用户名和密码则表示登陆成功,登陆成功之后跳转到系统的主页也就是index.html页面,跳转在前端使用jquery来完成。
1.登陆-持久层
1.1规划需要执行的SQL语句
依据用户提交的用户名和密码做select查询。密码的比较在业务层执行。
select * from t_user where username=?
说明:如果在分析过程中发现某个功能模块已经被开发完成,所以就可以省略当前的开发步骤,这个分析过程不能够省略。
1.2 接口设计和方法
不用重复开发。单元测试也是无需单独执行
2.登陆-业务层
2.1 规划异常
1.用户名对应的密码错误,密码匹配失败的异常:PasswordNotMatchException异常,运行时异常,业务异常。
2.用户名没有被找到,抛出异常:UsernameNotFoundException,运行时异常,业务异常
3.异常的编写:
·业务层异常需要继承ServiceException异常类。
·在具体的异常类定义构造方法(可以使用快捷键来生成,有5个构造方法)。
2.2 设计业务层接口和抽象方法及实现
1.直接在IUserService接口中编写抽象方法,login(String username);将当前登陆成功的用户数据以当前用户对象的形式进行返回。状态管理:可以将数据保存在cookie或者session中,可以避免重复度很高的数据多次频繁操作数据进行获取(用户名,用户id存放在session中,用户头像-cookie中)。
/**
* 用户登陆功能
* @param username 用户名
* @param password 用户的密码
* @return 当前匹配的用户数据,如果没有则返回null值
*/
User login(String username,String password);
2.需要在实现类中实现父接口中抽象方法。
@Override
public User login(String username, String password) {
//根据用户名称来查询用户的数据是否存在,如果不在则抛出异常
User result = userMapper.findByUsername(username);
if(result==null){
throw new UsernameNotFoundException("用户数据不存在");
}
// 检测用户的密码是否匹配
//1.先获取到数据库中的加密之后的密码
String oldPassword=result.getPassword();
//2.和用户传递过来的密码进行比较
//2.1先获取盐值:上一次在注册时所自动生成的盐值
String salt = result.getSalt();
//2.2将用户的密码按照相同的md5算法的规则进行加密
String newMd5Password=getMD5Password(password,salt);
//3.将密码进行比较
if(!newMd5Password.equals(oldPassword)){
throw new PasswordNotMatchException("用户密码错误");
}
//判断is——delete字段的值是否为1表示标记为已删除
if(result.getIsDelete()==1){
throw new UsernameNotFoundException("用户数据不存在");
}
//调用mapper层的findByUsername来查询用户的数据,提升了系统的性能
User user=new User();
user.setUid(result.getUid());
user.setUsername(result.getUsername());
user.setAvatar(result.getAvatar());
//将当前的用户数据返回,返回的数据是为了辅助其他页面做数据展示使用(uid,username,avatar)
return user;
}
3.在测试类中测试业务层登陆是否可以执行通过。
@Test
public void login(){
User u = userService.login("test01", "123");
System.out.println(u);
}
4.如果一个类没有手动创建。直接将这个类复制到项目,idea会找不到类,之前缓存导致不能正常找到这类的符号,重构一下即可。
3.登陆-控制层
3.1 处理异常
业务层抛出的异常是什么,需要在统一异常处理类中进行统一的捕获和处理,如果业务层抛出的异常已经在统一异常处理类中曾经处理过,则不需要重复添加。
else if (e instanceof UsernameNotFoundException) {
result.setState(5001);
result.setMessage("用户数据不存在的异常");
} else if (e instanceof PasswordNotMatchException) {
result.setState(5002);
result.setMessage("用户名的密码错误的异常");
}
3.2 设计请求、
请求路径:/users/login
请求方式:POST
请求数据:String username,String password,HttpSession session
请求结果:JsonResult<User>
3.3 处理请求
在UserController类中编写处理请求的方法。
/**
* 约定大于配置:开发思想来完成,省略了大量的配置及注解的编写
*1.接收数据方式:请求处理方法的参数列表设置为pojo类型来接收前端数据
* SpringBoot会将前端的url地址中的参数名和pojo类的属性名进行比较,如果
* 这两个名称相同,则将值注入到pojo类中对应的属性上
*/
/**
*2.接收数据方式:请求处理方法的参数列表设置为非pojo类型,直接将请求的参数名和方法的参数名直接进行比较
* 如果名称相同则自动完成值的依赖注入
*/
@RequestMapping("login")
public JsonResult<User> login(String username,String password){
User data = userService.login(username, password);
return new JsonResult<User>(OK,data);
}
4.登陆-前端页面
1.在login.html页面中依据前面所设置的请求来发送ajax请求。
<script type="text/javascript">
$("#btn-login").click(function () {
$.ajax({
url:"/users/login",
type:"POST",
data:$("#form-login").serialize(),
dataType:"JSON",
success:function (json) {
if(json.state==200){
alert("登陆成功")
//跳转到系统主页index.html
//相对路径来确定跳转页面
location.href="index.html"
}else{
alert("登陆失败")
}
},
error:function (xhr) {
alert("登录时产生未知的异常"+xhr.message)
}
})
})
</script>