一、工作内容
环境搭建、服务器链接、从服务器clone项目、注册和登录功能的demo、将注册登录集成到项目中,熟悉业务逻辑。
二、功能实现
注册
一个传统的注册功能,包含用户名、密码、手机号、邮箱,涉及到前后端分离不是很清楚那些前端能做。
极简实现流程:
数据获取(从controller层传入) --> 空值处理(name为空返回name不能为空,password为空设为123456,可以在controller处理也可以在service层处理)--> 验证name是否已经存在(调取dao层qureyByid,保证name唯一) --> 生成新用户对象、赋值、插入表 --> 返回注册信息。
优化方向:
手机号与邮箱正则校验、验证码发送、密码校验等。
登录
一个传统的登录功能,传入用户名密码、返回结果,过程中有token的生成与存入redis。
极简流程:
数据获取(从controller层传入) --> 空值处理(返回报错)--> 验证账号存在 --> 验证密码 --> 生成token(String token = UUID.randomUUID().toString().replaceAll("-", "");)--> 将token与user信息全部存入redis(使用string + json结构存储,相对hash结构来说效率较高、序列化简单)--> 每次登录有效时间重置 --> 返回登录信息。
token生成与存储代码如下,使用string + json结构存储进redis :
(1)配置RedisConfig.class文件
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// 使用 Jackson2JsonRedisSerializer 序列化 Object 类型
Jackson2JsonRedisSerializer<Object> jacksonSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
jacksonSerializer.setObjectMapper(objectMapper);
// 使用 StringRedisSerializer 序列化 String 类型
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(jacksonSerializer);
template.afterPropertiesSet();
return template;
}
}
(2)生成存储token与用户信息
/**
* 生产token,如果同一用户重复登录,token的时效重置
*/
@Service
public class ProductToken {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private UsersDao usersDao;
/**
* token有效时间,单位SECONDS(秒)
*/
private static final int TOKEN_EXPIRE_TIME = 30;
/**
* 生成有时效的token
* 之后调其他接口需要校验name和token值
* @param users
*/
public String productToken(Users users) {
Map<String, String> infoMap = new HashMap<String, String>();
String key=users.getUserName();
String token = (String) redisTemplate.opsForValue().get("name:" + key + ":token");
if( token== null) {
token = UUID.randomUUID().toString().replaceAll("-", "");
//将登陆的信息存入redis
// 存储 token 字符串
redisTemplate.opsForValue().set("name:" + key + ":token", token);
// 存储 users 对象
redisTemplate.opsForValue().set("token:" + token + ":user", users);
infoMap.put(key, "new token="+token);
}
else{
infoMap.put(key, "old token="+token);
}
// 设置 token 的过期时间
redisTemplate.expire("name:" + key + ":token", TOKEN_EXPIRE_TIME, TimeUnit.SECONDS);
// 设置 users 的过期时间
redisTemplate.expire("token:" + token + ":user", TOKEN_EXPIRE_TIME, TimeUnit.SECONDS);
return token;
}
}
优化方向:
手机号登陆、忘记密码、将合适的信息存储进redis等。
三、工具使用
Redis
什么是Redis
Redis 是一个开源的、使用 C 语言编写的、支持网络、可基于内存亦可持久化的日志型、开源的(BSD许可)高性能非关系型(NoSQL)的键值对(Key-Value)数据库。
与传统数据库不同的是 Redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向。
数据类型
Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串,值支持五种数据类型:字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)。每种数据类型都有不同的特点和适用场景。
持久化机制
RDB (Redis Database):定期生成数据快照,适合做冷备。
AOF (Append Only File):记录每个写命令,重启时重新执行 AOF 文件中的命令恢复数据,适合做热备。
可以同时开启 RDB 和 AOF 两种持久化机制,提高数据的可靠性。
冷备:
- 也称为离线备份或静态备份。
- 备份过程中需要停止数据库服务,不能对数据库进行读写操作。
- 备份文件不会随着数据库的更新而自动更新,需要定期进行全量备份。
- 恢复数据时需要停止数据库服务,将备份文件还原。
- 恢复效率较低,但数据完整性高。
- 适合于数据量较小、变更频率较低的场景。
热备:
- 也称为在线备份或动态备份。
- 备份过程中不需要停止数据库服务,可以正常读写数据。
- 备份文件会随着数据库的更新而自动更新,可以进行增量备份。
- 恢复数据时不需要停止数据库服务,可以快速恢复最新数据。
- 恢复效率较高,但备份过程可能会对数据库性能产生一定影响。
- 适合于数据量较大、变更频率较高的场景。
读写策略
Redis 采用单线程模型,使用 I/O 多路复用技术来处理并发,单机性能很高。
读操作直接从内存中读取,速度极快。
写操作先写入内存,再异步刷新到磁盘,保证写入的实时性。
分布式缓存
Redis 支持主从复制,可以实现读写分离,提高可用性和扩展性。
使用哨兵机制监控主从节点,实现自动故障转移。
利用 Redis 集群技术,可以实现水平扩展,解决单机内存容量瓶颈。
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master/leader),后者称为从节点(slave/follower) ; 数据的复制是单向的,只能由主节点到从节点,主要作用包括:
读写分离:
- 主节点负责写入操作,从节点负责读取操作。
- 可以通过在从节点上执行查询操作来分担主节点的读负载,提高整体系统的吞吐量。
数据冗余与容灾:
- 从节点保存了主节点的副本数据,当主节点发生故障时,可以快速切换到从节点,提高服务的可用性。
- 从节点可以作为备份节点,在主节点故障时进行数据恢复。
扩展性:
- 可以根据需求增加从节点的数量,线性扩展读取性能。
- 从节点可以作为集群的构建基础,实现水平扩展。
Redis 的主从复制实现原理如下:
- 主节点开启主从复制功能,等待从节点的连接;
- 从节点发起 SLAVEOF 命令,连接主节点;
- 主节点接收到 SLAVEOF 命令后,开始向从节点传输全量数据;
- 从节点接收到全量数据后,开始进行增量同步,实时接收主节点的写命令并更新自己的数据;
- 从节点可以设置为只读模式,避免客户端误写。
MySQL 也支持主从复制机制,并且原理与作用与 Redis 的主从复制比较相似。
分布式锁
Redis 可以实现分布式锁,原理是利用 Redis 的SETNX命令,当且仅当 key 不存在时设置成功。
获取锁时使用 、SETNX命令,释放锁时使用DEL命令。
为了防止死锁,可以为锁设置过期时间,并在加锁时检查是否已过期。
使用 Redlock 算法可以实现更可靠的分布式锁。
Swagger(用于可视化接口与测试)
本来以为是方便前端的,但是貌似后端使用更方便
Swagger 是一个开源的 API 文档生成工具,它可以帮助开发者快速生成、文档化和可视化 RESTful 风格的 Web 服务 API。Swagger 包括以下主要组件:
- Swagger Editor: 一个基于浏览器的编辑器,用于编写、设计和测试 API 的 OpenAPI (Swagger) 规范。
- Swagger UI: 一个基于 HTML、JS 和 CSS 的可视化 API 文档工具,可以根据 OpenAPI 规范显示交互式的 API 文档。
- Swagger Codegen: 一个代码生成器,可以根据 OpenAPI 规范自动生成服务端和客户端代码,支持多种语言和框架。
- Swagger Inspector: 一个 API 测试工具,可以帮助开发者探索、测试和记录 API。
使用 Swagger 的主要优点包括:
- API 文档自动生成: Swagger 可以根据代码中的注释自动生成漂亮的 API 文档,省去了手动维护文档的麻烦。
- 多语言支持: Swagger 可以生成多种语言的客户端和服务端代码,提高了开发效率。
- 交互式测试: Swagger UI 提供了一个交互式的 API 测试界面,开发者可以直接在浏览器中测试 API。
- 标准化: Swagger 遵循 OpenAPI 标准,使 API 定义更加规范化和可交换。
- API 管理: Swagger 可以帮助 API 提供者更好地管理 API 生命周期。
Postman(用于测试,相对Swagger更好的支持压测)
-
API 请求构建和测试:
- 支持各种 HTTP 方法(GET、POST、PUT、DELETE 等)
- 可以构建复杂的 API 请求,包括参数、授权、头部等
- 支持文件上传、JSON/XML 请求体等
- 提供实时的请求预览和响应展示
-
API 文档管理:
- 可以生成漂亮的 API 文档,并支持团队协作
- 文档包含请求、响应、参数等详细信息
- 支持导出为多种格式(HTML、PDF、Swagger 等)
-
环境和变量管理:
- 支持定义全局、集合和请求级别的环境变量
- 可以在不同的环境(开发、测试、生产等)之间切换
- 支持动态获取和使用变量
-
自动化和脚本编写:
- 支持编写 JavaScript 脚本来处理复杂的逻辑
- 可以编写测试用例并自动运行
- 支持定期运行 API 测试并生成报告
-
团队协作:
- 支持团队成员共享 API 集合和文档
- 提供实时的协作编辑和注释功能
- 支持权限管理,控制团队成员的访问权限
-
其他功能:
- 支持导入和导出 API 集合
- 提供丰富的插件和集成,可扩展功能
- 支持离线工作和跨平台使用(Windows、macOS、Linux)
Git
idea工具栏-->VSC-->启用git
Git clone到本地注意分支是否正确
Git push之前先commit,注意上传的分支。
合并分支时解决冲突注意合并方式。
EasyCode
可以从database的table直接GenerateCode Spring格式的代码(包括dao、entity、service、controller)
但是!数据库访问层(Dao)与数据库访问实现是分开的,sql查询在resources/mapper.xml文件中,请注意sql语句是错误的需要修改!!!Dao层可以改为注解开发。
第三周新增:
呜呜呜呜呜呜,手改sql语句好久才知道有模板可以直接解决的,不使用模板生成的sql语句没有逗号,
参考解决:EasyCode生成的SQL语句中无逗号分隔_easycode生成的xml没有逗号-CSDN博客
Easy Code的使用教程:Easy Code的使用教程(带模板)-CSDN博客
AxureRP
AxureRP 是一款功能强大的交互式原型设计工具,广泛应用于 Web 和移动应用程序的设计和开发过程中。以下是 AxureRP 的主要特点和功能:
-
交互式原型设计:
- 提供拖放式的界面设计功能,可以快速构建各种UI元素
- 支持定义交互行为,如点击、滚动、输入等
- 可以通过动作和事件链接不同的页面或组件,模拟真实的用户交互
-
丰富的组件库:
- 内置了大量的基础 UI 组件,如按钮、表单、导航等
- 支持自定义组件和样式,满足复杂的设计需求
- 提供 Material Design、iOS 和 Android 等平台的组件
-
动态内容和数据绑定:
- 支持定义动态内容,如列表、表格、数据表单等
- 可以通过数据绑定功能,将原型中的内容与真实数据关联
-
响应式设计:
- 支持定义不同尺寸的屏幕,并自动适配UI布局
- 可以模拟不同设备的显示效果,如移动端、平板等
-
协作和共享:
- 支持团队成员之间的协作编辑和审阅
- 可以将原型发布为可交互的在线文档,供利益相关方查看
-
原型测试和发布:
- 支持在原型中添加用户测试功能,如点击热点、问卷等
- 可以将原型打包发布为独立的 HTML 文件或 Axure Share 链接
四、问题记录
服务器连接问题
刚来的时候服务器连接不上,明明在同一段局域网,但是ping不通局域网内其他除网关外的IP地址,网上查阅各种解决途径无果,最后发现连接的wifi和服务器是一个就可以了(小公司,买的服务器主机在办公室内)。
环境配置问题
git下来代码后想用自己的数据库先跑一下测试,发现各种出错。
错误信息:java: java.lang.NoSuchFieldError: Class com.sun.tools.javac.tree.JCTree$JCImport does not have member field 'com.sun.tools.javac.tree.JCTree qualid'
原因:lombok配置问题
更改pom文件:
<!--原配置-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--改后-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.32</version>
<scope>provided</scope>
</dependency>