瑞吉外卖01-实现管理端登录登出功能

开发前准备

准备数据表

结合页面原型创建数据库reggie,可以使用图形化界面或者MySQL命令运行SQL文件导入表结构(使用命令时sql文件不要放在中文目录中)

在这里插入图片描述

创建工程

创建一个SpringBoot的工程(勾选Spring Web,MySQL和MyBatis),配置pom.xml文件导入druid,lombok和MyBatisPlus依赖的坐标

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.16</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.1</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

配置applicaton.yml文件

server:
  port: 8080
spring:
application:
  # web应用的名称(默认就是工程名)
  name: reggie_take_out
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/reggie?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
      username: root
      password: 123456
  redis:
    host: localhost
    port: 6379
    database: 0
  cache:
    redis:
      time-to-live: 1800000  #ms ->30min
mybatis-plus:
  configuration:
  	# 在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法开启映射(默认就是true)
    map-underscore-to-camel-case: true
    # 开启日志功能
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      id-type: ASSIGN_ID
reggie:
  path: D:\SpringBoot_Reggie\reggie_take_out\src\main\resources\static\front\hello\

创建主程序类并使用@SpringBootApplication注解, 告诉SpringBoot这是一个SpringBoot应用并且是所有程序的启动入口

@Slf4j
@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        SpringApplication.run(MainApplication.class, args);
        log.info("项目启动成功...");
    }
}

在请求控制器中创建处理请求的方法

@Slf4j
@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String handle01(@RequestParam("name") String name){
        log.info("请求进来了....");
        return "Hello, Spring Boot 2!"+"你好:"+name;
    }
}

静态资源映射

Spring Boot工程中引入的静态资源需要放到static或者templates目录下才能访问到

  • 访问resources目录下的静态资源需要编写配置类config/WebMvcConfig配置一下资源映射放行这些资源

打开浏览器访问登录页面(暂无法登录)http://localhost:8080/backend/page/login/login.html

@Configuration
@Slf4j
public class WebMvcConfig extends WebMvcConfigurationSupport {
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        log.info("开始进行静态资源映射...");
        // 根据用户的请求路径映射到对应的请求资源目录
        registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
        registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
    }
}

统一结果封装

编写一个通用结果类common/Result封装所有Controller的返回结果, 服务器响应给前端的所有数据最终都会包装成此种类型中

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result<T> {
    private Integer code;  // 编码:1成功,0和其他数字失败
    private String errMsg;  // 错误信息
    private T data; // 数据(如响应的实体类数据)
    private Map map = new HashMap();  // 动态数据

    public static <T> Result<T> success(T data) {
        Result<T> r = new Result<>();
        r.code = 1;  //成功状态码
        r.data = data;
        return r;
    }
 
    public static <T> Result<T> error(String errMsg) {
        Result<T> r = new Result<>();
        r.errMsg = errMsg; //设置错误信息
        r.code = 0;  //默认失败状态码,后期我们可以根据自己的需求来设置其他状态码
        return r;
    }

    public Result<T> add(String msg, String value) {
        this.map.put(msg, value);
        return this;
    }
}

登录和登出功能

前端登录登出效果

在这里插入图片描述

new Vue({
    methods: {
        async handleLogin() {
            // 校验用户名和密码是否为空,validate是element框架提供的校验方法
            this.$refs.loginForm.validate(async (valid) => {
                if (valid) {
                    // 渲染登录的状态,true表示登录中
                    this.loading = true
                    // res是服务端响应的结果(一般是一个通用结果封装类) 
                    let res = await loginApi(this.loginForm)
                    if (String(res.code) === '1') {// 1表示登录成功
                        localStorage.setItem('userInfo',JSON.stringify(res.data))// data表示实体类数据
                        window.location.href= '/backend/index.html'
                    } else {
                        this.$message.error(res.msg)
                        this.loading = false
                    }
                }
            })

            logout() {
                logoutApi().then((res)=>{
                    if(res.code === 1){
                        localStorage.removeItem('userInfo')
                        window.location.href = '/backend/page/login/login.html'
                    }
                })
            },
        }
    }
}) 

<div class="right-menu">
    <!--这里动态的显示登录的用户名-->
    <div class="avatar-wrapper">{{ userInfo.name }}</div>
	<!--这里就是登出的按钮-->
    <img src="images/icons/btn_close@2x.png" class="outLogin" alt="退出" @click="logout" />
</div>

<div class="right-menu">
    // userInfo就是登录成功后后端响应的用户信息
    <div class="avatar-wrapper">{{ userInfo.name }}</div>
	<img src="images/icons/btn_close@2x.png" class="outLogin" alt="退出" @click="logout" />
</div>

function loginApi(data) {
    return $axios({
        'url': '/employee/login',
        'method': 'post',
        data
    })
}

function logoutApi(){
    return $axios({
        'url': '/employee/logout',
        'method': 'post',
    })
}

登录和登出的业务流程

第一步: 创建对应的实体类Employee

@Data
public 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;
    private String idNumber;
    private Integer status;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
    // 这两个先不用管,后面再说
    @TableField(fill = FieldFill.INSERT)
    private Long createUser;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateUser;
}

第二步: 创建对应的Mapper和Service

// 直接将Mapper接口动态生成的代理类交给Spring容器管理(不需要再扫描mapper接口)
@Mapper
public interface EmployeeMapper extends BaseMapper<Employee> {
}
public interface EmployeeService extends IService<Employee> {
}

//继承ServiceImpl实现EmployeeService接口,别忘了@Service注解
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {
}

第三步: 在Controller中编写登录方法

在这里插入图片描述

@RestController
@RequestMapping("/employee")
public class EmployeeController {
    @Autowired
    private EmployeeService employeeService;
    /**
     * 登入功能
     * @param request   
     * @param employee
     * @return
     */
    // 登录页面发送post请求提交用户名和密码
    @PostMapping("/login")
    // 将页面提交的用户名和密码封装到Employee对象中
    public Result<Employee> login(HttpServletRequest request, @RequestBody Employee employee) {
        String password = employee.getPassword();
        // spring内部提供的工具类可以将密码进行MD5加密处理
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        // 根据页面提交的用户名查询数据库
        LambdaQueryWrapper<Employee> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Employee::getUsername, employee.getUsername());
        Employee emp = employeeService.getOne(lqw);
        // 没有查询到员工则返回登录失败的结果
        if (emp == null) {
            return Result.error("登陆失败");
        }
        // 与查询到的员工密码进行比对,如果不一致则返回登录失败的结果
        if (!emp.getPassword().equals(password)) {
            return Result.error("登录失败");
        }
        // 查看查询到员工的状态,如果是已禁用状态,则返回员工已禁用结果
        if (emp.getStatus() == 0) {
            return Result.error("该用户已被禁用");
        }
        // 登录成功,将员工id存入Session并返回登录结果
        request.getSession().setAttribute("employee",emp.getId());
        return Result.success(emp);
    }
} 

第四步: 在Controller中编写退出方法

/**
* 登出功能
* @param request
* @return
*/
@PostMapping("/logout")
public Result<String> logout(HttpServletRequest request) {
    // 清理Session中保存的当前登录员工的id
    request.getSession().removeAttribute("employee");
    // 返回结果
    return Result.success("退出成功");
}

登录状态校验

我们不登录直接访问 http://localhost/backend/index.html也可以正常访问首页显然是不合理的,所以需要用到过滤器或拦截器

过滤器或拦截器中判断用户是否登录,只有登录成功才能看到首页面,未登录状态则跳转到登录页面

在这里插入图片描述

第一步: 设置过滤器,/*表示处理所有请求

@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
    //Spring提供的工具类,专门用于路径匹配
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 强转
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //1.获取本次请求的URI
        String requestURI = request.getRequestURI();
        // 将拦截到的URI输出到日志,{}是占位符将自动填充request.getRequestURI()的内容
        log.info("拦截到请求:{}",requestURI);

        // 定义不需要处理的所有请求
        String[] urls = new String[]{
                "/employee/login",
                "/employee/logout",
            	// 访问backend和front目录下的静态页面的请求不需要拦截,但是页面中通过Ajax请求渲染的数据需要拦截
                "/backend/**",
                "/front/**"
        };
        //2.判断本次请求是否需要处理
        boolean check = check(urls, requestURI);
        //3.如果不需要处理,则直接放行
        if (check) {
            log.info("本次请求:{},不需要处理",requestURI);
            filterChain.doFilter(request,response);
            return;
        }
        //4.对于需要处理的请求,需要判断登录状态,如果已登录则直接放行
        if (request.getSession().getAttribute("employee") != null) {
            log.info("用户已登录,id为{}",request.getSession().getAttribute("employee"));
            filterChain.doFilter(request,response);
            return;
        }
        //5.如果未登录则返回一个Result对象且msg为NOTLOGIN
        log.info("用户未登录");
        // ,
        // 导入fastjson的坐标将Result对象转化为Json格式的字符串,然后通过输出流方式响应给客户端
        response.getWriter().write(JSON.toJSONString(Result.error("NOTLOGIN")));

    }

    public boolean check(String[] urls, String requestURI){
        for (String url : urls) {
            boolean match = PATH_MATCHER.match(url, requestURI);
            if (match) {
                //匹配
                return true;
            }
        }
        //不匹配
        return false;
    }
}

第二步: 前端设置响应拦截器,获取后端响应的用户信息,如果用户未登录则自动重定向到登录页面

// 响应拦截器
service.interceptors.response.use(res => {
    if (res.data.code === 0 && res.data.msg === 'NOTLOGIN') {// 返回登录页面
        console.log('---/backend/page/login/login.html---')
            localStorage.removeItem('userInfo')
            // 跳转到登录页面
            window.top.location.href = '/backend/page/login/login.html'
    } else {
        return res.data
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

打破时空界限的虚拟线上会议大厅:多人在线互动的未来

引言&#xff1a; 在数字时代&#xff0c;迅猛发展的科技不仅改变了我们的日常生活&#xff0c;也深刻地影响着商务和社交领域。虚拟会议大厅&#xff0c;作为一种创新的交流平台&#xff0c;正以其多人同时在线、音视频通话和直播推流的强大功能&#xff0c;展现着新时代的会…

2023最新整理软件测试常见面试题附答案

包含的模块&#xff1a; 本文分为十九个模块&#xff0c;分别是&#xff1a;软件测试 基础、liunx、MySQL、web测试、接口测试、APP测试 、管理工具、Python、性能测试、selenium、lordrunner、计算机网络、组成原理、数据结构与算法、逻辑题、人力资源需要的点击文末获取&…

海思平台awb标定

文章目录 1、raw图采集2、awb标定3、标定效果优化1、raw图采集 raw图采集标准: 如果raw是12bit,即raw12,那么Block9 块的亮度就是40960.8 = 3276.8左右。 勾上Dump Raw,我这里raw10,即Depth为10bit,那么Block19的亮度应该为10240.8 = 819.2左右,调整曝光Exposure Attr…

深入探讨跨境电商商城源码的多语言、多货币、多商户入驻支持“

随着全球电子商务的飞速发展&#xff0c;跨境电商已成为一股不可忽视的力量。在这个背景下&#xff0c;为跨境电商商城源码提供多语言、多货币、多商户入驻支持显得尤为重要。本文将深入探讨这三大特性的实现方式及其对跨境电商发展的影响。 一、多语言支持 对于跨境电商来说&a…

多数据源切换

多数据源切换 1.jdbcTemplate2.使用切面3.mybatis层次的多数据源4.spring的dynamic自动注入 项目中经常会有多个数据源&#xff0c;那么如何处理呢 有4种方法 准备&#xff1a; 创建两个数据库 CREATE SCHEMA test DEFAULT CHARACTER SET utf8mb4 ; CREATE SCHEMA school DEFA…

【Debug】此语法需要一个导入的帮助程序,但找不到模块“tslib”

报错如下&#xff1a; 代码可以编译运行&#xff0c;但是会有红线和报错。 解决方法&#xff1a;TypeScript error “TS2354: This syntax requires an imported helper but module ‘tslib’ cannot be found” Issue #37991 microsoft/TypeScript GitHub 在tsconfig.jso…

MacOS下VMware Fusion配置静态IP

前言 在虚拟机安装系统后&#xff0c;默认是通过DHCP动态分配的IP&#xff0c;这会导致每次重启虚拟机ip都可能会改变&#xff0c;使用起来会有很多不便。 配置静态IP 查看主机网关地址 cat /Library/Preferences/VMware\ Fusion/vmnet8/nat.conf 查看主机DNS&#xff0c;m…

3种方法,教你用Pytest更改自动化测试用例执行顺序!

前言 在自动化测试中&#xff0c;自动化测试用例设计原则就是&#xff1a;执行过程时不能存在依赖顺序。那么如果测试用例需要按照指定顺序执行&#xff0c;这个时候应该怎么做呢&#xff1f; 目前单元测试框架中UnitTest没有办法改变测试用例的执行顺序&#xff0c;但是另一…

数据结构-数型查找

二叉排序树&#xff08;BST&#xff09; 二叉排序树&#xff0c;又称二叉查找树&#xff08;BST&#xff0c;Binary Search Tree&#xff09; 一颗二叉树或者是空二叉树&#xff0c;或者是具有如下性质的二叉树&#xff1a; 左子树上所有结点的关键字均小于根结点的关键字&…

微信支付配置完整操作手册

微信支付配置 必须申请开通微信支付 微信支付官方地址&#xff1a;https://pay.weixin.qq.com/index.php/core/home/login?return_url%2F 申请指引&#xff1a;https://pay.weixin.qq.com/index.php/public/bare_applyment/login4bank 百度经验&#xff1a;https://jingyan.b…

什么是智能井盖?万宾科技的智能井盖传感器的效果

近年来为打造智慧城市政府一直在不懈努力。加速城市基础建设是一项重要的举措&#xff0c;它有助于推动城市综合治理城市生命线的建设工程。在改善市民生活质量的过程中&#xff0c;市政部门正积极进行井盖的改进和升级工作&#xff0c;特别是那些看似微不足道的井盖却蕴含着重…

实时数仓-Flink使用总结

阿里云实时计算Flink版是阿里云基于Apache Flink构建的企业级、高性能实时大数据处理系统。具备一站式开发运维管理平台&#xff0c;支持作业开发、数据调试、运行与监控、自动调优、智能诊断等全生命周期能力。本期将对Flink的使用进行总结。 1. Flink产品回顾 阿里云实时计算…

第八章 :如何基于Spring Boot +Mybatis 快速开发 Restful API

第八章 :如何基于Spring Boot +Mybatis 快速开发 Restful API 前言 本章知识重点:主要讲解开发人员如何利用【MybatisPlus+EasyCode插件 】快速开发Restful API ,利用节约的时间学习,养成一种正向循环的技术之道,最后达到终身学习成长! 案例基于SpringBoot 2.3.2.RELEASE…

北斗卫星为油气管道安全保障提供可靠技术支持

北斗卫星为油气管道安全保障提供可靠技术支持 随着现代社会对能源需求的不断增长&#xff0c;油气管道成为了能源输送的重要通道。然而&#xff0c;油气管道的安全风险也日益凸显。为了及时掌握油气管道的运行状态并有效地监测其安全状况&#xff0c;北斗卫星技术为油气管道监测…

企业真正的性能测试,压测-内存泄露案例分析,一篇概全...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、环境配置 1&a…

OCR转换技巧:如何避免图片转Word时出现多余的换行?

在将图片中的文字识别转换为Word文档时&#xff0c;我们很多时候时会遇到识别内容的一个自然段还没结束就换行的问题&#xff0c;这些就是我们常说的多余换行的问题。为什么会产生这个问题呢&#xff1f;主要是由于OCR返回的识别结果是按图片上的文字换行而换行&#xff0c;而不…

VM虚拟机只有一个C盘怎么添加硬盘新分区盘符

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 前言 VM虚拟机中安装Window 系统后&#x…

Docker学习——⑦

文章目录 1、Docker 为什么需要网络管理2、Docker 网络架构简介2.1 CNM2.2 Libnetwork2.3 驱动 3、常见网络类型4、docker 网络管理命令5、网络详解5.2 docker Bridge 网络5.2 docker Host 网络5.3 docker Container 网络5.4 docker none 网络 1、Docker 为什么需要网络管理 容…

北京永达理慈善基金会与望京街道携手,为乡村振兴贡献10万元

东西部协作是推进巩固脱贫攻坚成果同乡村振兴有效衔接的重要手段。北京市朝阳区人民政府望京街道办事处自2021年起与内蒙古自治区通辽市科左后旗散都苏木、查日苏镇开展为期五年的结对帮扶工作&#xff0c;并号召全社会各界企事业单位及爱心人士帮扶助力&#xff0c;奉献爱心。…

新加坡建筑设备公司【Ten-League】申请3230万美元纳斯达克IPO上市

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;总部位于新加坡的重型建筑设备和工程咨询服务公司Ten-League International Holdings Limited&#xff08;简称&#xff1a;Ten-League&#xff09;近期已向美国证券交易委员会&#xff08;SEC&am…