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

项目心得--网约车

一、RESTFUL

Post:新增

Put:全量修改

Patch:修改某个值

Delete: 删除

Get:查询

删除接口也可以用POST请求

url注意:

url中不要带有敏感词(用户id等)

url中的名词用复数形式

url设计:

api.xxx.com/courses

二、状态码和提示信息

code:状态码

message:success等

消息:真正的消息体

这样做可以省去解析消息体拿到状态码

三、分页

  1. /api/courses?page=1&size=10

  1. /api/courses?max_id=100&min_id=90

第一种缺点:不适合频繁有插入的情况(第一页的数据,可能在看第二页的时候被挤到第二页了,看到了重复数据)

第二种缺点:不合适看指定的页数(得要看了前一页之后,才能知道下一页的max_id和min_id)

四、接口设计工具

APIFOX

五、dependencies和dependencyManager

dependencyManager在父项目中只声明依赖,并不实现引用;子项目需要显示声明依赖;有利于版本统一,父项目声明后,子项目中可以不写版本号

dependencies:在父项目中写了依赖后,子项目自动继承父项目的依赖,可以直接使用

创建项目:

groupId:公司名

artifactId:项目名

六、创建项目

  1. 验证项目

项目创建完成,可以通过package打包的方式,验证项目是否创建完成

  1. 父项目中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中

  1. 在服务中添加nacos依赖

  1. 添加配置

  1. 在启动类中添加注解

@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

  1. 添加openFeign的依赖

       <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
  1. 启动类需要添加注解

@EnableFeignClients

  1. 使用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

  1. 添加依赖

  1. 生成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;}
  1. 解析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;}

十三、添加拦截器

  1. 实现HandlerInterceptor

  1. 重写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;}
}
  1. 把拦截器注入到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失效

  1. 可以通过token本身设置过期时间

  1. 也可以通过存储在redis中设置过期时间

双token

accessToken、refreshToken

accessToken是正常的访问token,refreshToken是刷新token,refreshToken的过期时间一般要比accessToken长。当accessToken快要过期了,但是用户正在访问,此时突然过期,对用户体验很不友好。此时,使用refreshToken访问,来更新accessToken和refreshToken。提高用户体验

可以在浏览器中安装JSON-handle插件,这样浏览器中的数据会展示成json格式

十五、读取yml中配置的参数

  1. @Value

2. 配置文件

@Data
@Configuration
@ConfigurationProperties(prefix = "xxx.xxx.xxx")
public class ApiAuthProperties {private String url;private String checkToken;}

十六、Ribbon

Ribbon用法:

  1. 在启动类中添加RestTemplate

  1. 通过RestTemplate进行远程调用

openFeign和Ribbon的区别

openFeign内置了Ribbon,调用的是服务注册中心(Nacos)的服务

Ribbon可以调用第三方接口,需要手动调用

url中的参数是复杂json,包含数组,对象

需要对一些符号进行编码:[ ] " : ,

使用ribbon进行接口调用时,url需要使用URI.create(url)

十七、根据数据库表生成对应实体类

  1. 引入jar包

  1. 编写自动生成工具类

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

设置需要的参数

二十六、并发问题

  1. 单节点可以使用synchronized加锁

synchronized锁long类型的数据,可以使用:

synchronized(( longNum + "").intern())

当调用intern()方法时,如果常量池中已经有这个字符串(根据equals判断),则直接返回

如果常量池中没有,把这个字符串添加进常量池并返回

但是synchronized是jvm级别的,解决不了集群之间的并发问题

2. 集群可以使用redisson

RLock lock = redissonClient.getLock(lockKey);
lock.lock(); // 加锁
lock.unlock(); // 解锁

一个项目启动多次(测试集群部署)

  1. 添加多个端口号

  1. 复制两个项目启动

二十七、修改项目名

  1. rename

  1. 修改包名

  1. 修改pom文件

二十八、其他

数据库名可以与服务名保持一致

JSONObject中是否有某个字段,可以用has

复制对象属性:

可以使用BeanUtils.copyProperties(src, dest);

微服务开发时,如果切换网络,可能会导致服务间调用不通了

前后端数据交互,可以使用:SseEmitter

路径中的下划线_和中划线-的区别:

搜索引擎关于爬虫的优化,建议在路径中使用中划线-

计算机通过外网被访问,需要提供一个外网的ip地址,可以使用花生壳产生一个外网ip

接入支付宝支付参考:https://opendocs.alipay.com/common/02ncur

相关文章:

项目心得--网约车

一、RESTFULPost&#xff1a;新增Put&#xff1a;全量修改Patch&#xff1a;修改某个值Delete: 删除Get&#xff1a;查询删除接口也可以用POST请求url注意&#xff1a;url中不要带有敏感词&#xff08;用户id等&#xff09;url中的名词用复数形式url设计&#xff1a;api.xxx.co…...

【二叉树广度优先遍历和深度优先遍历】

文章目录一、二叉树的深度优先遍历0.建立一棵树1. 前序遍历2.中序遍历3. 后序遍历二、二叉树的广度优先遍历层序遍历三、有关二叉树练习一、二叉树的深度优先遍历 学习二叉树结构&#xff0c;最简单的方式就是遍历。 所谓二叉树遍历(Traversal)是按照某种特定的规则&#xff…...

Spring Cloud微服务架构必备技术

单体架构 单体架构&#xff0c;也叫单体应用架构&#xff0c;是一个传统的软件架构模式。单体架构是指将应用程序的所有组件部署到一个单一的应用程序中&#xff0c;并统一进行部署、维护和扩展。在单体架构中&#xff0c;应用程序的所有功能都在同一个进程中运行&#xff0c;…...

TCP三次握手与四次挥手(一次明白)

TCP基本信息 默认端口号:80 LINUX中TIME_WAIT的默认时间是30s TCP三次握手 三次握手过程:每行代表发起握手到另一方刚刚收到数据包时的状态 客户端服务端客户端状态服务端状态握手前CLOSELISTEN客户端发送带有SYN标志的数据包到服务端一次握手SYN_SENDLISTEN二次握手服务端发送…...

pyside6@Mouse events实例@QApplication重叠导致的报错@keyboardInterrupt

文章目录报错内容鼠标事件演示报错内容 在pyside图形界面应用程序开发过程中,通常只允许运行一个实例 假设您重复执行程序A,那么可能会导致一些意向不到的错误并且,从python反馈的信息不容易判断错误的真正来源 鼠标事件演示 下面是一段演示pyside6的鼠标事件mouseEvent对象…...

订单30分钟未支付自动取消怎么实现?

目录了解需求方案 1&#xff1a;数据库轮询方案 2&#xff1a;JDK 的延迟队列方案 3&#xff1a;时间轮算法方案 4&#xff1a;redis 缓存方案 5&#xff1a;使用消息队列了解需求在开发中&#xff0c;往往会遇到一些关于延时任务的需求。例如生成订单 30 分钟未支付&#xff0…...

< 开源项目框架:推荐几个开箱即用的开源管理系统 - 让开发不再复杂 >

文章目录&#x1f449; SCUI Admin 中后台前端解决方案&#x1f449; Vue .NetCore 前后端分离的快速发开框架&#x1f449; next-admin 适配移动端、pc的后台模板&#x1f449; django-vue-admin-pro 快速开发平台&#x1f449; Admin.NET 通用管理平台&#x1f449; RuoYi 若…...

内网渗透-基础环境

解决依赖&#xff0c;scope安装 打开要给cmd powershell 打开远程 Set-ExecutionPolicy RemoteSigned -scope CurrentUser; 我试了好多装这东西还是得科学上网&#xff0c;不然不好用 iwr -useb get.scoop.sh | iex 查看下载过的软件 安装sudo 安装git 这里一定要配置bu…...

Go语言学习的第一天(对于Go学习的认识和工具选择及环境搭建)

首先学习一门新的语言&#xff0c;我们要知道这门语言可以帮助我们做些什么&#xff1f;为什么我们要学习这门语言&#xff1f;就小wei而言学习这门语言是为了区块链&#xff0c;因为自身是php出身&#xff0c;因为php的一些特性只能通过一些算法模拟的做一个虚拟链&#xff0c…...

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&#xff0c;所有操作用Python实现。目的是巩固Python&#xff0c;与增强数据处理能力。 这也是我写这篇文章的初衷。废话不说了&#xff0c;直接进入正题。 数据是网上找到的销售数据&#xff0c;长这样&#xff1a; 一、关联公式:…...

async/await 用法

1. 什么是 async/await async/await 是 ES8&#xff08;ECMAScript 2017&#xff09;引入的新语法&#xff0c;用来简化 Promise 异步操作。在 async/await 出 现之前&#xff0c;开发者只能通过链式 .then() 的方式处理 Promise 异步操作。示例代码如下&#xff1a; import …...

好意外,发现永久免费使用的云服务器

原因就不说了&#xff0c;说一下过程&#xff0c;在百度搜pythonIDE的时候&#xff0c;发现了一个网站 https://lightly.teamcode.com/https://lightly.teamcode.com/ 就是这个网站&#xff0c;看见这个免费试用&#xff0c;一开始觉得没什么&#xff0c;在尝试使用的过程中发…...

VSCode使用技巧,代码编写效率提升2倍以上!

VSCode是一款开源免费的跨平台文本编辑器&#xff0c;它的可扩展性和丰富的功能使得它成为了许多程序员的首选编辑器。在本文中&#xff0c;我将分享一些VSCode的使用技巧&#xff0c;帮助您更高效地使用它。 1. 插件 VSCode具有非常丰富的插件生态系统&#xff0c;通过安装插…...

SQL执行过程详解

1 、用户在客户端执行 SQL 语句时&#xff0c;客户端把这条 SQL 语句发送给服务端&#xff0c;服务端的进程&#xff0c;会处理这条客户端的SQL语句。 2 、服务端进程收集到SQL信息后&#xff0c;会在进程全局区PGA 中分配所需内存&#xff0c;存储相关的登录信息等。 3 、客…...

【物联网NodeJs-5天学习】第四天存储篇⑤ ——PM2,node.js应用进程管理器

【NodeJs-5天学习】第四天存储篇⑤ ——PM2&#xff0c;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很相似&#xff0c;但是它允许在容器头部快速插入和删除&#xff08;就像在尾部一样&#xff09;。所耗费的时间复杂度也为常数阶O(1)。并且更重要的一点是&#xff0c;deque 容器中存储元素并不能保证所有元素都存储到连续的内…...

当 App 有了系统权限,真的可以为所欲为?

看到群里发了两篇文章&#xff0c;出于好奇&#xff0c;想看看这些个 App 在利用系统漏洞获取系统权限之后&#xff0c;都干了什么事&#xff0c;于是就有了这篇文章。由于准备仓促&#xff0c;有些 Code 没有仔细看&#xff0c;感兴趣的同学可以自己去研究研究&#xff0c;多多…...

vue3.js的介绍

一.vue.js简述 Vue是一套用于构建用户开源的MVVM结构的Javascript渐进式框架&#xff0c;尤雨溪在2015年10月27日发布了vue.js 1.0Eavangelion版本&#xff0c;在2016年9月30日发布了2.0Ghost in the Shell版本&#xff0c;目前项目由官方负责 vue的核心只关注图层&#xff0…...

【Three.js】shader特效 能量盾

shader特效之能量盾前言效果噪点图主要代码index.htmldepth-fs.jsdepth-vs.jsshield-fs.jsshield-vs.js相关项目前言 效果噪点图 为了可以自定义能量球的效果&#xff0c;这里使用外部加载来的噪点图做纹理&#xff0c;省去用代码写特效的过程。 主要代码 index.html <…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...