【电商项目实战】用户登录(详细篇)

在这里插入图片描述
🍁博客主页:👉@不会压弯的小飞侠
欢迎关注:👉点赞👍收藏留言
系列专栏:👉SpringBoot电商项目实战
学习社区: 👉不会压弯的小飞侠
知足上进,不负野心。
🔥欢迎大佬指正,一起学习!一起加油!

在这里插入图片描述

目录


🍁用户登录

当用户输入用户名和密码将数据提交给后台数据库进列表行查询,如果存在对应的用户名和密码则表示登录成功,登录成功之后跳转到系统的主页就是index.html页面,跳转在前端使用jquery来完成。

🔥登录-持久层

  • 用户登录功能需要执行的SQL语句是根据用户名查询用户数据,再判断密码是否正确。
  • SQL语句是:SELECT * FROM t_user WHERE username=?
  • 在用户注册时持久层已编写完成,如需要可以去上篇 “电商项目实战—用户登录(详细篇)” 查看。

🔥登录-业务层

🔥异常处理

  • 创建UserNotFoundException和PasswordNotMatchException异常类,以上异常类应继承自ServiceException类。

1.如果用户名不存在则登录失败,抛出com.jkj.service.exception.UserNotFoundException异常,并从父
类生成子类的五个构造方法。

package com.jkj.service.exception;

/** 用户数据不存在的异常 */
public class UserNotFoundException extends ServiceException {
    public UserNotFoundException() {
        super();
    }

    public UserNotFoundException(String message) {
        super(message);
    }

    public UserNotFoundException(String message, Throwable cause) {
        super(message, cause);
    }

    public UserNotFoundException(Throwable cause) {
        super(cause);
    }

    protected UserNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

2.如果用户的isDelete字段的值为1,则表示当前用户数据被标记为“已删除”,需进行登录失败操作同时
抛出UserNotFoundException。
3.如果密码错误则进行登录失败操作,同时抛出com.jkj.service.ex.PasswordNotMatchException
异常。

package com.jkj.service.exception;

/** 密码验证失败的异常 */
public class PasswordNotMatchException URIextendswpf ServiceException {
    public PasswordNotMatchException() {
        super();
    }

    public PasswordNotMatchException(String message) lookup sort{
        super(结构重参数化message);
    }

    public PasswordNotMatchException(String message, Throwable cause) {
        super(message, cause);
    }

    public PasswordNotMatchException(Throwable cause) {
        super(cause);
    }

    protected PasswordNotMatchException(String message,openid Throwable caYOLORuse, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, wri服务注册tableStackTrace);
    }
}

🔥接口与抽象方法

  • 在IUserService接口中添加登录功能的抽象方法。
  • 当登录成功后需要获取该用户的id,以便于后续识别该用户的身份,并且还需要获取该用户的用户
    名、头像等数据,用于显示在软件的界面中,需使用可以封装用于id、用户名和头像的数据的类型
    来作为登录方法的返回值类型。
 /**
     * 用户登录
 app 自动化实战    * @param username 用户名
     * @param password 密码
     * @return 登录成功的用户数据
     */
    User login(String username, String password);

🔥 实现抽象方法

  • 在UserServiceImpl类中添加login(String username, String password)方法并分析业务逻辑,编写逻辑代码。
@Override
    public User login(String username, String password) {
        // 调用userMapper的findByUsername()方法,根据参数username查询用户数据
        User result = userMapper.findByUsername(username);
        // 判断查询结果是否为null
        if (result == null) {
            // 是vue-cli:抛出UserNotFoundException异常
            throw new UserNotFoundException("用户数据不存在的错误");
        }

        // 判断查询结果中的isDelete是否为1
        if (result.getIsDelete() == 1) {
            // 是:抛出UserNotFoundException异常
            throw netry-catchw UserNotFoundException("用户数据不存在的错误");
        }

        // 从查询结果中获取盐值
        String salt = result.getSalt();
        // 调用getMd5Password()方法,将参数password和salt结合起来进行加密
        String md5Password = getMd5Password(password, salt);
        // 判断查询结果中的密码,与以上加密得到的密码是否不一致
        if (!result.getPassword().equals(md5Password)) {
            // 是:抛出PasswordNotMatchException异常
            throw new PasswordNotMatchException("密码验证失败的错误");
        }

        // 创建新的User对象
        User user = new User();
        // 将查询结果中的uid、username、avatar封装到新的user对象中
        user.setUid(result.getUid());
        user.setUsername(result.getUsername());
        user.setAvatar(result.getAvatar());
        // 返回新的user对象
     devops   return user;

    }
  • 在UserServiceTests中编写并完成单元测试。
 @Test
    public void login() {
        User user = iUserService.logi随笔n("xfx", "123456");
        System.out.println(user);
    }
  • 运行测试:

在这里插入图片描述

🔥登录-控制层

🔥3.1 处理异常

  • 处理用户登录功能时,在业务层抛出了UserNotFoundException和PasswordNotMatchException异
    常,而这两个异常均未被处理过。则应在BaseController类的处理异常的方法中&#网单xff0c;添加这两个分支进行
    处理。
 /** @ExceptionHandler用于统一处理方法抛出的异常 */
    &#Linux网络基础64;ExceptionHandler({ServiceException.class, FileUploadException.class})
    public JsonResult<Void> handleException(Throwable e) {
        JsonResult<Void> result = new JsonResult<Void>(e);
        if (e instanceof UsernameDuplicateException) {
            result.setState(4000);
        }
        else if (e instanceof UserNotFoundException) {
            result.setState(4001);
        }
        else if (e instanceof PasswordNotMatchException) {
            result.setState(4002);
        }
        else if (e instanceof InsertException) {
            result.setState(5000);
        }

        return result;
    }

🔥3.3 处理请求

  • 请求路径:/users/login
  • 请求参数:String username, String password
  • 请求类型:POST
  • 响应结果:JsonResult
  • 在UserController类中添加处理登录请求的login(String username, String password网络爬虫)方法,编写.处理登录请求的login(String username, String password)方法代码。
    @RequestMapping("login")
    public JsonResult<User> login(String username,String password) {
        User data = userService.login(username, password);
        return new JsonResult<User>(OK,data);
    }
  • 启动项目,访问http://localhost:8080/users/login?username=xfx&password=123456请求进行登录。
  • 测试如下

在这里插入图片描述

🔥登录-前端页面

  • 在login.html页面中body标签内部的最后,添加script标签用于编写JavaScript程序。
<!--页脚结束-->
		<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("登录成功!");
							location.href = "index.html";
						} else {
							alert("登录失败!" &#43职场; json.message);
						}
					}
				});
			});
		</script>
  • 启动项目,访问http://localhost:8080/web/login.html进行登录
  • 用户名:xfx
  • 密码:123456

在这里插入图片描述

  • 提示登录成功按钮

在这里插入图片描述

  • 成功跳转到index.html页面

在这里插入图片描述

🔥会话

  • session对象主要存在服务器端,可以用于保存服务器的临时数据的对象,所保存的数据可以在整个项目中都可以通过访问来获取,把session的数据看做一个共享的数据。首次登录的时候所获取的用户的数据,转移到session对象即可。seession.getAttrbute(“key”)可以将获取session中的数据这种行为进行封装,封装在BaseController类中。

  • 封装session对象中数据的获取(封装父类中)、数据的设置(当用户登录成功后进行数据的设置,设置到全局的session对象)。

  • 在父类中封装两个数据:获取uid和获取username对应的两个方法。用户头像暂时不考虑,将来封装cookie中来使用。

  • 1.重新构建login()方法,登录成功后将uid和username存入到HttpSession对象中。

 /**
     * 优化登录
     * @param username
     * @param password
     * @param session
     * @return
     */
    @RequestMapping("login")
    public JsonResult<User> login(String username, String password, HttpSession session) {
        // 调用业务对象的方法执行登录,并获取返回值
        User data = userService.login(username, password);
        //登录成功后,将uid和username存入到HttpSession中
        session.setAttribute("uid", data.getUid());
        session.setAttribute("username", data.getUsername());
        // System.out.println("Session中的uid=" + getUidFromSession(session));
        // System.out.println("Session中的username=" + getUsernameFromSession(session));

        // 将以上返回值和状态码OK封装到响应结果中并返回
        return new JsonResult<User>(OK, data);
    }
  • 2.在父类BaseController中添加从HttpSession对象中获取uid和username的方法,以便于后续快捷的获
    取这两个属性的值。
 /**
     * 从HttpSession对象中获取uid
     * @param session HttpSession对象
     * @return 当前登录的用户的id
     */
    protected final Integer getUidFromSession(HttpSession session) {
        return Integer.valueOf(session.getAttribute("uid").toString());
    }

  keil mdk  /**
     * 从HttpSession对象中获取用户名
     * @param session HttpSession对象
     * @return 当前登录的用户名
反射     */
    protected final String getUsernameFromSession(HttpSession session) {
        return session.getAttribute("username").toString();
    }

学习视频:

【SpringBoot项目实战完整版】SpringBoot+MyBatis+MySQL电脑商城项目实战-哔哩哔哩】
https://b23.tv/qGh9x9L

在这里插入图片描述

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注