当前位置: 首页 > news >正文

苍穹外卖-Day1 | 环境搭建、nginx、git、令牌、登录加密、接口文档、Swagger

目录

nginx:

nginx反向代理和负载均衡概念

nginx反向代理和负载均衡如何配置?

后端环境:maven管理

sky-common

sky-pojo

sky-server:

后端环境搭建--Git进行版本控制

后端数据库--Mysql

前后端联调

前后端运行:

前后端联调如何完成--断点调试跟踪代码

断点调试小tips:

.yml文件简介:

YAML 的常见应用场景

令牌生成

完善登录功能

TODO使用小tips

导入接口文档

Swagger技术

介绍

使用方式

在线接口测试:

Swagger常用注解


nginx:

nginx学习,看这一篇就够了:下载、安装。使用:正向代理、反向代理、负载均衡。常用命令和配置文件,很全-CSDN博客

前端分为web端、小程序端

web端在nginx下面的html文件夹下面,nginx必须放在没有中文目录的环境运行

运行方法:双击nginx.exe,用浏览器打开访问localhost,访问端口号默认80

nginx反向代理和负载均衡概念

验证方法:在前端页面点击登录(打开F12开发者模式)可以看到前端请求地址

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

nginx反向代理好处:

  1. 缓存提高访问速度,
  2. 进行负载均衡(把大量请求按照指定方式均衡的分配给集群中的每台服务器),
  3. 保证后端服务安全

nginx反向代理和负载均衡如何配置?

反向代理主要依靠proxy_pass来配置

负载均衡的底层也是基于反向代理实现的,多配置了一些服务器server,转发可能需要给多个后台服务器

在这个项目中,负载均衡的配置文件在

后端环境:maven管理

sky-common

  1. constant:常量类
  2. context:上下文相关
  3. enumaration:枚举类
  4. exception:自定义异常类
  5. json:处理json转换
  6. properties:Springboot中的配置属性类,把配置文件中的一些配置对象封装
  7. result:后端返回结果
  8. utils:工具类

sky-pojo

前三项都属于POJO(Plain Old Java Object ,简单老式java对象),一种遵循简单设计原则的普通 Java 类,主要用于封装数据。

POJO 的核心特点:

  1. 无继承要求:不需要继承特定的类(如 Serializable 等,不过实际中为了序列化可能会实现)
  2. 无接口强制:不需要实现特定的接口
  3. 字段私有化:成员变量通常用 private 修饰
  4. 提供访问方法:通过 public 的 getter 和 setter 方法操作字段
  5. 无业务逻辑:主要用于数据存储,不包含复杂的业务处理方法
  6. 可包含构造方法:通常会有默认构造方法和带参数的构造方法

sky-server:

配置文件、配置类、拦截器、controller、service、mapper、启动类等

后端环境搭建--Git进行版本控制

在IDEA中VCS(version control system版本控制系统)新建git仓库,上方就会出现Git相关操作按钮。

先对号commit到本地仓库,再箭头push到远程仓库

后端数据库--Mysql

前段时间做数据库作业好像破坏了什么Mysql配置,启动方式:

管理员身份运行cmd,net start mysql,再使用Navicat

前后端联调

前后端运行:

前端双击nginx

后端代码编译:点击compile(父工程sky-take-out整体编译)

sky-server中运行application,运行项目

尝试在登录页面前端登录,报错,原因没有修改数据库连接账号密码

修改之后成功登录:

前后端联调如何完成--断点调试跟踪代码

右上角绿框可以快速运行查看启动类,旁边的小虫子是debug断点调试,

在EmployeeController类里面有login方法,打一个断点

重新登陆

@PostMapping("/login")public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {log.info("员工登录:{}", employeeLoginDTO);

员工登录DTO中封装前端试图登录的账号密码

断点调试可以方便看到前端提供过来的数据

  1. Mapper中的sql语句,如果是简单的查询可以写注解,复杂/mybatis中动态标签通过xml配置
  2. 后面的异常处理,由全局捕获业务异常的GlobalExceptionHandeler捕获,类型是BaseException(父类),其他类型的异常继承它

断点调试小tips:

stepover单步调试(F8),resume program左侧--运行至下一个断点

ctrl + alt + b可以跳转到光标的函数位置

.yml文件简介:

.yml 是一种文件格式的扩展名,对应的文件类型是 YAML 文件(YAML 全称是 "YAML Ain't Markup Language",即 “YAML 不是标记语言”)。它是一种数据序列化格式,主要用于存储和传输结构化数据,语法简洁、易读

简洁直观
采用缩进(通常是空格,而非 Tab)来表示数据的层级关系,避免了 XML 或 JSON 中的大量标签(如 <tag>)或括号(如 {} []),可读性极强。
例如,一个简单的用户信息 YAML 配置:

user:name: Aliceage: 25hobbies:- reading- hikingcontact:email: alice@example.comphone: 123456789

YAML 的常见应用场景

  • 配置文件:很多框架(如 Spring Boot、Docker、Kubernetes、Ansible 等)默认使用 YAML 作为配置文件格式,例如 Spring Boot 的 application.yml 用于配置数据库连接、端口号等。
  • 数据存储:可用于存储简单的结构化数据(如测试数据、配置参数)。
  • API 交互:部分 API 会使用 YAML 格式传输数据(虽然 JSON 更常见)。
格式特点适用场景
YAML缩进表示层级,简洁易读,支持注释配置文件(如 Spring Boot 配置)、人工编辑的结构化数据
JSON用括号表示层级,语法严格(无注释),机器友好API 数据传输、前端与后端交互
XML标签嵌套,语法繁琐,支持复杂结构和命名空间传统配置文件(如早期 Java 框架)、文档标记

如图上中的两个是springboot的配置文件

令牌生成

JwtProperties是一个配置属性类,在common-properties中,如下所示

package com.sky.properties;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Component
// 封装了SpringBoot里面的一些配置项
@ConfigurationProperties(prefix = "sky.jwt")
@Data
public class JwtProperties {/*** 管理端员工生成jwt令牌相关配置*/private String adminSecretKey;private long adminTtl;private String adminTokenName;/*** 用户端微信用户生成jwt令牌相关配置*/private String userSecretKey;private long userTtl;private String userTokenName;}

其中

@ConfigurationProperties(prefix = "sky.jwt") 

是 Spring Boot 中的一个注解,用于将配置文件(如 application.yml 或 application.properties)中指定前缀的配置项,自动绑定到当前类的属性上

  1. @ConfigurationProperties
    这是 Spring Boot 提供的核心注解,作用是 “配置属性绑定”。它会自动读取配置文件中的内容,并将符合规则的配置值赋值给类中的成员变量。

  2. prefix = "sky.jwt"
    prefix 表示 “配置前缀”,指定了要读取的配置项的共同前缀。
    这意味着:Spring 会去配置文件中寻找所有以 sky.jwt 开头的配置项,然后与当前类的属性进行匹配绑定。

所以在aplication.yml中找到下面这一段,会被绑定到JwtProperties类的属性上

sky:jwt:# 设置jwt签名加密时使用的秘钥admin-secret-key: itcast# 设置jwt过期时间admin-ttl: 7200000# 设置前端传递过来的令牌名称admin-token-name: token

可以看到和上面一一对应

生成jwt令牌在EmployeeController

package com.sky.controller.admin;import com.sky.constant.JwtClaimsConstant;
import com.sky.dto.EmployeeLoginDTO;
import com.sky.entity.Employee;
import com.sky.properties.JwtProperties;
import com.sky.result.Result;
import com.sky.service.EmployeeService;
import com.sky.utils.JwtUtil;
import com.sky.vo.EmployeeLoginVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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 java.util.HashMap;
import java.util.Map;/*** 员工管理*/
@RestController
@RequestMapping("/admin/employee")
@Slf4j
public class EmployeeController {@Autowiredprivate EmployeeService employeeService;@Autowiredprivate JwtProperties jwtProperties;/*** 登录** @param employeeLoginDTO* @return*/@PostMapping("/login")public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {log.info("员工登录:{}", employeeLoginDTO);Employee employee = employeeService.login(employeeLoginDTO);//登录成功后,生成jwt令牌Map<String, Object> claims = new HashMap<>();claims.put(JwtClaimsConstant.EMP_ID, employee.getId());// jwt令牌String token = JwtUtil.createJWT(jwtProperties.getAdminSecretKey(),jwtProperties.getAdminTtl(),claims);// 需要传递给前端的信息,用VO进行封装EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder().id(employee.getId()).userName(employee.getUsername()).name(employee.getName()).token(token).build();return Result.success(employeeLoginVO);}/*** 退出** @return*/@PostMapping("/logout")public Result<String> logout() {return Result.success();}}

其中EmployeeLoginVO如下所示

package com.sky.vo;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "员工登录返回的数据格式")
public class EmployeeLoginVO implements Serializable {@ApiModelProperty("主键值")private Long id;@ApiModelProperty("用户名")private String userName;@ApiModelProperty("姓名")private String name;@ApiModelProperty("jwt令牌")private String token;}

完善登录功能

问题:密码在数据库明文存储,安全性低 

TODO使用小tips

导入接口文档

教程使用Yapi,这个网站现在无法使用

尝试使用ApiPost失败,于是尝试apifox,导入类型选择Yapi,可以成功导入

Swagger技术

介绍

可以帮助后端生成接口文档,并进行在线调试

 

使用方式

Bean注解:使用Spring框架创建并管理对象

在server的config类下面

package com.sky.config;import com.sky.interceptor.JwtTokenAdminInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;/*** 配置类,注册web层相关组件*/
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {@Autowiredprivate JwtTokenAdminInterceptor jwtTokenAdminInterceptor;/*** 注册自定义拦截器** @param registry*/protected void addInterceptors(InterceptorRegistry registry) {log.info("开始注册自定义拦截器...");registry.addInterceptor(jwtTokenAdminInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin/employee/login");}/*** 通过knife4j生成接口文档* @return*/@Beanpublic Docket docket() {log.info("准备生成接口文档...");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/");}
}

由于上面配置的静态资源映射,将后端接口文档映射到localhost:8080/doc.html

  • 如果不设置静态资源映射,SpringMVC会以为在请求某一个controller,是动态请求
  • 如果扫描包的名字写错了,就无法正确扫描生成动态接口文档

访问即可查看该接口文档

knife4j为此动态生成接口文档

目前已经有的两个接口是解析下面的类生成的

/*** 员工管理*/
@RestController
@RequestMapping("/admin/employee")
@Slf4j
public class EmployeeController {@Autowiredprivate EmployeeService employeeService;@Autowiredprivate JwtProperties jwtProperties;/*** 登录** @param employeeLoginDTO* @return*/@PostMapping("/login")public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {log.info("员工登录:{}", employeeLoginDTO);Employee employee = employeeService.login(employeeLoginDTO);//登录成功后,生成jwt令牌Map<String, Object> claims = new HashMap<>();claims.put(JwtClaimsConstant.EMP_ID, employee.getId());String token = JwtUtil.createJWT(jwtProperties.getAdminSecretKey(),jwtProperties.getAdminTtl(),claims);EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder().id(employee.getId()).userName(employee.getUsername()).name(employee.getName()).token(token).build();return Result.success(employeeLoginVO);}/*** 退出** @return*/@PostMapping("/logout")public Result<String> logout() {return Result.success();}}

在线接口测试:

Swagger常用注解

在EmployeeController里面加入相关注解之后

http://www.lryc.cn/news/616170.html

相关文章:

  • 攻击实验(ARP欺骗、MAC洪范、TCP SYN Flood攻击、DHCP欺骗、DHCP饿死)
  • 【接口自动化】初识pytest,一文讲解pytest的安装,识别规则以及配置文件的使用
  • YOLOv11 模型轻量化挑战:突破边缘计算与实时应用的枷锁
  • Ollama+Deepseek+Docker+RAGFlow打造自己的私人AI知识库
  • C语言深度剖析
  • Docker 详细介绍及使用方法
  • 【东枫科技】 FR2 Massive MIMO 原型验证与开发平台,8*8通道
  • DBSACN算法的一些应用
  • 力扣-20.有效的括号
  • Design Compiler:布图规划探索(ICC II)
  • 【FPGA】初识FPGA
  • Jotai:React轻量级状态管理新选择
  • 密码学的数学基础2-Paillier为什么产生密钥对比RSA慢
  • 重学React(四):状态管理二
  • 机器学习第八课之K-means聚类算法
  • 编程基础之多维数组——计算鞍点
  • 【Docker实战】将Django应用容器化的完整指南
  • 【代码随想录day 15】 力扣 257. 二叉树的所有路径
  • [FOC电机控制] 电压频谱图
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘ray’问题
  • Redis一站式指南一:从MySQL事务到Redis持久化及事务实现
  • 【每天一个知识点】深度领域对抗神经网络
  • MACBOOK M1安装达梦8数据库
  • nginx-主配置文件
  • 异步问题的概念和消除问题技巧
  • 【Tomcat】企业级web应用服务器
  • ATF(TF-A)安全通告 TFV-12(CVE-2024-5660)
  • nestjs官网推荐typeorm而不是prisma的原因
  • 实现MATLAB2024b和M文件关联(防止运行多个MATLAB)
  • 【0基础3ds Max】主工具栏介绍(下)