基于Springboot外卖系统04:后台系统用户登录+登出功能

登录业务流程

① 在登录页面输入用户名和密码

② 调用后台接口进行验证

③ 通过验证之后,根据后台的响应状态跳转到项目主页

2. 登录业务的相关技术点

  • http 是无状态的
  • 通过 cookie 在客户端记录状态
  • 通过 session 在服务器端记录状态
  • 通过 token 方式维持状态

如果前端与后台接口之间不存在跨域问题,那么推荐使用cookie和session来记录登录状态。

如果前端与服务器接口之间存在跨域问题,那么就要使用token的方式来维持登录状态。

1 需求与逻辑分析

1.1 页面展示

1). 页面原型展示

登录页面存放目录 /resources/backend/page/login/login.html

2). 查看登录请求

通过浏览器调试工具(F12),可以发现,点击登录按钮时,页面会发送请求(请求地址为http://localhost:8080/employee/login)并提交参数 username和password, 请求参数为json格式数据

404,因为后台系统还没有响应此请求的处理器,所以需要创建相关类来处理登录请求 ;

 3). 数据模型(employee表)

 4). 前端页面分析

 当点击 "登录" 按钮, 会触发Vue中定义的 handleLogin 方法:

 在上述的前端代码中, 大家可以看到, 发送登录的异步请求之后, 获取到响应结果, 在响应结果中至少包含三个属性: code、data、msg 。

 由前端代码,我们也可以看到,在用户登录成功之后,服务端会返回用户信息,而前端是将这些用户信息,存储在客户端的 localStorage 中了。

localStorage.setItem('userInfo',JSON.stringify(res.data))

1.2 登陆逻辑分析

1.2.1 登陆逻辑

①. 将页面提交的密码password进行md5加密处理, 得到加密后的字符串

②. 根据页面提交的用户名username查询数据库中员工数据信息 

③. 如果没有查询到, 则返回登录失败结果

④. 密码比对,如果不一致, 则返回登录失败结果

⑤. 查看员工状态,如果为已禁用状态,则返回员工已禁用结果

⑥. 登录成功,将员工id存入Session, 并返回登录成功结果

1.3 登出逻辑

在后台管理系统中,管理员或者员工,登录进入系统之后,页面跳转到后台系统首页面(backend/index.html),此时会在系统的右上角显示当前登录用户的姓名。

如果员工需要退出系统,直接点击右侧的退出按钮即可退出系统,退出系统后页面应跳转回登录页面。

1). 退出页面展示

 2).前端页面分析

点击将会调用一个js方法logout, 在logout的方法中执行如下逻辑:

A. 发起post请求, 调用服务端接口 /employee/logout 执行退出操作 ;

B. 删除客户端 localStorage 中存储的用户登录信息, 跳转至登录页面 ;

2  代码开发

2.1 基础准备工作

在进行登录功能的代码实现之前, 首先在我们的工程下创建包结构:

 1). 创建实体类Employee

所属包: com.itheima.reggie.entity

package com.itheima.reggie.entity;import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**@Description: 员工实体类 该实体类主要用于和员工表 employee 进行映射。* @version v1.0* @author LiBiGo* @date 2022/8/12 11:05*/// 在实体类上添加@Data注解,可以省去代码中大量的 get()、 set()、 toString() 等方法,提高代码的简洁:
@Datapublic class Employee implements Serializable {private static final long serialVersionUID = 1L;private Long id;private String username;private String name;private String password;private String phone;private String sex;// map-underscore-to-camel-case: true// 在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射private String idNumber; //身份证 因为在配置文件中设置驼峰命名,所以与数据库中的不太一样,数据库中为id_numberprivate Integer status;private LocalDateTime createTime; // 同上 驼峰命名法private LocalDateTime updateTime;   // 同上 驼峰命名法@TableField(fill = FieldFill.INSERT)private Long createUser;@TableField(fill = FieldFill.INSERT_UPDATE)private Long updateUser;}

2). 定义Mapper接口

所属包: com.itheima.reggie.mapper

package com.itheima.reggie.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.reggie.entity.Employee;
import org.apache.ibatis.annotations.Mapper;/*** Description: 在MybatisPlus中, 自定义的Mapper接口, 需要继承自 BaseMapper。* @author w* @version 1.0* @date 2022/8/12 11:11*/@Mapper
public interface EmployeeMapper extends BaseMapper<Employee> {}

3).Service接口

package com.itheima.reggie.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.reggie.entity.Employee;/**@Description: 本Service接口, 在定义时需要继承自MybatisPlus提供的Service层接口 IService,*                  这样就可以直接调用 父接口的方法直接执行业务操作, 简化业务层代码实现。* @version v1.0* @author LiBiGo* @date 2022/8/12 12:20*/
public interface EmployeeService extends IService<Employee> {}

4). Service实现类

package com.itheima.reggie.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.mapper.EmployeeMapper;
import com.itheima.reggie.service.EmployeeService;
import org.springframework.stereotype.Service;/*** Description: new java files header..* @author w* @version 1.0* @date 2022/8/12 11:15*/
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper,Employee> implements EmployeeService{
}

5). Controller基础代码

所属包: com.itheima.reggie.controller

package com.itheima.reggie.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;/*** Description: new java files header..* @author w* @version 1.0* @date 2022/8/12 11:17*/@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {@Autowiredprivate EmployeeService employeeService;@PostMapping("/login")public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){/**@Description: 员工登陆* @param @RequestBody 传入的是json 故需要将其转化为实体类,json中的类名与实体类名对应才可以封装*          A. 由于需求分析时, 我们看到前端发起的请求为post请求, 所以服务端需要使用注解 @PostMapping*          B. 由于前端传递的请求参数为json格式的数据, 这里使用Employee对象接收, 但是将json格式数据封装到实体类中, 在形参前需要加注解@RequestBody* @return com.itheima.reggie.common.R<com.itheima.reggie.entity.Employee>* @version v1.0* @author LiBiGo* @date 2022/8/12 11:32*///  ①. 将页面提交的密码password进行md5加密处理, 得到加密后的字符串String password = employee.getPassword();password = DigestUtils.md5DigestAsHex(password.getBytes());//  ②. 根据页面提交的用户名username查询数据库中员工数据信息LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(Employee::getUsername,employee.getUsername());Employee emp = employeeService.getOne(queryWrapper); //在数据库中用户名是唯一的,所以可以用getone()//  ③. 如果没有查询到, 则返回登录失败结果if (emp == null){return R.error("用户名不存在");}//  ④. 密码比对,如果不一致, 则返回登录失败结果if(!emp.getPassword().equals(password)){return R.error("密码失败");}//  ⑤. 查看员工状态,如果为已禁用状态,则返回员工已禁用结果if(emp.getStatus() == 0){return R.error("账户已禁用");}//  ⑥. 登录成功,将员工id存入Session, 并返回登录成功结果request.getSession().setAttribute("employee",emp.getId());return R.success(emp);}@PostMapping("/logout")public R<String> logout(HttpServletRequest request){/**@Description: 需要在Controller中创建对应的处理方法, 接收页面发送的POST请求 /employee/logout* @version v1.0* @author LiBiGo* @date 2022/8/12 12:09*///  清理Session中保存的当前登录员工的idrequest.getSession().removeAttribute("employee");//  返回结果return R.success("退出成功");}
}

6). 导入通用结果类R

package com.itheima.reggie.common;import lombok.Data;
import java.util.HashMap;
import java.util.Map;/*** 通用返回结果,服务端响应的数据最终都会封装成此对象* @param <T>* A. 如果业务执行结果为成功, 构建R对象时, 只需要调用 success方法;*      如果需要返回数据传递 object 参数, 如果无需返回, 可以直接传递null。* B. 如果业务执行结果为失败, 构建R对象时, 只需要调用 error方法, 传递错误提示信息即可。*/
@Data
public class R<T> {private Integer code; //编码:1成功,0和其它数字为失败private String msg; //错误信息private T data; //数据private Map map = new HashMap(); //动态数据public static <T> R<T> success(T object) {R<T> r = new R<T>();r.data = object;r.code = 1;return r;}public static <T> R<T> error(String msg) {R r = new R();r.msg = msg;r.code = 0;return r;}public R<T> add(String key, Object value) {this.map.put(key, value);return this;}}

3 功能测试

3.1 登陆功能测试

代码实现完毕后, 启动项目, 访问url: http://localhost:8080/backend/page/login/login.html , 进行登录测试。

在测试过程中, 可以通过debug断点调试的方式来跟踪程序的执行过程,并且可以查看程序运行时各个对象的具体赋值情况。而且需要注意, 在测试过程中,需要将所有的情况都覆盖到。

3.2 登出功能测试

5.3 功能测试

1). 代码实现完毕后, 重启服务, 访问登录界面 http://localhost:8080/backend/page/login/login.html ;

2). 登录完成之后, 进入到系统首页 backend/index.html, 点击右上角退出按钮执行退出操作, 完成后看看是否可以跳转到登录页面 , 并检查localStorage。

退出前:

  退出后:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469063.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python中sys模块有什么用_Python中模块之sys的功能介绍

argv 命令行参数 方法&#xff1a;sys.argv 返回值&#xff1a;list 例如&#xff1a;test1.py文件中有两句语句1.import sys 2.print(sys.argv) python test1.py 2 3 df >>> [test1.py,2,3,df] #该方法返回的列表中第一个元素为程序的路径,会把执行参数传入到列表中 …

排序算法时间复杂度、空间复杂度、稳定性比较

排序算法分类 排序算法比较表格填空 排序算法平均时间复杂度最坏时间复杂度空间复杂度是否稳定冒泡排序:————-::—–::—–::—–:选择排序:————-::—–::—–::—–:直接插入排序:————-::—–::—–::—–:归并排序:————-::—–::—–::—–:快速排序:———…

基于Springboot外卖系统05:用户非登陆状态的页面拦截器实现

1. 完善登录功能 1.1 问题分析 用户访问接口验证&#xff0c;如果用户没有登录&#xff0c;则不让他访问除登录外的任何接口。 1.前端登录&#xff0c;后端创建session&#xff0c;返给前端 2.前端访问其他接口&#xff0c;失效或不存在&#xff0c;则返回失效提示&#xff…

Sargable 与 谓语下推 (predicate pushdown) 简介

关键词&#xff1a;SQL优化 , sargable , pushdown filter , predicate pushdown Sargable Sargable Search ARGument ABLE &#xff0c;即SQL中可利用数据库自身索引优势对查询条件进行执行性能优化。换句话说&#xff0c;即可以利用存储层的索引优势来优化的查询条件。wikip…

python删除指定行_关于csv:删除python中的特定行和对应文件

我想删除90%的"转向"值等于0的行。这三个图像都有一个对应的图像文件&#xff0c;中间&#xff0c;左边和右边。我也要删除它们。csv文件如下&#xff1a;我编写了以下代码&#xff0c;以至少获取转向值为0的文件。我所需要的就是随机获取90%的文件并删除它们的代码。…

I2C总线传输协议

简介 I2C&#xff08;Inter-integrated Circuit&#xff09;总线支持设备之间的短距离通信&#xff0c;用于处理器和一些外围设备之间的接口&#xff0c;它只需要两根信号线来完成信息交换。I2C最早是飞利浦在1982年开发设计并用于自己的芯片上&#xff0c;一开始只允许100kHz…

基于Springboot外卖系统06: 新增员工功能+全局异常处理器

2. 新增员工 2.1 需求分析 后台系统中可以管理员工信息&#xff0c;通过新增员工来添加后台系统用户。点击[添加员工]按钮跳转到新增页面&#xff0c;如下 当填写完表单信息, 点击"保存"按钮后, 会提交该表单的数据到服务端, 在服务端中需要接受数据, 然后将数据保…

Linq 实现sql中的not in和in条件查询

T-SQL的IN&#xff1a; Select ProductID, ProductName, CategoryID From dbo.Products Where CategoryID in (1, 2)T-SQL的NOT IN&#xff1a; Select ProductID, ProductName, CategoryID From dbo.Products Where CategoryID not in (1, 2)Or Select ProductID, ProductName…

spring aop实现原理_Spring 异步实现原理与实战分享

最近因为全链路压测项目需要对用户自定义线程池 Bean 进行适配工作&#xff0c;我们知道全链路压测的核心思想是对流量压测进行标记&#xff0c;因此我们需要给压测的流量请求进行打标&#xff0c;并在链路中进行传递&#xff0c;那么问题来了&#xff0c;如果项目中使用了多线…

基于Springboot外卖系统07:员工分页查询+ 分页插件配置+分页代码实现

1. 员工分页查询 1.1 需求分析 在分页查询页面中, 以分页的方式来展示列表数据&#xff0c;以及查询条件 "员工姓名"。 请求参数 搜索条件&#xff1a; 员工姓名(模糊查询) 分页条件&#xff1a; 每页展示条数 &#xff0c; 页码 响应数据 总记录数 结果列表 1…

1045-Access denied for user 'root'@'localhost'(using password:YES)

解决&#xff1a; 1. 开始 --> cmd --> net stop mysql (停用MySQL服务 没启动的可以省略) 2. 找到安装路径 MySQL Server 5.1下的my.ini 3. 打开 my.ini 找到 [mysqld] 然后在下面加上 这句&#xff1a; skip_grant_tables &#xff08;意思好像是 启动MySQL服务…

arial字体可以商用吗_【工作总结】莫让字体版权引火上身

前段一条微软雅黑字体引发的巨额罚款新闻&#xff0c;引起国内多个TW大群小地震&#xff0c;人人自危。我也赶紧检查自家文档、商用出版物、网站的字体&#xff0c;以免给公司带来法务后患。把这两天收集的信息&#xff0c;采取的行动记录一下。哪些中文字体免费&#xff1f;事…

基于Springboot外卖系统08:员工账号状态管理功能+对象转换器+扩展Spring mvc的消息转换器

1. 员工账号状态管理 1.1 需求分析 在员工管理列表页面&#xff0c;可以对某个员工账号进行启用或者禁用操作。账号禁用的员工不能登录系统&#xff0c;启用后的员工可以正常登录。如果某个员工账号状态为正常&#xff0c;则按钮显示为 "禁用"&#xff0c;如果员工…

Android init.rc 服务启动不成功

Android init.rc 服务启动不成功 问题 在开发过程中发现一个问题&#xff0c;我们需要在开机的时候判断硬件版本号去启动服务&#xff0c; 服务的名字是ledservice和ledservice4,但是发现每次烧录完固件后&#xff0c;服务启动不 成功&#xff0c;需要再复位重启一次&#xff0…

python爬虫什么网站都能爬吗_python如何爬取动态网站

python有许多库可以让我们很方便地编写网络爬虫&#xff0c;爬取某些页面&#xff0c;获得有价值的信息&#xff01;但许多时候&#xff0c;爬虫取到的页面仅仅是一个静态的页面&#xff0c;即网页 的源代码&#xff0c;就像在浏览器上的“查看网页源代码”一样。一些动态的东西…

hdu4027Can you answer these queries?

题目链接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid4027 区间&#xff08;单点&#xff09;更新&#xff0c;区间求和。 1 #include<cstdio>2 #include<algorithm>3 #include<cmath>4 #define lson l,m,rt<<15 #define rson m1,r,rt<…

基于Springboot外卖系统09:员工信息编辑+员工信息保存

1 编辑员工信息功能 1.1 需求分析 在员工管理列表页面点击 "编辑" 按钮&#xff0c;跳转到编辑页面&#xff0c;在编辑页面回显员工信息并进行修改&#xff0c;最后点击 "保存" 按钮完成编辑操作。 那么从上述的分析中&#xff0c;当前实现的编辑功能需…

共享资料

共享资料 请关注公众号 嵌入式Linux 索取posted on 2018-09-22 00:27 公众号&#xff1b;嵌入式Linux 阅读(...) 评论(...) 编辑 收藏

selenium-05-常见问题

一&#xff1a;日期控件 selenium不能直接对日期控件操作&#xff0c;可以通过js对日期控件做赋值操作 WebElement inputTimeBoxdriver.findElement(by.name("###")); //定位日期控件 Stringtime "2015/10/10"; ((JavascriptExecutor)driver).executeScri…

bcp 不能调用where 子句_MySQL中IS NULL、IS NOT NULL、!=不能用索引?胡扯!

不知道从什么时候开始&#xff0c;网上流传着这么一个说法&#xff1a;MySQL的WHERE子句中包含 IS NULL、IS NOT NULL、! 这些条件时便不能使用索引查询&#xff0c;只能使用全表扫描。这种说法愈演愈烈&#xff0c;甚至被很多同学奉为真理。咱啥话也不说&#xff0c;举个例子。…