VUE进行前后端交互
目录
一、 跨域
1. 什么是跨域?
2. 什么是本域?
3. 浏览器请求的三种报错
二、SpringBoot解决跨域问题+其他前后端跨域请求解决方案
1. SpringBoot上直接添加@CrossOrigin
2. 处理跨域请求的Configuration
3. 采用过滤器的方式
3.1 方式一
3.2 方式二
4. 其他解决方案---NGINX反向代理
三、VUE的前后端交互
1. 前后端交互模式
1.1 传统的交互方式
1.2 传统的URL
1.3RESTFUL风格的URL
2. Promise相关概念与使用
2.1 promise使用的优势
2.2 promise的基本用法
2.3 then参数的函数返回值
2.4 Promise常用API
2.5 Fetch接口调用
2.5.1 fetch的基本语法
2.5.2 fetch请求参数
2.6 Axios进行接口调用
2.6.1 axios基本用法
2.6.2 axios常用API
2.7 asyns/await接口调用
2.7.1 async/await的基本用法
参考文章:(8条消息) 三、vue前后端交互(轻松入门vue)_vue如何和后端交互_莫逸风的博客-CSDN博客
一、 跨域
1. 什么是跨域?
在了解什么是跨域的时候,我们首先要了解一个概念,叫同源策略,什么是同源策略呢,就是我们的浏览器出于安全考虑,只允许与本域下的接口交互。不同源的客户端脚本在没有明确授权的情况下,不能读写对方的资源。
2. 什么是本域?
本域指的是同协议、同端口、同域名
3. 浏览器请求的三种报错
① 请求未发送
② 请求发送后,服务器发现不一样,服务器未反应。
③ 请求发送,服务器有反应,数据返回的时候,浏览器发现不对,被拦截。
二、SpringBoot解决跨域问题+其他前后端跨域请求解决方案
1. SpringBoot上直接添加@CrossOrigin
在Controller层直接添加@CrossOrigin注解就可以解决
2. 处理跨域请求的Configuration
CrossOriginConfig.java
继承WebMvcConfigurerAdapter或者实现WebMvcConfigurer接口
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;/*** AJAX请求跨域* @author Mr.W* @time 2018-08-13*/
@Configuration
public class CorsConfig extends WebMvcConfigurerAdapter {static final String ORIGINS[] = new String[] { "GET", "POST", "PUT", "DELETE" };@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*").allowCredentials(true).allowedMethods(ORIGINS).maxAge(3600);}
}
3. 采用过滤器的方式
3.1 方式一
@Component
public class CORSFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletResponse res = (HttpServletResponse) response;res.addHeader("Access-Control-Allow-Credentials", "true");res.addHeader("Access-Control-Allow-Origin", "*");res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {response.getWriter().println("ok");return;}chain.doFilter(request, response);}@Overridepublic void destroy() {}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}
}
3.2 方式二
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.cors.reactive.CorsUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;/*** @author JiaweiWu* @create 2018/3/22.*/
@Configuration
public class RouteConfiguration {//这里为支持的请求头,如果有自定义的header字段请自己添加(不知道为什么不能使用*)private static final String ALLOWED_HEADERS = "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN,token,username,client";private static final String ALLOWED_METHODS = "*";private static final String ALLOWED_ORIGIN = "*";private static final String ALLOWED_Expose = "*";private static final String MAX_AGE = "18000L";@Beanpublic WebFilter corsFilter() {return (ServerWebExchange ctx, WebFilterChain chain) -> {ServerHttpRequest request = ctx.getRequest();if (CorsUtils.isCorsRequest(request)) {ServerHttpResponse response = ctx.getResponse();HttpHeaders headers = response.getHeaders();headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN);headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);headers.add("Access-Control-Max-Age", MAX_AGE);headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS);headers.add("Access-Control-Expose-Headers", ALLOWED_Expose);headers.add("Access-Control-Allow-Credentials", "true");if (request.getMethod() == HttpMethod.OPTIONS) {response.setStatusCode(HttpStatus.OK);return Mono.empty();}}return chain.filter(ctx);};}
}
1. ServerWebExchange的注释: ServerWebExchange是一个HTTP请求-响应交互的契约。提供对HTTP请求和响应的访问,并公开额外的服务器端处理相关属性和特性,如请求属性。
2.
4. 其他解决方案---NGINX反向代理
server {listen 80;server_name abc.com;#charset koi8-r;#access_log logs/host.access.log main;location /client { #访问客户端路径proxy_pass http://localhost:81;proxy_redirect default;}location /apis { #访问服务器路径rewrite ^/apis/(.*)$ /$1 break;proxy_pass http://localhost:82;}
}
三、VUE的前后端交互
1. 前后端交互模式
1.1 传统的交互方式
原生AJAX、基于jQuery的ajax、fetch、axios
1.2 传统的URL
格式:schema://host:port/path?query#fragment
schema:协议,例如http、https、ftp等。
host:域名或者IP地址。
port:端口,http默认端口80,可以省略。
path:路径,例如/abc/a/b/c
query:查询参数,例如uname=lisi&age=12
fragment:锚点(哈希Hash),用于定位页面的某个位置
1.3RESTFUL风格的URL
HTTP请求方式
- GET 查询
- POST 添加
- PUT 修改
- DELETE 删除
2. Promise相关概念与使用
2.1 promise使用的优势
Promise是异步编程的一种解决方案,从语法上讲,Promise是一个对象,从它可以获取异步操作的消息。
- 可以避免多层异步调用嵌套问题(回调地域)
- Promise对象提供了简介的API,使得控制异步操作更加容易
2.2 promise的基本用法
-
实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务。
-
resolve和reject两个(方法)参数用于处理成功和失败两种情况,并通过p.then获取处理结果。
var p = new Promise(function(resolve,reject){//成功时调用resolve()//失败时调用reject()
});
p.then(function(ret){//从resolve得到正常结果
},function(ret){//从reject得到错误信息
});
2.3 then参数的函数返回值
2.3.1 返回实例对象
p.then(function(ret){//返回一个实例对象,这个实例对象用于调用下一个thenreturn new Promise();
}).then(...)
???在上面也就是如果目前获取了对象就相当于传到了ret中,下一步then中ret则可以调用其中的数据或者其他方法???
2.3.2 返回普通值
返回的普通值会直接传递给下一个then,通过then函数中函数的参数接收该值(底层会对返回的普通值封装为一个Promise使得能够继续调用then)
p.then(function(ret){return "hahah";
}).then(function(ret){alter(ret); //这里的输出值就是 hahah
}
2.3.3 基于promise请求ajax的demo
<script>//Promise基本使用,原生ajaxfunction getText(url) {var p = new Promise(function (resolve, reject) {var xhr = new XMLHttpRequest();xhr.onreadystatechange = function () {//readyState表示文档状态if (xhr.readyState != 4) return;if (xhr.readyState == 4 && xhr.status == 200){//处理正常情况resolve(xhr.responseText);}else {reject('服务器错误');}};xhr.open('get',url);xhr.send(null);});return p;}//链式调用解决回调地狱,return一个新的调用就可以继续调用新的then()了。getText('http://localhost:8088/saymo').then(function (data) {alert(data);return getText('http://localhost:8088/sayyi');},function (info) {alert(info);}).then(function (data) {alert(data);return getText('http://localhost:8088/sayfeng')}).then(function (data) {alert(data);});
</script>
2.4 Promise常用API
2.4.1 实例方法
1. p.then() #输出执行结果
2. p.catch() #捕获异常
3. p.finally() #无论正常还是异常都会执行
<script>function foo() {return new Promise(function (resolve, reject) {setTimeout(function () {//resolve(123)//正常情况reject("出错了");//错误情况},1000)})}foo().then(function (data) {alert(data);}).catch(function (data) {alert(data);}).finally(function () {alert("结束了")})//与上面效果相同foo().then(function (data) {alert(data);},function (data) {alert(data);}).finally(function () {alert("结束了")})
</script>
2.4.2 对象方法
Promise.all() #并发处理多个异步任务,只有所有任务都执行完成才可以得到结果
Promise.race() #并发处理多个异步任务,只要有一个执行完成就可以得到结果
<script>function getText(url) {var p = new Promise(function (resolve, reject) {var xhr = new XMLHttpRequest();xhr.onreadystatechange = function () {//readyState表示文档状态if (xhr.readyState != 4) return;if (xhr.readyState == 4 && xhr.status == 200){//处理正常情况resolve(xhr.responseText);}else {reject('服务器错误');}};xhr.open('get',url);xhr.send(null);});return p;}var p1 = getText("http://localhost:8088/saymo");var p2 = getText("http://localhost:8088/sayyi");var p3 = getText("http://localhost:8088/sayfeng");//result是一个数组形式的三个数据,顺序和p1,p2,p3顺序相同Promise.all([p1,p2,p3]).then(function (result) {alert(result);})//result返回一个数据,最快返回的一个Promise.race([p1,p2,p3]).then(function (result) {alert(result);})
</script>
2.5 Fetch接口调用
还有一种更加简便的方法,就是使用fetch接口进行调用,这个是基于Promise实现的
2.5.1 fetch的基本语法
1. 语法结构
fetch(url).then(fn2).then(fn3)....cach(fn)
2. 基本用法
fetch('/abc').then(data=>{return data.text();
}).then(ret=>{//这里得到的才是最终的数据console.log(ret);
})
2.5.2 fetch请求参数
1. 常用配置选项
method(String):HTTP请求方法,默认为GET(GET、POST、PUT、DELETE)
body(String):HTTP的请求参数
headers(Object):HTTP的请求头,默认为{}
2. get请求参数传递
<script>fetch('http://localhost:8088/sayHi?name="莫逸风',{method:'get'}).then(function (data) {return data.text();}).then(function (data) {alert(data);});
</script>
3. post请求参数传递
参数form表单形式
fetch('http://localhost:8088/login',{method:'post',body:,headers:{'Content-Type':'application/x-www-form-urlencoded',// Content-Type还有下面三种形式//1. multipart/form-data//2. application/json//3. text/xml }}).then(function (data) {return data.text();}).then(function (data) {alert(data);})
参数json表单形式
fetch('http://localhost:8088/login',{method:'post',body:JSON.stringify({name:'莫逸风',pass:'1234',}),headers:{'Content-Type':'application/json',}}).then(function (data) {return data.text();}).then(function (data) {alert(data);});
4. 返回响应类型
text():将返回体处理成字符串类型
json():返回结果和JSON.parse(responseText)一样
2.6 Axios进行接口调用
axios(官网:https://github.com/axios/axios)是一个基于Promise用于浏览器和node.js的HTTP客户端
它具有以下特征:
- 支持浏览器和node.js
- 支持promise
- 能拦截请求和相应
- 自动转换JSON数据
2.6.1 axios基本用法
//去github下载文件,此js位于axios-master\dist
<script src="axios.js"></script>
<script>axios.get('http://localhost:8088/saymo').then(function (ret) {//data属性是固定的用法,用于获取后台的实际数据alert(ret.data)})
</script>
2.6.2 axios常用API
- get:查询数据
- post:添加数据
- put:修改数据
- delete:删除数据
1. get传递参数
通过URL传递参数
axios.get('http://localhost:8088/sayhi?name=莫逸风').then(function (ret) {alert(ret.data)})
通过params传递参数
axios.get('http://localhost:8088/sayhi',{params:{name:"莫逸风"}}).then(function (ret) {//data属性是固定的用法,用于获取后台的实际数据alert(ret.data)})
2. post传递参数
通过对象传递参数,默认为json格式
axios.post('http://localhost:8088/login',{name:"莫逸风",pass:"1234",}).then(function (ret) {//data属性是固定的用法,用于获取后台的实际数据alert(ret.data)})
通过URLSearchParams传递参数
var param = new URLSearchParams();
param.append('name','莫逸风');
param.append('pass','12345');axios.post('http://localhost:8088/login',param).then(function (ret) {//data属性是固定的用法,用于获取后台的实际数据alert(ret.data)})
3. axios的响应结果
- data:实际响应回来的数据
- headers:响应头信息
- status:响应状态码
- statusText:响应状态信息
axios.post('http://localhost:8088/login',param).then(function(ret){console.log(ret);//所有数据都包含在此对象中//对于json形式的响应数据可以直接获取,不需要转换alert(ret.data.name);
})
4. axios的全局配置
axios.defaults.timeout = 3000; //超时时间
//默认地址,再写请求的时候只需要写后面的路由就行了
axios.defaults.baseURL = 'http://localhost:3000/app';
axios.defaults.headers['mytoken']='aqwerwqwerqwer2ewrwe23eresdff23'//设置请求头
5. axios拦截器
请求拦截器
//在这里就是在请求之前设置了拦截器,用于获取网页http://localhost:8088/
axios.interceptors.request.use(function (config) {config.baseURL = "http://localhost:8088/";alert(config.url);return config;},function (err) {console.log(err);})axios.get('sayhi?name=莫逸风').then(function (ret) {//data属性是固定的用法,用于获取后台的实际数据alert(ret.data)})
响应拦截器
axios.interceptors.response.use(function (res) {var data = res.data;return data;},function (err) {console.log(err);})axios.get('sayhi?name=莫逸风').then(function (res) {//data属性是固定的用法,用于获取后台的实际数据alert(res)})
2.7 asyns/await接口调用
2.7.1 async/await的基本用法
async/await是ES7引入的语法,可以更加方便的进行异步操作
async关键字用于函数上(async函数的返回值是Promise实例对象)
await关键字用于async函数中(await可以得到异步的结果)
<script src="axios.js"></script>
<script>axios.defaults.baseURL = 'http://localhost:8088/';async function queryData(){var ret = await axios.get('saymo');//alert(ret.data);return ret.data;}queryData().then(function (data) {alert(data);});
</script>
异步请求
<script>axios.defaults.baseURL = 'http://localhost:8088/';async function queryData(){var ret = await axios.get('saymo');alert(ret.data);var ret1 = await axios.get('sayyi');alert(ret1.data);var ret2 = await axios.get('sayfeng');return ret2.data;}queryData().then(function (data) {alert(data);});
</script>
相关文章:

VUE进行前后端交互
目录 一、 跨域 1. 什么是跨域? 2. 什么是本域? 3. 浏览器请求的三种报错 二、SpringBoot解决跨域问题其他前后端跨域请求解决方案 1. SpringBoot上直接添加CrossOrigin 2. 处理跨域请求的Configuration 3. 采用过滤器的方式 3.1 方式一 3.2 方式…...
ThingsBoard Gateway:物联网设备数据采集与集成的强大解决方案
文章目录ThingsBoard Gateway:物联网设备数据采集与集成的强大解决方案1\. ThingsBoard Gateway:概述2\. 主要特点与优势3\. 应用场景4\. 如何使用ThingsBoard Gateway:物联网设备数据采集与集成的强大解决方案 随着物联网(IoT&a…...
什么是镜像/raid
镜像(Mirroring)是一种文件存储形式,是冗余的一种类型,一个磁盘上的数据在另一个磁盘上存在一个完全相同的副本即为镜像。可以把许多文件做成一个镜像文件,与GHOST等程序放在一个盘里用GHOST等软件打开后,又…...

【Python】如何有效比较两个时间序列在图形上的相似度?
文章目录前言一、1.准备二、实操1.使用Matplotlib可视化比较两个时间序列2.计算两个时间序列的相关系数:3.使用Python实现动态时间规整算法(DTW):总结前言 比较两个时间序列在图形上是否相似,可以通过以下方法&#x…...

JavaEE-常见的锁策略和synchronized的锁机制
目录常见的锁策略乐观锁和悲观锁轻量级锁和重量级锁自旋锁和挂起等待锁普通互斥锁和读写锁公平锁和非公平锁可重入锁和不可重入锁synchronized的锁机制synchronized特性锁升级/锁膨胀锁消除锁粗化常见的锁策略 乐观锁和悲观锁 乐观锁和悲观锁主要是看主要是锁竞争的激烈程度.…...

信息化,数字化,智能化是三种不同的概念吗?
前两年流行“信息化”,网上铺天盖地都是关于“信息化”的文章,这两年开始流行起“数字化”,于是铺天盖地都是“数字化”的文章。(这一点从数字化和信息化这两个关键词热度趋势就可以看出来)。 但点开那些文章仔细看看…...
【华为OD机试 2023最新 】 匿名信(C++ 100%)
题目描述 电视剧《分界线》里面有一个片段,男主为了向警察透露案件细节,且不暴露自己,于是将报刊上的字减下来,剪拼成匿名信。 现在又一名举报人,希望借鉴这种手段,使用英文报刊完成举报操作。 但为了增加文章的混淆度,只需满足每个单词中字母数量一致即可,不关注每个…...

硬件语言Verilog HDL牛客刷题day05 时序逻辑部分
1.VL29 信号发生器 1.题目: 题目描述: 请编写一个信号发生器模块,根据波形选择信号wave_choise发出相应的波形:wave_choice0时,发出方波信号;wave_choice1时,发出锯齿波信号;wave…...

Ajax 入门
前端技术:在浏览器中执行的程序都是前端技术。如 html、css、js 等 后端技术:在服务器中执行的长须,使用 Java 等语言开发的后端程序。servlet,jsp,jdbc,mysql,tomacat 等 全局刷新 使用表单…...

半导体器件基础06:发光二极管
说在开头:关于玻尔原子模型(1) 卢瑟福的模型面临着与经典电磁波理论的矛盾,按照经典电磁波理论,卢瑟福的原子不可能稳定存在超过1秒钟。玻尔面临着选择:要么放弃卢瑟福模型,要么放弃麦克斯韦伟…...

AutoCV第二课:Python基础
目录Python基础前言1.流程控制1.1 条件语句1.2 循环语句1.2.1 while循环语句1.2.2 for循环语句1.3 作业1.4 拓展-try except语法2.函数2.1 函数定义2.2 函数的参数2.2.1 位置参数2.2.2 命名参数2.2.3 默认参数2.2.4 可变参数2.2.5 参数展开2.3 递归函数2.3.1 递归函数定义2.3.2…...
LeetCode算法 打家劫舍 和 打家劫舍II C++
目录题目 打家劫舍参考答案题目 打家劫舍II参考答案题目 打家劫舍 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯…...

蓝桥杯刷题冲刺 | 倒计时10天
作者:指针不指南吗 专栏:蓝桥杯倒计时冲刺 🐾马上就要蓝桥杯了,最后的这几天尤为重要,不可懈怠哦🐾 文章目录1.有边数限制的最短路2.九进制转十进制1.有边数限制的最短路 题目 链接: 853. 有边数…...
个人练习-Leetcode-剑指 Offer II 109. 开密码锁
题目链接:https://leetcode.cn/problems/zlDJc7/ 题目大意:给出一个四位数字的密码锁,初始状态是0000,目标是targer。每一次转动只能让一个位的轮盘转动一下(0往后转是9)。有一个vector<string> dea…...
四个常见的Linux面试问题
四个常见的Linux面试问题。 刚毕业要找工作了,只要是你找工作就会有面试这个环节,那么在面试环节中,有哪些注意事项值得我的关注呢?特别是专业技术岗位,这样的岗位询问一般都是在职的工程师,如何在面试环节…...

15、接口(C#)
15.1 什么是接口 接口是指定一组函数成员而不实现它们的引用类型。所以只能类和结构实现接口。 15.2 声明接口 接口声明不能包含以下成员 数据成员静态成员 接口声明只能包含以下类型的费静态成员函数声明: 方法事件索引器属性 这些函数成员的声明不能包含任何实…...
C++中常见的容器类使用方法举例(vector、deque、map、set)
cpp中常见的容器类有vector、list、deque、map、set、unordered_map和unordered_set。 下面将举例直接说明各个容器的使用方法。 文章目录综合示例1. vector:动态数组,支持随机访问2. list:双向链表,支持双向遍历和插入删除3. de…...

什么是强缓存和协商缓存
什么是缓存 浏览器缓存就是把一个已经请求过的Web资源(如html页面,图片,js,数据等)拷贝一份副本储存在浏览器中。缓存会根据进来的请求保存输出内容的副本。当下一个请求来到的时候,如果是相同的URL&#…...
算法刷题之堆
1. heapq 堆 Python 中只有最小堆: import heapqa [] heapq.heappush(a, 3) # 添加元素 heapq.heappush(a, 2) heapq.heappush(a, 1) while len(a): # 判断堆的长度print(heapq.heappop(a)) # 弹出堆顶元素# 将列表转换为最小堆 nums [2, 3, 1, 4, 5, 6] hea…...

javaweb导师选择系统
本文以JSP为开发技术,实现了一个导师选择系统。导师选择系统分为三大模块,包括管理员:学员信息管理、导师信息管理、导师选择管理、导师分布图、公告信息管理、系统管理,学生:个人资料管理、导师选择管理、导师分布图管…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...