Java Web项目—餐饮管理系统Day02-管理员后台开发(一)登录

文章目录

      • 1. 创建实体类
      • 2. 创建三层调用结构
        • mapper
        • service
        • controller
      • 3. 登录逻辑实现
      • 4. 过滤器/拦截器

登录功能开发, 主要是要校验登录账号及密码的准确性, 注意密码使用 base64 加密.
另外一个最重要的是要记住当前用户的id以记住登录状态, 并使用拦截器, 对于部分请求, 需要先校验登录状态, 若校验成功才放行.

1. 创建实体类

登录业务逻辑涉及到的是员工的登录与管理, 创建 Employee 实体类, 它包装 MySQL 查询返回的数据:

package com.rain.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;/*** 员工实体*/
@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;
}

2. 创建三层调用结构

mapper

创建 mapper 层, 它负责实际的数据库操作, 同时借助于 mybatisplus, 它的编写十分简洁:

package com.rain.reggie.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.rain.reggie.entity.Employee;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface EmployeeMapper extends BaseMapper<Employee>{
}

接口先被声明为 Mapper 接口, 接着它继承了 mybatisplus 中的 BaseMapper, 同时指明泛型类型为 Employee.

service

创建 service 层, 该层负责接受 controller 的业务需求, 调用 Mapper 层完成业务逻辑开发.
对于 service 层, 需要设计接口和实现类:

package com.rain.reggie.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.rain.reggie.entity.Employee;public interface EmployeeService extends IService<Employee> {
}
package com.rain.reggie.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rain.reggie.entity.Employee;
import com.rain.reggie.mapper.EmployeeMapper;
import com.rain.reggie.service.EmployeeService;
import org.springframework.stereotype.Service;@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper,Employee> implements EmployeeService{
}

注意实现类先继承了 ServiceImpl, 指明泛型类型, 接着实现了 EmployeeService 接口.

controller

来到顶层的设计 controller 层, 该层负责接受前端发送的请求, 解析请求参数, 调用 service 层获得结果, 将结果封装后返回前端.

注意请求路径、请求方式、响应结果的形式、请求需要完成的功能等等在 API 文档中有明确规定.
这里需要创建一个通用的数据返回实体类, 包括数据内容/消息/响应码. 另外还包含一个临时字典.

public class R<T>{private String msg;private Integer code;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. 登录逻辑实现

员工登录

  1. 获取密码并进行md5加密
  2. 查询数据库校验是否存在该用户(用户名)
  3. 不存在则直接返回失败信息
  4. 否则继续校验密码
  5. 不匹配则直接返回失败信息
  6. 否则继续校验用户状态
  7. 若为禁用状态则返回失败信息
  8. 否则登陆成功, 返回成功信息, 同时向请求中写入登录信息, 也即员工ID.

注意 mybatisplus 的使用方法:

package com.rain.reggie.controller;@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {@Autowiredprivate EmployeeService employeeService;// http://localhost:8080/backend/page/login/login.html@PostMapping("/login")public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(Employee::getUsername, employee.getUsername());Employee query = employeeService.getOne(queryWrapper);String pwd = employee.getPassword();pwd = DigestUtils.md5DigestAsHex(pwd.getBytes())if (query == null)return R.error("用户不存在");if (!query.getPassword().equals(pwd))return R.error("密码错误");if (query.getStatus() == 0)return R.error("账户已停用");request.getSession().setAttribute("employee", result.getId());return R.success(query);}// 登出@PostMapping("/logout")public R<String> logout(HttpServletRequest request){//清理Session中保存的当前登录员工的idrequest.getSession().removeAttribute("employee");return R.success("退出成功");}
}

4. 过滤器/拦截器

为了实现未登录则无法访问后台资源的效果, 需要编写过滤器或者拦截器, 这里采用过滤器.
实现的关键点在于 @WebFilter 注解和重写 doFilter() 方法
先获取到请求路径, 检查路径是否需要拦截, 不需要拦截的例如登入登出请求以及静态资源访问请求等.
对于需要拦截的, 检查会话中是否存储 “employee” 键值对, 若检查到该键值对, 表示已登录
直接放行, 否则向响应中写入错误状态字符串.

package com.rain.reggie.filter;@Slf4j
@WebFilter(filterName = "loginFilter", urlPatterns = "/*")
public class LoginFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;String uri = request.getRequestURI();log.info("拦截到请求{}", uri);if (ok(uri)){log.info("本次请求{}不需要处理", uri);filterChain.doFilter(request, response);return;}if (null != request.getSession().getAttribute("employee")){log.info("已登录");filterChain.doFilter(request, response);return;}log.info("未登录");response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));}private static boolean ok(String uri){AntPathMatcher matcher = new AntPathMatcher();String[] ok_list = {"/employee/login","/employee/logout","/backend/**","/front/**"};for (String u: ok_list){if (matcher.match(u, uri))return true;}return false;}
}

注意为了使过滤器生效, 需要添加 Servlet 包扫描注解.

package com.rain.reggie;@SpringBootApplication
@ServletComponentScan
public class Reggie001Application {public static void main(String[] args) {SpringApplication.run(Reggie001Application.class, args);}}

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

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

相关文章

从原理总结chatGPT的Prompt的方法

ChatGPT的Prompt方法是一种引导模型生成对话的技术&#xff0c;它基于前面已经提供的上下文信息&#xff0c;以及一个特定的输入格式来指导模型生成合理、连贯的回答。以下是ChatGPT Prompt方法的原理总结&#xff1a; 输入格式&#xff1a;Prompt方法将对话分为多个轮次&#…

外观模式实战运用

前言 即使在没有学习过设计模式之前&#xff0c;只要是写过代码&#xff0c;都会在不经意间使用到外观模式&#xff0c;或者说用到了外观模式的思想。 外观模式的定义&#xff1a;通过创建一个统一的高层接口&#xff0c;使得复杂的子系统更加容易使用。这个模式为复杂的系统…

Seata 2.x 系列【10】回滚日志表 undo_log

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Seata 版本 2.0.0 本系列Spring Boot 版本 3.2.0 本系列Spring Cloud 版本 2023.0.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 概述2. 表语句…

【Java 并发】AbstractQueuedSynchronizer 中的 Condition

1 简介 任何一个 Java 对象都天然继承于 Object 类, 在线程间实现通信的往往会应用到 Object 的几个方法, 比如 wait(), wait(long timeout), wait(long timeout, int nanos) 与 notify(), notifyAll() 几个方法实现等待 / 通知机制。同样的, 在 Java Lock 体系下也有同样的方…

[C++核心编程](十):文件操作

目录 文件类型 文件三大类 写文本文件 读文本文件 写二进制文件 读二进制文件 文件打开方式 程序运行时产生的数据都属于临时数据&#xff0c;程序一旦运行结束都会被释放&#xff0c;因此通过文件可以将数据持久化 C中对文件操作需要包含头文件<fstream> 文件类…

每日shell脚本之邮件

每日shell脚本之邮件 以下是一个简单的脚本&#xff0c;它接收三个参数&#xff1a;收件人地址、邮件主题和邮件内容。这个脚本将使用系统的默认邮件服务器来发送邮件。 #!/bin/bash# 检查参数数量 if [ $# -ne 3 ]; thenecho "使用方法&#xff1a; $0 <收件人邮箱&…

工具篇--分布式定时任务springBoot--elasticjob简单使用(1)

文章目录 前言一、elasticjob 介绍&#xff1a;二、elasticjob 使用&#xff1a;2.1 部署zookeeper&#xff1a;2.2 引入库2.2 定义任务&#xff1a;2.3 任务执行&#xff1a;2.4 任务执行控制台输出&#xff1a; 三、elasticjob 启动错误&#xff1a;3.1 KeeperErrorCode Ope…

Linux系统架构----Nginx的服务优化

Linux系统架构----Nginx的服务优化 一.隐藏版本号 在生产环境中&#xff0c;需要隐藏Nginx的版本号&#xff0c;以免泄露Nginx的版本&#xff0c;使得攻击者不能针对特定版本进行攻击 查看Nginx的版本有两种方法 使用fiddler工具抓取数据包&#xff0c;查看Nginx版本 在Cen…

【Node.js从基础到高级运用】十二、身份验证与授权:JWT

身份验证与授权是现代Web应用中不可或缺的部分。了解如何在Node.js应用中实施这些机制&#xff0c;将使你能够构建更安全、更可靠的应用程序。本文将引导你通过使用JWT实现用户注册、登录和权限控制的过程。 JWT&#xff08;Json Web Token&#xff09; JWT是一种用于双方之间…

蓝桥杯深度优先搜索|剪枝|N皇后问题|路径之谜(C++)

搜索&#xff1a;暴力法算法思想的具体实现 搜索&#xff1a;通用的方法&#xff0c;一个问题如果比较难&#xff0c;那么先尝试一下搜索&#xff0c;或许能启发出更好的算法 技巧&#xff1a;竞赛时遇到不会的难题&#xff0c;用搜索提交一下&#xff0c;说不定部分判题数据很…

R语言tidycmprsk包分析竞争风险模型

竞争风险模型就是指在临床事件中出现和它竞争的结局事件&#xff0c;这是事件会导致原有结局的改变&#xff0c;因此叫做竞争风险模型。比如我们想观察患者肿瘤的复发情况&#xff0c;但是患者在观察期突然车祸死亡&#xff0c;或者因其他疾病死亡&#xff0c;这样我们就观察不…

基于单片机的太阳能热水器控制系统设计与仿真

目录 摘要 3 Controling system design and simulation of the solar water heater based on single chip microcomputer 4 第一章 前言 5 1.1设计背景和意义 5 1.2国内外的发展趋势 5 第二章 系统设计总览 7 2.1控制中心 7 2.2外围设备 7 第三章 系统硬件设计 8 3.1 总硬件的…

小程序路由跳转---事件通信通道EventChannel(二)

事件通信通道EventChannel实现两个页面之间的数据传输已在上篇小程序路由跳转—事件通信通道EventChannel&#xff08;一&#xff09;展开叙述&#xff0c;接下来讨论下多个页面&#xff08;三个及以上&#xff09;数据的通道如何构建。 本文重点&#xff1a;三个以上页面需将…

jenkin部署spring boot项目【从0到1】

写在前面&#xff0c;遇到的很多错误 本来想用docker启动Jenkins的&#xff0c;也这样做了&#xff0c;但是遇到了一个非常严重的问题&#xff0c;就是mvn命令在docker里面不生效&#xff0c;然后就修改文件&#xff0c;但是发现vi不存在&#xff0c;好的。接着用yum安装vi工具…

【Stable Diffusion】入门-02:AI绘画提示词+参数设置攻略

目录 1 提示词1.1 分类和书写方式1.1.1 内容型提示词1.1.2 标准化提示词1.1.3 通用模板 1.2 权重1.2.1 套括号1.2.2 数字权重1.2.3 进阶语法 1.3 负面提示词 2 参数详解2.1 Sampling steps2.2 Sampling method2.3 Width, Height2.4 CFG Scale2.5 Seed2.6 Batch count, Batch si…

Vue2 引入自己下载的SVG图像的方式

Vue2 引入下载的SVG图像的方式 Step 1&#xff1a;安装依赖 npm i svg-sprite-loader --saveStep 2&#xff1a;创建文件路径 // index.js import Vue from vue import SvgIcon from /components/SvgIcon// svg component// register globally Vue.component(svg-icon, Svg…

pytorch fasterrcnn-resnet50-fpn 神经网络 目标识别 应用 —— 逻辑概述

pytorch fasterrcnn-resnet50-fpn 神经网络 目标识别 应用 —— 逻辑概述 前提&#xff1a;工欲善其事必先利其器一、逻辑概述1 模型训练1) 训练数据2) 网络结构 2 推理识别 [下一章 推理识别代码讲解](https://blog.csdn.net/qq_42239488/article/details/126309847)&#xff…

《JAVA与模式》之抽象工厂模式

系列文章目录 文章目录 系列文章目录前言一、使用简单工厂模式的解决方案二、引进抽象工厂模式三、抽象工厂模式结构四、抽象工厂模式的优缺点前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看…

Hubspot 2023年推荐使用的11个AI视频生成器

视频是任何营销活动不可或缺的一部分&#xff1b;然而&#xff0c;如果你不懂编辑或时间紧迫&#xff0c;它们可能会很乏味&#xff0c;很难创建。一只手从电脑里伸出来&#xff0c;拳头碰到另一只手&#xff1b;代表AI视频生成器。 幸运的是&#xff0c;你可以利用许多人工智能…

【数据分析】数据分析介绍

专栏文章索引&#xff1a;【数据分析】专栏文章索引 目录 一、介绍 二、生活中的数据分析 1.无处不在的数据 2.为什么要进行数据分析&#xff1f; 三、数据挖掘案例 1.案例分析 一、介绍 数据采集&#xff1a;数据采集是指从不同来源收集原始数据的过程&#xff0c;包括…