瑞吉外卖实战-笔记

软件开发的流程
在这里插入图片描述

角色分工
在这里插入图片描述

软件环境
在这里插入图片描述

开发环境的搭建

数据库环境

maven环境
1.创建完成后,需要检查一下编码、maven仓库、jdk等

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.12</version>
</parent>
//注意:3.0版本以下使用的java版本是11,

2.导入pom

 <dependencies>
<!--sb的起步依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency>
<!--sb的测试依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
<!--springboot的web使用依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><scope>compile</scope></dependency>
<!--mybatisplus的起步依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version></dependency>
<!--json数据包--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.76</version></dependency><dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.6</version></dependency>
<!--数据库的驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope><version>8.0.33</version></dependency>
<!--数据源的依赖--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.23</version></dependency>
<!--阿里云的短信服务--><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>4.0.3</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-dysmsapi</artifactId><version>1.1.0</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.4.5</version>
</plugin>
</plugins>
</build>

1.Filter-过滤器

作用:用于登录校验,未登录禁止访问

@WebFilter(filterName = "EmployeeLoginFilter",urlPatterns = "/*"),申明过滤器,名称自取,拦截路径为所有路径
想要使用过滤器,需要在启动类添加 @ServletComponentScan 注解

实现逻辑

  1. 创建一个类,实现Filter
  2. 重写doFilter方法
  3. 定义放行的路径数组
String[] url=new String[]
{ "/employee/login","/employee/logout","/common/**","/user/sendMsg","/user/login","/backend/**","/front/**"
};
//"/employee/login","/employee/logout"这是controller中的路径
//"/backend/**""/common/**",静态资源路径,即前端页面代码,路径从resources第一个包开始

4.获取前端请求路径,与以上的放行路径进行对比

HttpServletRequest httpServletRequest= (HttpServletRequest) servletRequest;
HttpServletResponse httpServletResponse= (HttpServletResponse) servletResponse;
String requestURI = httpServletRequest.getRequestURI();//获取前端请求路径

5.遍历对比信息

public static final AntPathMatcher antPathMatcher=new AntPathMatcher();//路径对比器
public boolean pathmatch(String[] url,String requesturl)//自定义对比方法{for (String path:url) {boolean match = antPathMatcher.match(path, requesturl);if(match){return true;}}return false;}

6.调用自定义的方法,boolean pathmatch = this.pathmatch(url, requestURI);如果为true,则匹配成功,放行, filterChain.doFilter(httpServletRequest,httpServletResponse);这两个参数为doFilter的参数
7.如果没有进行前后端分离的话,在跳转到登录命令的controller后,需要设置一个session属性,用于判断是否登录

//Longincontroller,方法中需要自定义一个HttpServletRequest对象
request.getSession().setAttribute("employee",one.getId());

8.判断session是否存在,不存在则表示未登录
Object employee = httpServletRequest.getSession().getAttribute(“employee”);

2.MybatisPlus的分页查询-Pageconfig

作用:自定义分页,无需手动构造分页内容

@Configuration
public class PageConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor mybatisPlusInterceptor=new MybatisPlusInterceptor();mybatisPlusInterceptor.addInnerInterceptor( new PaginationInnerInterceptor());return mybatisPlusInterceptor;}
}
//通过Page<Object> page=new Page<>(起始页,每页条数)可直接使用

3.公共字段填充-MetaObjectHander

作用:数据表发生变化时,自动添加某些字段

实现逻辑
1.自定义类实现MetaObjectHandler类
2.重写insertFill方法/updateFill方法
3.添加公共参数

metaObject.setValue("updateTime", LocalDateTime.now())//第一个参数为数据表字段名称;

4.MybatisPlus

作用:mybatis的升级,不用手动编写sql

注意:使用mybatisplus,数据层与业务层有所不同

`
//数据层
@Mapper
public interface Mapper extends BaseMapper<实体类名>
//业务层接口
public interface Service extends IService<实体类名> {}
//业务层实现类
@Service
public class ServiceImpl extends ServiceImpl<Mapper,实体类名> implements Service {}`

想要使用mybatisplus自带的命令
1.构造一个条件对象
LambdaQueryWrapper<实体类> queryWrapper=new LambdaQueryWrapper<>();查找条件
LambdaUpdateWrapper<实体类> updateWrapper=new LambdaUpdateWrapper<>();条件更新
2.通过条件对象进行sql操作

5.数据传输对象-Dto

作用:将多个表单对象封装到一起,用于前端展示
步骤
1.创建表单类A、B
2.自定义一个类,继承A类
3.在自定义类中定义其他属性(集合/字符串/整形等)
4.集合中的参数为表单类B

@Data
public class DishDto extends Dish {private List<DishFlavor> flavors = new ArrayList<>();private String categoryName;private Integer copies;
}

6.后端响应结果集

将后端的发送的数据进行封装,在前端页面展示

//结果类包含的内容
private Integer code;//用于表示后端处理成功或失败
private String msg;//用于对后端处理结果的描述
private T data;//定义一个泛型,用于将后端处理后的数据传到前端自定义泛型类
public class R<T> {// 类成员和方法的定义
}泛型类的构造方法,返回值是一个泛型
public static <T>R<T>success(T obj){R<T> r=new R<T>();r.data=obj;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;}

7.自定义异常类

作用:捕获后端异常,当后端发生异常时,能够及时通知到前端

1.自定义异常类
//根据需要,继承想要展示的异常
public class CustomException extends RuntimeException{
public CustomException(String msg)
{
super(msg);		//调用父类的构造方法
}
}2.定义异常处理类-ExceptionHandler
//@RestControllerAdvice通常与ExceptionHandler注解连用
@RestControllerAdvice(annotations = RestController.class)//=@Responsebody+@ControllerAdvice,参数为被拦截的错误来源
@Slf4j
public class ExceptionHandler {@org.springframework.web.bind.annotation.ExceptionHandler(CustomException.class)//处理异常类//SQLIntegrityConstraintViolationException epublic R<String> ex(SQLIntegrityConstraintViolationException e){log.info("异常处理");if(e.getMessage().contains("Duplicate entry"))//e.getmessage,就能获取到自定义错误的信息{System.out.println(e.getMessage());String[] errstr= e.getMessage().split(" ");for (String s:errstr) {System.out.println(s);}String msg=errstr[2]+"已存在";log.info(msg);return R.error(msg);}return R.error("失败了");}

8.多线程-ThreadLocal

作用
1.跟踪请求处理过程中的数据:如将用户的标识(比如用户ID)存储在 threadLocal 中,这样在整个请求处理过程中都可以方便地获取和使用它
2.线程隔离的数据存储:一些数据在多线程环境中是线程私有的,并且不同线程之间的数据不应该相互干扰,可以使用 ThreadLocal 来实现数据的线程隔离。

//一般在校验登录的时候就为其赋值,将初始化的session赋给threadLocal,对象.方法调用即可
public class BaseContext {private static ThreadLocal<Long> threadLocal=new ThreadLocal<>();//通过这个方法就能随时获取sessionid,不用构建HttpServletRequest参数对象public static void setThreadLocal(Long integer){threadLocal.set(integer);}public static Long getThreadLocal(){return threadLocal.get();}
}

10.文件上传下载-文件存储与本地,数据库只存储文件名

文件上传
1.获取上传的文件后缀名称
2.生成唯一的文件名称
3.校验存储位置的文件夹是否存在
4.转存到对应的文件夹

@Value("${reggie.path}")//配置文件自定义文件夹路径private String path;@PostMapping("/upload")public R<String> upload(MultipartFile file) throws IOException //上传的文件对象参数名,必须与前端的input框的name名字一致,且文件对象必须是MultipartFile{//上传的file文件是一个临时文件,需要转存,不然本次操作后,该文件就会销毁消失String originalFilename = file.getOriginalFilename(); //获取文件上传时的名称log.info(originalFilename);String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));//获取上传文件的后缀log.info(file+"这是前端的对象信息");String filename = UUID.randomUUID().toString()+suffix;//UUID生成一个唯一的名字log.info(filename);/*** 判断配置文件 @Value("${reggie.path}")的目录是否存在,没有就创建*/File dir=new File(path);log.info("dir"+dir);if(!dir.exists()){log.info("创建文件");dir.mkdirs();//创建@Value("${reggie.path}")的文件夹}file.transferTo(new File(path+"/"+filename));   //将临时文件转存到该路径return R.success(filename);}

文件下载

@GetMapping("/download")public void download(String name, HttpServletResponse response)//name为图片存储地址{//下载文件需要经过两个步骤,读数据流,写数据流try {FileInputStream fileInputStream=new FileInputStream(new File(path+"/"+name));//输入流,将文件地址写入ServletOutputStream outputStream = response.getOutputStream();//输出流,因为这里需要将数据流显示到前端,所以用HttpServletResponseresponse.setContentType("image/jpeg");//设置传输到前端的数据格式int len=0;byte[] bytes=new byte[1024];while((len=fileInputStream.read(bytes))!=-1)//len是每次读取的字节数,bytes是存储读出字节的内容,fileInputStream.read是读取输入流,当读取完最后一个数时,len=-1{outputStream.write(bytes,0,len);//输出流,outputStream = response.getOutputStream(),写入bytes数组中的内容,从0开始写入,长度是lenoutputStream.flush();//刷新数据流}outputStream.close();//关闭输出流fileInputStream.close();//关闭输入流} catch (Exception e) {throw new RuntimeException(e);}}

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

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

相关文章

Python实现GA遗传算法优化卷积神经网络分类模型(CNN分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 遗传算法&#xff08;Genetic Algorithm&#xff0c;GA&#xff09;最早是由美国的 John holland于20世…

TSINGSEE青犀视频安防监控EasyCVR视频汇聚平台电子地图定位偏移的排查与解决

安防监控EasyCVR视频汇聚综合管理平台具有强大的数据接入、处理及分发能力&#xff0c;平台可提供视频监控直播、云端录像、云存储、录像检索与回看、告警上报与查询、平台级联、云台控制、语音对讲、电子地图、轨迹跟踪、H.265自动转码等视频能力。 在视频监控管理平台TSINGSE…

word转pdf两种方式(免费+收费)

一、免费方式 优点&#xff1a;1、免费&#xff1b;2、在众多免费中挑选出的转换效果相对较好&#xff0c;并且不用像openOffice那样安装服务 缺点&#xff1a;1、对字体支持没有很好&#xff0c;需要安装字体库或者使用宋体&#xff08;对宋体支持很好&#xff09;2、对于使…

2023 电赛 E 题 K210 方案--K210实现矩形识别

相关库介绍 sensor&#xff08;摄像头&#xff09; sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) sensor.skip_frames(10) reset()&#xff1a;重置并初始化单目摄像头 set_pixformat()&#xff1a;设置摄像头输出格式&#xff0c…

中小学分班查询系统如何制作?这个方法值得借鉴

暑假即将结束&#xff0c;新学年即将开始&#xff0c;学校面临着一个重要的任务&#xff0c;那就是学生的分班问题。这个问题涉及到新生入学的分班&#xff0c;以及低年级学生升入高年级时的分班。对于负责分班的老师们来说&#xff0c;这无疑增加了不少工作量和挑战。 在开学…

上榜 Gartner | 中国领先的实时数据管理厂商 DolphinDB

在 Gartner 近日发布的 Hype Cycle for Data, Analytics and AI in China, 2023 报告中&#xff0c;DolphinDB 位列实时数据管理代表厂商。这是自去年 DolphinDB 入选 Gartner《中国数据库管理系统供应商甄选》后&#xff0c;又一次凭借领先的产品能力获得国际权威第三方分析机…

P2P网络NAT穿透原理(打洞方案)

1.关于NAT NAT技术&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;是一种把内部网络&#xff08;简称为内网&#xff09;私有IP地址转换为外部网络&#xff08;简称为外网&#xff09;公共IP地址的技术&#xff0c;它使得一定范围内的多台主机只…

python算法指南程序员经典,python算法教程pdf百度云

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;你也能看懂的python算法书 pdf&#xff0c;python算法教程这本书怎么样&#xff0c;现在让我们一起来看看吧&#xff01; 给大家带来的一篇关于算法相关的电子书资源&#xff0c;介绍了关于算法、详解、算法基础方面的内…

Kaggle狗图像分类实战

文章目录 Kaggle狗图像分类实战d2l安装问题python语法学习os.path.joind2l 数据加载streamlit Kaggle狗图像分类实战 d2l安装问题 d2l安装失败&#xff0c;报错如上图 去下面的网站下载到该项目文件目录下再pip install即可 Python d2l项目安装包(第三方库)下载详情页面 - …

ATFX汇评:英央行利率决议来袭,大概率加息25基点

ATFX汇评&#xff1a;今日19:00&#xff0c;英国央行公布利率决议、会议纪要和货币政策报告&#xff1b;半小时后&#xff0c;英国央行行长贝利召开货币政策新闻发布会。当前英国央行基准利率5%&#xff0c;市场预期将加息25基点至5.25%&#xff0c;假若符合预期&#xff0c;则…

【css】背景图片附着

属性&#xff1a;background-attachment 属性指定背景图像是应该滚动还是固定的&#xff08;不会随页面的其余部分一起滚动&#xff09;。 background-attachment: fixed&#xff1a;为固定&#xff1b; background-attachment: scroll为滚动 代码&#xff1a; <!DOCTYPE h…

opencv的Mask操作,选择图片中感兴趣的区域

最近做目标检测任务的时候&#xff0c;需要对固定区域的内容进行检测&#xff0c;要用到opencv的mask操作&#xff0c;选择图片固定的区域 代码 import cv2 import numpy as npimg cv2.imread(data/images/smoking.png)# 弹出一个框 让你选择ROI | x,y是左上角的坐标 x,y,w,…

23款奔驰C260 L更换内饰最全发光套件,提升车内氛围感

原厂1:1设计&#xff0c;免编程匹配&#xff0c;无损安装&#xff0c;可升级项目&#xff1a; 1、碳纤维中控氛围灯&#xff08;阿凡达水滴款&#xff09; 2、发光前风口&#xff1b; 3、发光后风口&#xff1b; 4、发光座椅背气氛灯&#xff1b; 5、中音发光盖板 6、主动…

数学分析:流形的线性代数回顾

因为是线性的&#xff0c;所以可以把所有的系数都提取出去。这也是多重线性代数的性质。可以看成基本的各项自变量的乘法。 这里可以看到两个不同基向量下&#xff0c;他们的坐标转化关系。 引出了张量积&#xff0c;也就是前面提到的内容。 对偶空间的例子总是比较美好。 因为…

使用express搭建后端服务

目录 1 创建工程目录2 初始化3 安装express依赖4 启动服务5 访问服务总结 上一篇我们利用TDesign搭建了前端服务&#xff0c;现在的开发讲究一个前后端分离&#xff0c;后端的话需要单独搭建服务。后端服务的技术栈还挺多&#xff0c;有java、php、python、nodejs等。在众多的技…

代理模式(Proxy)

代理模式是一种结构型设计模式&#xff0c;让开发者能够提供对象的替代品或其占位符。代理对象控制着对于原对象的访问&#xff0c;并允许在将请求提交给原对象前后进行一些处理。代理模式为原对象提供一种代理以控制对这个对象的访问&#xff0c;并由代理对象控制对原对象的引…

青蛙过河 [递推法]

青蛙过河 [递推法] 题目描述输入输出样例输入样例输出样例 递推解答A C 代码 题目描述 有一条河&#xff0c;左边一个石墩( A A A区)上有编号为 1 &#xff0c; 2 &#xff0c; 3 &#xff0c; 4 &#xff0c; … &#xff0c; n 1&#xff0c;2&#xff0c;3&#xff0c;4&am…

电脑更新win10黑屏解决方法

电脑更新win10黑屏解决方法 电脑黑屏出现原因解决步骤 彻底解决 电脑黑屏 出现原因 系统未更新成功就关机&#xff0c;导致系统出故障无法关机 解决步骤 首先长安电源键10s关机 按电源键开机&#xff0c;出现logo时按F8进入安全模式。 进入自动修复环境后&#xff0c;单击…

[nlp] TF-IDF算法介绍

&#xff08;1&#xff09;TF是词频(Term Frequency) 词频是文档中词出现的概率。 &#xff08;2&#xff09; IDF是逆向文件频率(Inverse Document Frequency) 包含词条的文档越少&#xff0c;IDF越大。

宋浩概率论笔记(二)随机变量

本章节内容较多&#xff0c;是概率论与数理统计中最为重要的章节&#xff0c;对于概率密度和分布函数的理解与计算要牢牢掌握&#xff0c;才能在后期的学习中更得心应手。