用户登录【项目 商城】

简介: 用户登录【项目 商城】

用户登录


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

1. 登录-持久层

1.1 规划需要执行的sql语句

依据用户提交的用户名和密码做select查询。密码的比较在业务层执行。

select * form t_user where username=?
 说明:如果在分析过程中发现某个功能已经被开发完成,
 所有就可以省略当前的开发步骤,这个分析过程不能够省略。

1.2 接口设计和方法

不要重复开发了。单元测试也是无需单独执行了。

2. 登录-业务层

2.1 规划异常

1.用户名对应的密码错误,密码匹配失败的异常。PasswordNotMatchException异常,运行时异常,业务异常。

2.用户名没有被找到的,抛出异常:UsernameNotFoundException,运行时异常,业务异常。

3.异常的编写:

  • 业务层异常需要继承ServiceException异常类
  • 在具体的异常类中定义构造方法(可以使用快捷键来生成,有5个构造方法)。

    业务层异常

2.2 设计业务层接口和抽象方法

1.直接在IUserService接口中编写抽象方法,login(String username,String password)

将当前登录成功的用户数据以当前用户对象的形式进行返回,状态管理:可以将数据保存在cookie或者session中,可以避免重复的很高的数据多次频繁操作数据进行获取。(用户名、用户id-存放在session中,用户头像-cookie中)。

   /**
     * 用户登录功能
     * @param username 用户名
     * @param password 用户的密码
     * @return 当前匹配的用户数据,如果没有则返回null值
     */
    User login(String username,String password);

2.3 抽象方法的实现

2.需要在实现类中实现父接口中抽象方法。

  @Override
    public User login(String username, String password) {
        //根据用户名称来查询用户的数据是否存在,如果不存在则抛出异常
        User result=userMapper.findByUsername(username);
        if (result==null){
            throw new UserNotFoundException("用户数据不存在");
        }
        //检测用户的密码是否匹配
        //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 UserNotFoundException("用户数据不存在");
        }
        //调用mapper层的findByUsername来查询用户的数据,提示系统的性能
        User user=new User();
        user.setUid(result.getUid());
        user.setUsername(result.getUsername());
        user.setAvatar(result.getAvatar());
        //将当前的用户数据返回,返回的数据是为了辅助其他页面做数据展示使用(uid,username,avatar)
        return user;
    }

UserService–login


3.在测试类中测试业务层登录的方法是否可以执行通过。

  @Test
    public void login(){
        User user = userService.login("test01", "123");
        System.out.println(user);
    }

UserServiceTests–login


4.如果一个类没有手动创建直接将这个类复制到项目,idea找不到这个类。之前的缓存导致不能够正常找到这类的符号。重新构建。

测试



3. 登录-控制层

3.1 处理异常

1.业务层抛出的异常是什么,需要在统一异常处理类中进行统一的捕获和处理,如果也曾抛出的异常类型已经在统一的异常处理里中曾经处理过,则不必重复。

BaseController

    else if (e instanceof UserNotFoundException){
            result.setState(5001);
            result.setMessage("用户数据不存在的异常");
        }else if (e instanceof PasswordNotMatchException){
            result.setState(5002);
            result.setMessage("用户密码错误的异常");
        }

BaseController–login异常


3.2 设计请求

请求路径:/users.login
请求方式:/POST
请求数据:String username,String password
响应结果:JsonResult<User>

3.3 处理请求

在UserController类中编写处理请求的方法。

    @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=test01&password=123


  /**
     * 约定大于配置:开发思想来完成,省略大量的配置甚至注解的编写
     * 1.接受数据方式:请求处理方法的参数列表设置为pojo类型来接受前端的数据,
     * SpringBoot会将前端的url地址中的参数名和pojo类的属性名进行比较
     * 如果这两个名称相同,则将值注入到pojo类中对应的属性上
     */
    @RequestMapping("reg")
    public JsonResult<Void> reg(User user)
    /**
     * 2.接受数据方式:请求处理方法的参数列表设置为非pojo类型
     * SpringBoot会直接将请求的参数名和方法的参数名直接进行比较,
     * 如果名称相同则自动完成值的依赖注入
     */
    @RequestMapping("login")
    public JsonResult<User> login(String username,String password)

UserController–接受数据方式


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";
              //  头像保存至cookie
              $.cookie("avatar", json.data.avatar, {expires: 7});
              console.log("cookie中的avatar=" + $.cookie("avatar"));
            } else {
              alert("登录失败!" + json.message);
            }
          },
          error:function (xhr){
            alert("登录时产生未知的异常"+xhr.message);
          }
        });
      });
    </script>

login.html


2.访问页面进行用户的登录操作。

测试

http://localhost:8080/web/login.html#


用户会话Session

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


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


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

  /**
     * 获取session对象的uid
     * @param session session对象
     * @return 当前登录得到用户uid的值
     */
    protected final Integer getuidFromSession(HttpSession session){
        return Integer.valueOf(session.getAttribute("uid").toString());
    }
    /**
     * 获取session对象的username
     * @param session session对象
     * @return 当前登录得到用户username的值
     * 
     * 在实现类中重写了父类中的toString()方法,不是句柄信息的输出@xxx
     */
    protected final String getUsernameFromSession(HttpSession session){
        return session.getAttribute("username").toString();
    }

3.在登录的方法中将数据封装在session对象中。服务器本身自动创建有session对象,已经是一个全局的session对象。SpringBoot直接使用session对象,直接将HttpSession类型的对象作为请求处理方法的参数,会自动将全局的session对象注入到session注入到请求处理方法的session形参上。

设计请求中添加 HttpSession session

请求路径:/users.login
请求方式:/POST
请求数据:String username,String password,HttpSession session
响应结果:JsonResult<User>
  @RequestMapping("login")
    public JsonResult<User> login(String username,
                                  String password,
                                  HttpSession session){
        User data = userService.login(username, password);
        //向session对象中完成数据的绑定(session全局的)
        session.setAttribute("uid",data.getUid());
        session.setAttribute("username",data.getUsername());
        //获取session中绑定的数据
        //System.out.println(getuidFromSession(session));
        //System.out.println(getUsernameFromSession(session));
        return new JsonResult<User>(OK,data);
    }


README–用户登录

相关文章
|
1月前
|
移动开发 容器
订水商城H5实战教程-02系统登录
订水商城H5实战教程-02系统登录
|
1月前
|
JavaScript 数据安全/隐私保护
|
9月前
|
Java 数据安全/隐私保护
注册登录账号系统
注册登录账号系统
313 0
|
10月前
|
SQL Java 数据库连接
用户注册【项目 商城】2
用户注册【项目 商城】2
44 0
|
1月前
uniapp获取微信用户信息登录
uniapp获取微信用户信息登录
|
7月前
|
JSON 前端开发 NoSQL
淘东电商项目(27) -门户登出功能
淘东电商项目(27) -门户登出功能
31 0
|
10月前
|
SQL 前端开发 测试技术
修改密码【项目 商城】
修改密码【项目 商城】
46 0
|
10月前
|
前端开发 测试技术 数据库
用户注册【项目 商城】3
用户注册【项目 商城】3
42 0
|
10月前
|
SQL JavaScript 前端开发
用户注册【项目 商城】1
用户注册【项目 商城】1
45 0
|
10月前
|
JSON 缓存 前端开发
用户注册【项目 商城】4
用户注册【项目 商城】4
51 0