项目--苍穹外卖

news2024/11/28 3:31:02

1.| constant | 存放相关常量类 |
| context | 存放上下文类 |
| enumeration | 项目的枚举类存储 |
| exception | 存放自定义异常类 |
| json | 处理json转换的类 |
| properties | 存放SpringBoot相关的配置属性类 |
| result | 返回结果类的封装 |
| utils | 常用工具类 |
2.| Entity | 实体,通常和数据库中的表对应 |
| DTO | 数据传输对象,通常用于程序中各层之间传递数据 |
| VO | 视图对象,为前端展示数据提供的对象 |

| POJO | 普通Java对象,只有属性和对应的getter和setter |

3.| config | 存放配置类 |
| controller | 存放controller类 |
| interceptor | 存放拦截器类 |
| mapper | 存放mapper接口 |
| service | 存放service类 |
| SkyApplication | 启动类 |

3.先编译一下,然后正常运行

 前后端联调:

nginx反向代理,就是将前端发送的动态请求由nginx转发到后端服务器

好处: 

前端发送的请求,是如何请求到后端服务的?

在使用Nginx作为反向代理的Java项目中,前端发送的请求会被Nginx接收并处理,然后转发给后端服务。以下是一些基本步骤:

客户端(前端)发送请求到Nginx服务器。
Nginx服务器接收请求,并根据配置的规则进行处理。
Nginx根据配置的规则将请求转发给后端服务。
后端服务接收到请求并处理,然后返回响应。
Nginx接收后端服务的响应,并将其返回给客户端。

在这个过程中,Nginx扮演了反向代理的角色,接收客户端的请求并转发给后端服务,同时也将后端服务的响应返回给客户端。通过Nginx,可以实现对请求的负载均衡(把大量的请求按照我们指定的方式均衡的分配给集中的每台服务器)、缓存、安全过滤等处理,提高系统的性能和安全性。 

配置:nginx.conf

server{     

             listen 80;     

             server_name localhost;          

             location /api/ {                     

                             proxy_pass   http://localhost:8080/admin/;  #反向代理     } }

nginx 负载均衡的配置方式: nginx.conf

upstream webservers{     

                server 192.168.100.128:8080;     

                server 192.168.100.129:8080;

}

server{     listen 80;     

                server_name localhost;          

                location /api/ {                   

                                proxy_pass   http://webservers/admin/;  #负载均衡     } }

完善登录功能

问题:员工表中的密码是明文存储,安全性太低。 

1.将密码加密后存储,提高安全性

2.使用MD5加密方式对明文密码加密

1.修改数据库中明文密码,改为MD5加密后的密文

2.修改Java代码,前端提交的密码进行MD5加密后再跟数据库中密码比对

在EmployeeServiceImpl中

//进行md5加密,然后再进行比对

password = DigestUtils.md5DigestAsHex(password.getBytes());

if (!password.equals(employee.getPassword())) {    

//密码错误  

throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR); }

前后端 分离开发流程:

导入接口文档 

json导入YApi

Yapi 是设计阶段使用的工具,管理和维护接口

Swagger 在开发阶段使用的框架,帮助后端开发人员做后端的接口测试

Swagger

使用Swagger你只需要按照它的规范去定义接口及接口相关的信息,就可以做到生成接口文档,以及在线接口调试页面。

Knife4j 是为Java MVC框架集成Swagger生成Api文档的增强解决方案。

1.导入maven坐标

2.在配置类中加入knnife4j相关配置

3.设置静态资源映射,否则接口文档页面无法访问

<dependency>            

<groupId>com.github.xiaoymin</groupId>            

<artifactId>knife4j-spring-boot-starter</artifactId>            

<version>3.0.2</version>

</dependency>

 WebMvcConfiguration中:

@Bean

public Docket docket(){    

    ApiInfo apiInfo = new ApiInfoBuilder()            

                .title(“苍穹外卖项目接口文档”)            

                .version(“2.0”)            

                .description(“苍穹外卖项目接口文档")            

                .build();    

Docket docket = new Docket(DocumentationType.SWAGGER_2)            

           .apiInfo(apiInfo)            

           .select()            

           //指定生成接口需要扫描的包      .apis(RequestHandlerSelectors.basePackage("com.sky.controller"))                          .paths(PathSelectors.any())            

        .build();

return  docket;

}

/* * 
*设置静态资源映射 ,主要是访问接口文档
* @param registry
*/
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
   log.info(“开始设置静态资源映射...");   
   registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");    
   registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
   }

常用注解:

通过注解可以控制生成的接口文档,使接口文档拥有更好的可读性,常用注解如下:

@Api(tags ="员工相关接口")

@ApiOperation(value = "员工登录")    方法上

@ApiOperation("员工退出")

DTO:专注于做数据传输

当前端提交的数据和实体类中对应的属性差别比较大时,建议使用DTO来封装数据

VO

新增员工

@PostMapping
@ApiOperation("新增员工")
public Result save(@RequestBody EmployeeDTO employeeDTO){
log.info("新增员工:{}",employeeDTO);
employeeService.save(employeeDTO);
return Result.success();
}

void save(EmployeeDTO employeeDTO); 

@Override
public void save(EmployeeDTO employeeDTO) {
Employee employee = new Employee();
//employee.setName(employeeDTO.getName());

//对象属性拷贝
BeanUtils.copyProperties(employeeDTO,employee);
//设置账号的状态,默认正常状态1表示正常,0表示锁定
employee.setStatus(StatusConstant.ENABLE);

//设置密码,默认123456
employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.

DEFAULT_PASSWORD.getBytes()));

//设置当前记录的创建时间和修改时间
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());

//设置当前记录创建人id和修改人id
//TODO 后期需要改为当前登录用户的id
employee.setCreateUser(10L);
employee.setUpdateUser(10L);

employeeMapper.insert(employee);
}

  

@Insert("insert into employee (name,username,password,phone,sex,id_number,create_time,update_time," +
"create_user,update_user)" +"values "+
"(#{name},#{username},#{password},#{phone},#{sex},#{idNumber},#{createTime},#{updateTime},#{createUser},#{updateUser})")
void insert(Employee employee);

 

存在问题

1.录入的用户名已存在,抛出异常后没有处理

2.新增员工时,创建人id和修改人id设置为了固定值 

@ExceptionHandler
public Result exceptionHandler(SQLIntegrityConstraintViolationException ex) {
log.error("异常信息:{}", ex.getMessage());
Duplicate entry 'zhangsan' for key 'employee.idx username
String message = ex.getMessage(); //获得异常信息
if (message.contains("Duplicate entry")) { //判断异常信息里面有没有关键字Duplicate entry
String[] split = message.split(" "); //动态把字符串提取出来,根据空格分割,得到数组对象
String username = split[2]; //第三个,下标为2
String msg = username + MessageConstant.ALREADY_EXISTS; //用户名已存在
return Result.error(msg);
} else {
return Result.error(MessageConstant.UNKNOWN_ERROR);
}
}

 

解析出登录员工id后,如何传递给Service的save方法?

ThreadLocal 并不是一个Thread,而是Thread的局部变量。

ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。

ThreadLocal常用方法:

public void set(T value)     设置当前线程的线程局部变量的值

public T get()         返回当前线程所对应的线程局部变量的值

public void remove()        移除当前线程的线程局部变量 

注意:客户端发送的每次请求,后端的Tomcat服务器都会分配一个单独的线程来处理请求

 

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

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

相关文章

✔ ★算法基础笔记(Acwing)(二)—— 数据结构(17道题)【java版本】

数据结构 1. 单链表模板1. 单链表(7分钟) 2. 双链表模板1. 双链表 3. 模拟栈1. 模拟栈(一个数组即可)2. 表达式求值(20分钟) 4. 队列 tt -1,hh 0;1. 模拟队列 5. 单调栈1. 单调栈(4分钟)3.14 6. 单调队列1. 滑动窗口例题(10分钟) 7. KMP1. KMP字符串(10分钟)二刷体会★三刷体…

Python之glob

import os import glob import datetime # for dirpath, dirname, files in os.walk(rE:\htdos\Project): # print(dirpath, dirname, files)# glob.glob(**) 当前目录的所有文件和文件夹 # glob.glob(**/) 当前目录的所有文件夹 # glob.glob(20*) 找到当前目录以20开头的…

HDMI协议Ver2.0a(学习笔记)

1 简介 本规范由HDMI论坛制定 2.目的和范围 本文件构成了高清多媒体接口2.0版规范&#xff08;HDMI规范2.0版&#xff09;。本规范通过引用纳入了HDMI规范1.4b版&#xff0c;并定义了附加和改进的功能。对Source、Sink、中继器和电缆的合规性所需的机械、电气、行为和协议要…

解决java.lang.reflect.ReflectionException: Reflection error

解决java.lang.reflect.ReflectionException: Reflection error 摘要引言正文1. 理解异常的根本原因2. 处理反射操作错误用法获取类的方式不正确&#xff1a;调用方法的方式不正确&#xff1a; 3. 处理访问权限问题4. 异常处理 总结参考资料 博主 默语带您 Go to New World. ✍…

Unity 课时 1 : No.1 模拟面试题

课时 1 : No.1 模拟面试题 C# 1.装箱和拆箱是什么&#xff1f; ​ 对于应用类型。将基类的子类转化成基类称为装箱。将基类转换成子类&#xff0c;成为拆箱。装箱通常使用隐式转换&#xff0c;拆箱可以使用 as 或者 强制转换。同样对于值类型也可以进行装箱和拆箱。 答案&a…

C++11—线程库

C线程库 文章目录 C线程库线程的创建thread提供的成员函数get_idthis_thread命名空间线程的回收策略join detach 线程函数参数mutex的种类lock_guardunique_lock原子性操作库(atomic)cas操作windows和Linux创建进程的区别 线程的创建 调用无参的构造函数 thread() noexcept;#in…

视频云存储/安防监控/AI分析/视频AI智能分析网关行为分析算法应用场景汇总

随着城市经济的日益发展&#xff0c;城市建设也如火如荼。很多施工人员为了自身方便&#xff0c;无视安全规章制度&#xff0c;不按照安全施工要求进行着装、施工。具有很大的安全隐患&#xff0c;一旦发生事故&#xff0c;就会造成人员损伤和工程进度的挤压。为了改善此问题&a…

QT实战之翻金币游戏【详细过程及介绍】

目录 前言 一、游戏整体分析 二、创建项目 三、添加资源 四、主界面实现 1、设置游戏主场景基本配置 2、设置背景图片 3、创建开始按钮并设置动画 4、创建关卡选择界面并实现主界面与其的切换 五、关卡选择界面实现 1、设置关卡选择场景基本配置 2、设置关卡选择场…

2-2 自动微分机制

神经网络是如何更新网络参数的呢&#xff1f; 为什么需要自动微分机制&#xff1f; 以及什么是自动微分机制&#xff1f; 神经网络通常依赖反向传播求梯度来更新网络参数&#xff0c;求梯度过程通常是一件非常复杂而容易出错的事情。而深度学习框架可以帮助我们自动地完成这种求…

PostgreSQL数据库IPC——SI Message Queue

SI Message Queue代码位于src/backend/storage/ipc/sinvaladt.c和src/backend/storage/ipc/sinval.c文件中&#xff0c;属于PostgreSQL数据库IPC进程间通信的一种方式【之前介绍过PostgreSQL数据库PMsignal——后端进程\Postmaster信号通信也是作为PostgreSQL数据库IPC进程间通…

Linux下Minio分布式存储安装配置(图文详细)

文章目录 Linux下Minio分布式存储安装配置(图文详细)1 资源准备1.1 创建存储目录1.2 获取Minio Server资源1.3 获取Minio Client资源 2 Minio Server安装配置2.1 切换目录2.2 后台启动2.3 查看进程2.4 控制台测试 3 Minio Client安装配置3.1 切换目录3.2 移动mc脚本3.2 运行mc命…

记录一次LiteFlow项目实战

文章目录 学习LiteFlowspring boot整合LiteFlow依赖配置组件定义spring boot配置文件规则文件的定义 执行 组件EL规则串行并行 动态构建组件动态构建chain&#xff08;流程&#xff09;销毁chain高级特性 题外话&#xff1a; 最近喜欢上骑摩托车了&#xff0c;不是多大排量的摩…

C++ if...else 语句

一个 if 语句 后可跟一个可选的 else 语句&#xff0c;else 语句在布尔表达式为假时执行。 语法 C 中 if…else 语句的语法&#xff1a; if(boolean_expression) {// 如果布尔表达式为真将执行的语句 } else {// 如果布尔表达式为假将执行的语句 }如果布尔表达式为 true&…

联想拯救者Lenovo Legion Y7000 2020H(81Y7)原厂Win10系统

链接&#xff1a;https://pan.baidu.com/s/15GwrfjvhK3-_OlhkfPyUbA?pwd4v03 系统自带所有驱动、出厂主题壁纸LOGO、Office办公软件、联想电脑管家等预装程序 所需要工具&#xff1a;16G或以上的U盘 文件格式&#xff1a;ISO 文件大小&#xff1a;10.7GB 注&#xff1a;恢复…

用vb语言编写一个抄底的源代码程序实例

以下是一个基于通达信软件编写的简单抄底源代码程序&#xff0c;用于自动识别股票的底部形态并发出买入信号&#xff1a; vbs 复制 导入通达信软件自带的股票数据接口 Dim TdxApi Set TdxApi CreateObject("TdxApi.TdxLocalAPI") 设置股票代码、周期、数据类型等参…

算法通关村第十九关:白银挑战-动态规划高频问题

白银挑战-动态规划高频问题 1. 最少硬币数 LeetCode 322 https://leetcode.cn/problems/coin-change/description/ 思路分析 尝试用回溯来实现 假如coins[2,5,7]&#xff0c;amount27&#xff0c;求解过程中&#xff0c;每个位置都可以从[2,5,7]中选择&#xff0c;因此可以…

深入理解JVM虚拟机第六篇:内存结构与类加载子系统概述

文章目录 一&#xff1a;内存结构概述 1&#xff1a;运行时数据区 2&#xff1a;运行时数据区简图 3&#xff1a;运行时数据区详细图中英文版 二&#xff1a;类加载器子系统 1&#xff1a;加载 2&#xff1a;连接 3&#xff1a;初始化 一&#xff1a;内存结构概述 1…

CAN基础概念

文章目录 目的控制器、收发器、总线帧格式CAN2.0和CAN-FD波特率与采样点工作模式总结 目的 CAN是非常常用的一种数据总线&#xff0c;被广泛用在各种车辆系统中。大多数时候CAN的控制器和收发器干了比较多的工作&#xff0c;从而对于写代码使用来说比较简单。这篇文章将对CAN使…

经历网数据库共享

经历网&#xff0c;为留住您的经历而生 点击 经历网 进入网站查看当前数据 经历网网址&#xff1a;https://www.jili20.com/ 以下 数据库 数据 截止至 2023年9月13日 1&#xff09;百度网盘 提取 链接&#xff1a;https://pan.baidu.com/s/1WwR4cI9lbSAYTuffo8qmVQ 或点击 此…

微信小程序的在线课外阅读打卡记录系统uniapp

本文从管理员、学生和教师的功能要求出发&#xff0c;中学课外阅读记录系统中的功能模块主要是实现学生、教师、阅读任务、阅读打卡、提醒信息、阅读排行、任务计划、阅读类型、在线考试等。经过认真细致的研究&#xff0c;精心准备和规划&#xff0c;最后测试成功&#xff0c;…