项目心得--网约车
一、RESTFUL
Post:新增
Put:全量修改
Patch:修改某个值
Delete: 删除
Get:查询
删除接口也可以用POST请求
url注意:
url中不要带有敏感词(用户id等)
url中的名词用复数形式
url设计:
api.xxx.com/courses
二、状态码和提示信息
code:状态码
message:success等
消息:真正的消息体
这样做可以省去解析消息体拿到状态码
三、分页
/api/courses?page=1&size=10
/api/courses?max_id=100&min_id=90
第一种缺点:不适合频繁有插入的情况(第一页的数据,可能在看第二页的时候被挤到第二页了,看到了重复数据)
第二种缺点:不合适看指定的页数(得要看了前一页之后,才能知道下一页的max_id和min_id)
四、接口设计工具
APIFOX
五、dependencies和dependencyManager
dependencyManager在父项目中只声明依赖,并不实现引用;子项目需要显示声明依赖;有利于版本统一,父项目声明后,子项目中可以不写版本号
dependencies:在父项目中写了依赖后,子项目自动继承父项目的依赖,可以直接使用
创建项目:
groupId:公司名
artifactId:项目名
六、创建项目
验证项目
项目创建完成,可以通过package打包的方式,验证项目是否创建完成
父项目中packaging为pom
<packaging>pom</packaging>
3.创建子项目
new module
创建完子项目,父项目的pom文件中会多:
<modules><module>子项目名 </module>
<modules>
4. relativePath
relativePath用于找父项目的pom文件位置,默认就是../pom.xml
<relativePath>../pom.xml<relativePath>
5. 子项目调用
同一个父项目中的各个子项目,如果需要相互调用,可以在父项目中加对应的项目依赖,也可以在调用的项目中添加依赖
七、nacos
nacos只是一个应用服务,下载了以后,直接启动运行
nacos启动时,路径带中文会报错
windows上可以使用启动脚本来启动nacos,把启动命令放在bat文件中,双击bat文件就可以启动了
把服务注册到nacos中
在服务中添加nacos依赖
添加配置
在启动类中添加注解
@EnableDiscoveryClient
八、链式调用@Accessors
实体类上可以加@Accessors(chain=true)注解
用于链式调用,set完一个属性后可以直接再设置另一个属性,会返回对象本身
user.setName("").setAge();
九、springboot、spring cloud、spring cloud alibaba版本统一问题
spring cloud alibaba中有说明版本统一问题,可以通过dependcyManager在管理整个项目的版本
https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
在父项目中注明spring cloud alibab的版本号
十、openFeign
子项目之间调用可以使用openFegin
添加openFeign的依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
启动类需要添加注解
@EnableFeignClients
使用openFegin需要引用loadBalance依赖
使用openFeign进行远程调用
使用feign进行服务调用会出现的问题:
GET请求中,如果参数放在body中,使用@RequestBody进行参数传递,GET请求会被转成POST请求。
解决方式一:需要修改成路径参数 @PathVariable
解决方式二:添加依赖
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId></dependency>
十一、mysql8的数据库连接
需要写时区serverTimezone=GMT%2B8
十二、JWT
用于生成解析token
JWT:Json Web Token
官网:https://jwt.io/
第一部分和第二部分都可以被解析出来,所以token里面不要放很重要的信息
第三部分中有一个256位的密码,可以增加密码的安全性
项目中引入JWT
添加依赖
生成token
// 生成tokenpublic static String generatorToken(String phone , String identity , String tokenType) {Map<String,String> map = new HashMap<>();map.put(JWT_KEY_PHONE,phone);map.put(JWT_KEY_IDENTITY, identity);map.put(JWT_TOKEN_TYPE, tokenType);// 防止每次生成的token一样。map.put(JWT_TOKEN_TIME, Calendar.getInstance().getTime().toString());JWTCreator.Builder builder = JWT.create();// 整合mapmap.forEach((k,v) -> {builder.withClaim(k,v);});// 整合过期时间
// builder.withExpiresAt(date);// 生成 tokenString sign = builder.sign(Algorithm.HMAC256(SIGN));return sign;}
解析token
// 解析tokenpublic static TokenResult parseToken(String token){DecodedJWT verify = JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);String phone = verify.getClaim(JWT_KEY_PHONE).asString();String identity = verify.getClaim(JWT_KEY_IDENTITY).asString();TokenResult tokenResult = new TokenResult();tokenResult.setPhone(phone);tokenResult.setIdentity(identity);return tokenResult;}
十三、添加拦截器
实现HandlerInterceptor
重写preHandle方法
public class JwtInterceptor implements HandlerInterceptor {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {boolean result = true;String resutltString = "";String token = request.getHeader("Authorization");// 解析tokenTokenResult tokenResult = JwtUtils.checkToken(token);if (tokenResult == null){resutltString = "access token invalid";result = false;}else{// 拼接keyString phone = tokenResult.getPhone();String identity = tokenResult.getIdentity();String tokenKey = RedisPrefixUtils.generatorTokenKey(phone,identity, TokenConstants.ACCESS_TOKEN_TYPE);// 从redis中取出tokenString tokenRedis = stringRedisTemplate.opsForValue().get(tokenKey);if ((StringUtils.isBlank(tokenRedis)) || (!token.trim().equals(tokenRedis.trim()))){resutltString = "access token invalid";result = false;}}if (!result){PrintWriter out = response.getWriter();out.print(JSONObject.fromObject(ResponseResult.fail(resutltString)).toString());}return result;}
}
把拦截器注入到spring容器中
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {@Beanpublic JwtInterceptor jwtInterceptor(){return new JwtInterceptor();}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(jwtInterceptor())// 拦截的路径.addPathPatterns("/**")// 不拦截的路径.excludePathPatterns("/noauth").excludePathPatterns("/verification-code").excludePathPatterns("/verification-code-check");}
}
拦截器是在bean实例化前初始化的,所以拦截器中使用bean需要在拦截器配置类中手动注入要使用的bean
十四、token
token失效
可以通过token本身设置过期时间
也可以通过存储在redis中设置过期时间
双token
accessToken、refreshToken
accessToken是正常的访问token,refreshToken是刷新token,refreshToken的过期时间一般要比accessToken长。当accessToken快要过期了,但是用户正在访问,此时突然过期,对用户体验很不友好。此时,使用refreshToken访问,来更新accessToken和refreshToken。提高用户体验
可以在浏览器中安装JSON-handle插件,这样浏览器中的数据会展示成json格式
十五、读取yml中配置的参数
@Value
2. 配置文件
@Data
@Configuration
@ConfigurationProperties(prefix = "xxx.xxx.xxx")
public class ApiAuthProperties {private String url;private String checkToken;}
十六、Ribbon
Ribbon用法:
在启动类中添加RestTemplate
通过RestTemplate进行远程调用
openFeign和Ribbon的区别
openFeign内置了Ribbon,调用的是服务注册中心(Nacos)的服务
Ribbon可以调用第三方接口,需要手动调用
url中的参数是复杂json,包含数组,对象
需要对一些符号进行编码:[ ] " : ,
使用ribbon进行接口调用时,url需要使用URI.create(url)
十七、根据数据库表生成对应实体类
引入jar包
编写自动生成工具类
FastAutoGenerator.create("jdbc:mysql://localhost:3306/service-driver-user?characterEncoding=utf-8&serverTimezone=GMT%2B8","root","root").globalConfig(builder -> {builder.author("作者名").fileOverride().outputDir("导出文件路径");}).packageConfig(builder -> {builder.parent("com.mashibing.serviceDriverUser").pathInfo(Collections.singletonMap(OutputFile.mapperXml,"xxx\\service-driver-user\\src\\main\\java\\com\\mashibing\\serviceDriverUser\\mapper"));}).strategyConfig(builder -> {builder.addInclude("driver_user_work_status");}).templateEngine(new FreemarkerTemplateEngine()).execute();
加sql相关的日志
logging:level:com:baomidou:mybatisplus: debug
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
十八、请求参数
@RequestParam
写在params中的参数,接收时使用@RequestParam
@RequestBody
在body中的,接收时使用@RequestBody
@PathVariable
在路径中的,接收时使用@PathVariable
Header
header中的参数,接收时使用HttpServletRequest,httpServletRequest.getHeader("xxx");
十九、日期
实体类的中Date不推荐,推荐使用LocalDate
时间转成时间戳:
localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()
使用@JsonFormat注解,需要以下依赖
二十、请求错误码
4开头的是客户端的错误
5开头的是服务端的错误
400:参数有误,比如说日期格式有误
401:权限有误
404:地址有误
二十一、idea运行xml中的sql注意事项
勾选bulid project automatically
按住clt+shift+A,选择Register,勾选compiler.xxx
二十二、把mapper文件放在resource下,需要配置
二十三、数字与字符串
json格式中的字符串使用getLong获取,可能会导致精度丢失
可以getString后,通过Long.parseLong转换
小数用double存储,还是用字符串存储
如果小数用于计算,用double
如果不用于计算,只用于展示,可以用字符串
二十四、设置提交忽略目录
在项目的跟目录下找到.gitignore文件
写项目名/子项目名/target/,这样可以忽略target下所有文件
二十五、并发测试
工具:Jmeter
https://jmeter.apache.org/
需要配置环境变量JMETER_HOME
设置需要的参数
二十六、并发问题
单节点可以使用synchronized加锁
synchronized锁long类型的数据,可以使用:
synchronized(( longNum + "").intern())
当调用intern()方法时,如果常量池中已经有这个字符串(根据equals判断),则直接返回
如果常量池中没有,把这个字符串添加进常量池并返回
但是synchronized是jvm级别的,解决不了集群之间的并发问题
2. 集群可以使用redisson
RLock lock = redissonClient.getLock(lockKey);
lock.lock(); // 加锁
lock.unlock(); // 解锁
一个项目启动多次(测试集群部署)
添加多个端口号
复制两个项目启动
二十七、修改项目名
rename
修改包名
修改pom文件
二十八、其他
数据库名可以与服务名保持一致
JSONObject中是否有某个字段,可以用has
复制对象属性:
可以使用BeanUtils.copyProperties(src, dest);
微服务开发时,如果切换网络,可能会导致服务间调用不通了
前后端数据交互,可以使用:SseEmitter
路径中的下划线_和中划线-的区别:
搜索引擎关于爬虫的优化,建议在路径中使用中划线-
计算机通过外网被访问,需要提供一个外网的ip地址,可以使用花生壳产生一个外网ip
接入支付宝支付参考:https://opendocs.alipay.com/common/02ncur
相关文章:
项目心得--网约车
一、RESTFULPost:新增Put:全量修改Patch:修改某个值Delete: 删除Get:查询删除接口也可以用POST请求url注意:url中不要带有敏感词(用户id等)url中的名词用复数形式url设计:api.xxx.co…...
【二叉树广度优先遍历和深度优先遍历】
文章目录一、二叉树的深度优先遍历0.建立一棵树1. 前序遍历2.中序遍历3. 后序遍历二、二叉树的广度优先遍历层序遍历三、有关二叉树练习一、二叉树的深度优先遍历 学习二叉树结构,最简单的方式就是遍历。 所谓二叉树遍历(Traversal)是按照某种特定的规则ÿ…...
Spring Cloud微服务架构必备技术
单体架构 单体架构,也叫单体应用架构,是一个传统的软件架构模式。单体架构是指将应用程序的所有组件部署到一个单一的应用程序中,并统一进行部署、维护和扩展。在单体架构中,应用程序的所有功能都在同一个进程中运行,…...
TCP三次握手与四次挥手(一次明白)
TCP基本信息 默认端口号:80 LINUX中TIME_WAIT的默认时间是30s TCP三次握手 三次握手过程:每行代表发起握手到另一方刚刚收到数据包时的状态 客户端服务端客户端状态服务端状态握手前CLOSELISTEN客户端发送带有SYN标志的数据包到服务端一次握手SYN_SENDLISTEN二次握手服务端发送…...
pyside6@Mouse events实例@QApplication重叠导致的报错@keyboardInterrupt
文章目录报错内容鼠标事件演示报错内容 在pyside图形界面应用程序开发过程中,通常只允许运行一个实例 假设您重复执行程序A,那么可能会导致一些意向不到的错误并且,从python反馈的信息不容易判断错误的真正来源 鼠标事件演示 下面是一段演示pyside6的鼠标事件mouseEvent对象…...
订单30分钟未支付自动取消怎么实现?
目录了解需求方案 1:数据库轮询方案 2:JDK 的延迟队列方案 3:时间轮算法方案 4:redis 缓存方案 5:使用消息队列了解需求在开发中,往往会遇到一些关于延时任务的需求。例如生成订单 30 分钟未支付࿰…...
< 开源项目框架:推荐几个开箱即用的开源管理系统 - 让开发不再复杂 >
文章目录👉 SCUI Admin 中后台前端解决方案👉 Vue .NetCore 前后端分离的快速发开框架👉 next-admin 适配移动端、pc的后台模板👉 django-vue-admin-pro 快速开发平台👉 Admin.NET 通用管理平台👉 RuoYi 若…...
内网渗透-基础环境
解决依赖,scope安装 打开要给cmd powershell 打开远程 Set-ExecutionPolicy RemoteSigned -scope CurrentUser; 我试了好多装这东西还是得科学上网,不然不好用 iwr -useb get.scoop.sh | iex 查看下载过的软件 安装sudo 安装git 这里一定要配置bu…...
Go语言学习的第一天(对于Go学习的认识和工具选择及环境搭建)
首先学习一门新的语言,我们要知道这门语言可以帮助我们做些什么?为什么我们要学习这门语言?就小wei而言学习这门语言是为了区块链,因为自身是php出身,因为php的一些特性只能通过一些算法模拟的做一个虚拟链,…...
C和C++到底有什么关系
C++ 读作”C加加“,是”C Plus Plus“的简称。顾名思义,C++是在C的基础上增加新特性,玩出了新花样,所以叫”C Plus Plus“,就像 iPhone 6S 和 iPhone 6、Win10 和 Win7 的关系。 C语言是1972年由美国贝尔实验室研制成功的,在当时算是高级语言,它的很多新特性都让汇编程序…...
14个Python处理Excel的常用操作,非常好用
自从学了Python后就逼迫用Python来处理Excel,所有操作用Python实现。目的是巩固Python,与增强数据处理能力。 这也是我写这篇文章的初衷。废话不说了,直接进入正题。 数据是网上找到的销售数据,长这样: 一、关联公式:…...
async/await 用法
1. 什么是 async/await async/await 是 ES8(ECMAScript 2017)引入的新语法,用来简化 Promise 异步操作。在 async/await 出 现之前,开发者只能通过链式 .then() 的方式处理 Promise 异步操作。示例代码如下: import …...
好意外,发现永久免费使用的云服务器
原因就不说了,说一下过程,在百度搜pythonIDE的时候,发现了一个网站 https://lightly.teamcode.com/https://lightly.teamcode.com/ 就是这个网站,看见这个免费试用,一开始觉得没什么,在尝试使用的过程中发…...
VSCode使用技巧,代码编写效率提升2倍以上!
VSCode是一款开源免费的跨平台文本编辑器,它的可扩展性和丰富的功能使得它成为了许多程序员的首选编辑器。在本文中,我将分享一些VSCode的使用技巧,帮助您更高效地使用它。 1. 插件 VSCode具有非常丰富的插件生态系统,通过安装插…...
SQL执行过程详解
1 、用户在客户端执行 SQL 语句时,客户端把这条 SQL 语句发送给服务端,服务端的进程,会处理这条客户端的SQL语句。 2 、服务端进程收集到SQL信息后,会在进程全局区PGA 中分配所需内存,存储相关的登录信息等。 3 、客…...
【物联网NodeJs-5天学习】第四天存储篇⑤ ——PM2,node.js应用进程管理器
【NodeJs-5天学习】第四天存储篇⑤ ——PM2,node.js应用进程管理器1. 前言2. 官方说明3. 安装PM24. PM2常用命令4.1 启动命令4.2 重新启动命令4.3 热重载命令4.4 停止命令4.5 删除命令4.6 查看进程运行状态4.4 显示某一个进程的具体信息4.8 显示日志信息4.9 终端监控…...
【C++学习】【STL】deque容器
dequeDouble Ended Queues(双向队列)deque和vector很相似,但是它允许在容器头部快速插入和删除(就像在尾部一样)。所耗费的时间复杂度也为常数阶O(1)。并且更重要的一点是,deque 容器中存储元素并不能保证所有元素都存储到连续的内…...
当 App 有了系统权限,真的可以为所欲为?
看到群里发了两篇文章,出于好奇,想看看这些个 App 在利用系统漏洞获取系统权限之后,都干了什么事,于是就有了这篇文章。由于准备仓促,有些 Code 没有仔细看,感兴趣的同学可以自己去研究研究,多多…...
vue3.js的介绍
一.vue.js简述 Vue是一套用于构建用户开源的MVVM结构的Javascript渐进式框架,尤雨溪在2015年10月27日发布了vue.js 1.0Eavangelion版本,在2016年9月30日发布了2.0Ghost in the Shell版本,目前项目由官方负责 vue的核心只关注图层࿰…...
【Three.js】shader特效 能量盾
shader特效之能量盾前言效果噪点图主要代码index.htmldepth-fs.jsdepth-vs.jsshield-fs.jsshield-vs.js相关项目前言 效果噪点图 为了可以自定义能量球的效果,这里使用外部加载来的噪点图做纹理,省去用代码写特效的过程。 主要代码 index.html <…...
【6000字长文】需求评审总是被怼?强烈推荐你试试这三招
前段时间和一个合作部门的产品新人沟通需求,结束的时候,他问了我一个问题,“你在产品新人阶段,最害怕做的事情是什么”? 我不假思索的回答说,“需求评审,是曾经最不想面对的环节,甚至在评审之前几个小时就开始心跳加速了。当然这也是产品修炼路上的必经之路,其实只要掌…...
Hive介绍及DDL
1.OLTP和OLAP OLTP: 联机事务处理系统。在前台接收的用户数据可以立即传送到后台进行处理,并在很短的时间内给出处理结果。关系型数据库是OLTP典型应用,如MySQL OLTP环境开展数据分析是否可行? 为了更好的开展数据分析&#x…...
Simulink 自动代码生成电机控制:在某国产ARM0定点MCU上实现自动代码生成无感电机控制
目录 前言 开发流程 定点化的技巧 代码生成运行演示 总结 前言 这次尝试了在国产arm0内核的MCU上实现Simulink自动代码生成永磁同步电机无传感控制。机缘巧合之下拿到了一块国产MCU的电机控制板和一个5000RPM的小电机。最后实现了无传感控制,在这里总结下一些经…...
MySQL基本查询
文章目录表的增删查改Create(创建)单行数据 全列插入多行数据 指定列插入插入否则更新替换Retrieve(读取)SELECT列全列查询指定列查询查询字段为表达式查询结果指定别名结果去重WHERE 条件基本比较BETWEEN AND 条件连接OR 条件连…...
你需要知道的 7 个 Vue3 技巧
VNode 钩子在每个组件或html标签上,我们可以使用一些特殊的(文档没写的)钩子作为事件监听器。这些钩子有:onVnodeBeforeMountonVnodeMountedonVnodeBeforeUpdateonVnodeUpdatedonVnodeBeforeUnmountonVnodeUnmounted我主要是在组件…...
行政区划获取
行政区划获取一、导入jar包二、代码展示背景:公司的行政区划代码有问题,有的没有街道信息,有的关联信息有误,然后找到了国家的网站国家统计局-行政区划,这个里面是包含了所有的行政信息,但是全是html页面&a…...
让ChatGPT介绍一下ChatGPT
申请新必应内测通过了,我在New Bing中使用下ChatGPT,让ChatGPT介绍一下ChatGPT 问题1:帮我生成一篇介绍chatGPT的文章,不少于2000字 回答: chatGPT是什么?它有什么特点和用途? chatGPT是一种…...
【Redis】Redis 主从复制 + 读写分离
Redis 主从复制 读写分离1. Redis 主从复制 读写分离介绍1.1 从数据持久化到服务高可用1.2 主从复制1.3 如何保证主从数据一致性?1.4 为何采用读写分离模式?2. 一主两从环境准备2.1 配置文件2.2 启动 Redis3. 主从复制原理3.1 全量同步3.1.1 建立连接3…...
2023届秋招,鬼知道我经历了什么
仅记录个人经历,充满主观感受,甚至纯属虚构,仅供参考,杠就是你对 本想毕业再写,但是考虑到等毕业了,24秋招的提前批就快开始了,大概就来不及了,正好现在有点时间,陆陆续…...
ChatGPT助力校招----面试问题分享(一)
1 ChatGPT每日一题:期望薪资是多少 问题:面试官问期望薪资是多少,如何回答 ChatGPT:当面试官问及期望薪资时,以下是一些建议的回答方法: 1、调查市场行情:在回答之前,可以先调查一…...
网站搜索出来有图片/项目营销推广策划
以函数对象取代函数 使用场景: 你有一个大型函数,其中对局部变量的使用使你无法采用Extract Method. 解决方法:将这个函数放进一个单独的对象中,如此一来局部变量就变成了对象内字段,然后可以在同一个对象将这个大型函…...
网站开发公司业务/关键词点击优化工具
版本:mongodb3.4; Index : 如果mongodb不能使用索引进行排序,就会将数据放入内存中进行排序,而当内存使用超过32MB时,就会报错。 在创建索引时,应确保索引的选择力,避免多余的查询。避免没有选择力的索引。…...
企业建设网站的功能是什么/深圳百度seo公司
容器一直是应用程序开发行业的显着趋势之一,因为越来越多的组织选择它们来更快地构建、测试和部署他们的应用程序而没有摩擦。 容器本质上不是安全的。尽管容器具有内置的安全功能,但它们仍然需要第三方工具来保护运行时和开发环境。随着过去几年对公司…...
源汇区建设局网站/关键词权重
转眼似乎半个多月过去了,最近忙了点其他的事,所以这个CMS做的进度也慢了,不过昨天和今天稍微加了点班,把最大的一块制作OK了,也就是下面我要说的—— 窗口 先看下窗口大致构成图吧: 窗口很简单,…...
有可以花钱让人做问券的网站吗/广告策划案优秀案例
Redis为我们提供了publish/subscribe(发布/订阅)功能。我们可以对某个channel(频道)进行subscribe(订阅),当有人在这个channel上publish(发布)消息时,redis就会通知我们,这样我们可以收到别人发布的消息。作为Java的redis客户端,J…...
wordpress模板加密/网络推广优化网站
安装xlwt:到python官网下载xlwt模块后,执行python setup.py install,或者在PyCharm的Project Interpreter输入xlwt后点击Install Package就可以了。操作xlwt:导入xlwt模块:import xlwt ;创建workbook:xlwt.Workbook()&…...