Express框架从入门到如土

news2024/11/28 4:46:07

目录

  • 前言
  • 一,初体验
  • 二,路由
    • 2.1 什么是路由
    • 2.2. 路由的使用
    • 2.3 获取请求报文参数
    • 2.4 id的通配
    • 2.5 响应的设置
  • 三,中间件
    • 3.1 中间件概述
    • 3.2 全局中间件与路由中间件的比对
    • 3.3 全局中间件的使用
    • 3.4 局部中间件的使用
    • 3.5 静态资源中间件(内置)
    • 3.6 获取请求体数据中间件(外置)
  • 四,路由模块化
  • 五,模板引擎
    • 5.1 模板引擎
    • 5.2 EJS
    • 5.3 EJS与express框架的结合
  • 六,express-generator
    • 6.1 创建一个express项目
    • 6.2 代码结构
    • 6.3 url前缀
  • 后记

前言

Express框架是一个基于Node.js平台的极简的、灵活的web开发框架。封装了Nodejs的http模块。我们可以通过Express框架来实现很多功能。

学习本篇文章需要有前端三件套以及发送请求相关的基础,还要有Nodejs的相关基础(http模块)。这些在笔者的专栏中都有涉及到,可以查看:

前后端交互知识储备
Nodejs

话不多说,开始学习。

一,初体验

首先,需要进行包管理初始化:

npm i init -y

接着需要下载express包:

npm i express

接着,我们来写如下代码:

//导入express
const express = require('express')
//创建实例对象
const app = express()

//创建路由
app.get('/home', (req, res) => {
    res.end('hello express')
})

//监听端口
app.listen(3000, () => {
    console.log('服务已经启动,端口3000正在监听中...')
})

在写完下面代码后终端运行:

在这里插入图片描述
打开127.0.0.1:3000/home:
在这里插入图片描述

二,路由

2.1 什么是路由

官方定义:路由确定了应用程序如何响应客户端对待特定端点的请求。

2.2. 路由的使用

路由的组成有:请求方法、路径、回调函数。

express提供了一系列方法,可以很方便的使用路由:

app.<method>(path.callback)

其中,method可以是get,也可也是post,和http模块非常类似。

这里有一个特例:

app.get('/', (req, res) => {
    res.end('home')
})

发送请求,面上为空,实际上报文中是一个/。

访问首页一般都不会主动设置路径,都由上面这个路由规则进行响应。

在这里插入图片描述
还有一个路由比较特殊:

app.get('*', (req, res) => {
    res.end('404 not found')
})

在这个路由规则中,*代表着,除了上面写的其他路由规则之外的请求,都会返回404。

另外再说一个比较特殊的,不过是方法上的特殊:

app.all('/text', (req, res) => {
    res.end(test)
})

上面这串代码,无论是get还是post都会返回test。

2.3 获取请求报文参数

框架封装了一些API来方便获取请求报文中的数据,并且兼容原生HTTp模块的获取方式。

我们先来看一下原生的操作:

const express = require('express')

const app = express()

app.get('/request', (req, res) => {
    // 原生操作
    console.log(req.method)//获取请求方法
    console.log(req.url)//获取请求url
    console.log(req.httpVersion)//获取http版本
    console.log(req.header)//获取请求头部
    res.end('hello express')
})

app.listen(3000, () => {
    console.log('服务已经启动,端口3000正在监听中......')
})

上面这些方法在express框架中依旧可以使用。是因为express是兼容http模块的。

我们来看一下运行结果:
在这里插入图片描述
接着我们来看看用express框架下该如何获取请求报文参数:

    console.log(req.path)//获取路径
    console.log(req.query)//获取查询字符串
    console.log(req.ip)//获取ip
    console.log(req.get('host'))//获取某个请求头

这次发送一个携带参数的请求:
在这里插入图片描述
在控制台显示的结果是:
在这里插入图片描述

2.4 id的通配

这里从前端的角度来说。比如我要做一个产品页面。

产品页面中会有很多个产品,每个产品点开后的展示格式是一样的,但是内容是不一样的。每个产品在数据库里面有个id。

那我们在发送请求申请产品的时候是不是要把每个产品的id对应的路由都写到呢?非也。

我们可以写一个id的通配,实现每个id发送请求都可以响应相应数据:

app.get('/:id.html', (req, res) => {
    //获取路由参数
    console.log(req.params.id)//获取id
    res.send('产品')
})

无论请求后面是哪个参数,都可以获取相应的页面:
在这里插入图片描述

2.5 响应的设置

原生http的响应在express框架中依然适用。

我们来看一下原生跟响应有关的设置:

app.get('/response', (req, res) => {
    // 原生响应
    res.statusCode = 400;//状态码
    res.statusMessage = 'love'//响应信息
    res.setHeader('xxx', 'yyy')//响应头
    res.write('hello express')//设置响应体1
    res.end('response')//设置响应体2
    res.end('response')
})

接着看一下express中与响应有关的配置:

    //express响应
    res.status(500);//状态码
    res.set('aaa', 'bbb')//响应头
    ResizeObserver.send('你好')//响应体
    // 其他响应
    res.redirect('http://baidu.com')//路由重定向

三,中间件

3.1 中间件概述

中间件的本质是一个回调函数。作用是封装一些公共操作,简化代码。

中间件函数可以像路由一样,访问请求对象request和响应对象response。

中间件的作用:使用函数封装公共操作,简化代码。

中间件的类型分为两种:全局中间件和路由中间件。

3.2 全局中间件与路由中间件的比对

这里举一个例子。我们去火车站坐车,大概会有两次检票。第一次是进候车厅的时候我们需要扫身份证进行检票,在这个过程中,不同车次的人,只要在这一天有火车可做,都可以通过候车厅的检票口进入候车厅。

当我们进入候车厅后,时间到了,我们再次检票。这一次检票是在检票口,检票通过后就可以去往各自的车次。检票的时候,是同一车次的人一起检票。而不是所有人一拥而上。

我们可以把第一次检票看作全局中间件;把第二次检票看作路由中间件。

全局中间件一旦启用,在每一个请求发起时都会用到;而路由中间件一旦启用,相应路由在请求发起的时候会用到。

以上是全局中间件与路由中间件的区别。

3.3 全局中间件的使用

说一个需求,我们来实现。首先看以下路由规则:

app.get('/home', (req, res) => {
    res.send('前台首页')
})

app.get('/admin', (req, res) => {
    res.send('后台首页')
})

app.all('*', (req, res) => {
    res.send('<h1>404 Not Found</h1>')
})

现在我们来说需求:在每一个请求发起的时候,在一个文件中记录请求的的url和ip。

以下是分析:
既然是每个请求发起都要记录,那么每个路由被请求都需要有响应处理。所以是一个全局中间件。之前也说过全局中间件是一个函数。所以我们可以把这个函数定义在外面:

//声明中间件函数
function recordMiddleware(req, res, next) {

}
app.use(recordMiddleware)

app.get('/home', (req, res) => {
    res.send('前台首页')
})

app.get('/admin', (req, res) => {
    res.send('后台首页')
})

app.all('*', (req, res) => {
    res.send('<h1>404 Not Found</h1>')
})

==这个函数一共有三个参数:req,res,next。==前面也说过,中间件函数可以获取到路由的req,res。另外还要多一个参数:==next。==这个next参数是函数类型。

next参数,我们可以这么理解:当这个中间件函数调用完,才会调用next。调用next之后,会继续调用路由或者下一个中间件。

接着我们来看一下上面这个需求的完整代码:

const express = require('express')
const app = express();
const fs = require('fs')
const path = require('path')

//声明中间件函数
function recordMiddleware(req, res, next) {
    let {url, ip} = req;
    fs.appendFileSync(path.resolve(__dirname, './assess.log'), `${url} ${ip}\r\n`)
    next()
}
app.use(recordMiddleware)

app.get('/home', (req, res) => {
    res.send('前台首页')
})

app.get('/admin', (req, res) => {
    res.send('后台首页')
})

app.all('*', (req, res) => {
    res.send('<h1>404 Not Found</h1>')
})
app.listen(3000, () => {
    console.log('服务器已经启动,端口3000正在监听...')
})

上面这段代码,我来讲一下中间件函数的内部,主要是跟nodejs相关的。如果想单纯了解中间件也可也跳过。

在这段代码中,我们引入了fs和path模块。首先利用解构赋值获取到了req(请求报文)中的url和ip。其次,我们利用fs模块中的appendFileSync,这个api的作用是利用fs模块在文件中写东西,由于后面加了Sync这个后缀,所以是同步的,(一般情况下异步会有个回调函数,同步就没有)。再说说这个在文件中写东西的函数内部,内部利用path模块,resove函数是拼接字符串,第一个参数是该文件(写东西)的地址,第二个参数是写进去的内容。内容用到了字符串变量的操作。把之前获得的url和ip写进去。

最后调用next,证明上面的已经执行完毕,可以接着执行中间件或者路由。

==需要注意的是,全局中间件需要app.use一下,相当于是注册全局中间件。注册后就可以正常使用了。==完整代码在上面,有兴趣可以复制粘贴玩一下。

最后要说的是,全局中间件可以调用多个。

以上就是全局中间件的相关讲解。

3.4 局部中间件的使用

先说需求:针对/admin和/setting的请求,要求URL携带code=521参数,入围携带提示【暗号错误】。

先看基础代码:

const express = require('express')
const app = express()

app.get('/admin', (req, res) => {
    res.end('12321')
})

app.get('/setting', (req, res) => {
    res.end('12321')
})

app.listen(3000, () => {
    console.log('服务器已启用...')
}) 

接着我们来分析一下这个需求:这个需求是只针对个别路由的,所以此时,我们要选择使用局部中间件。通过局部中间件获取url并判断里面的code参数是否是521。如果是521,那么我们可以继续执行路由规则;如果不是,则返回暗号错误。

下面我们来看一下代码:

const express = require('express')
const app = express()

//声明中间件
let checkCodeMiddleware = (req, res, next) => {
    if(req.query.code === '521') {
        next();
    } else {
        res.send('暗号错误')
    }
}

app.get('/admin', checkCodeMiddleware, (req, res) => {
    res.end('12321')
})

app.get('/setting', checkCodeMiddleware, (req, res) => {
    res.end('12321')
})

app.listen(3000, () => {
    console.log('服务器已启用...')
}) 

==这个地方需要注意的是,局部中间件的注册,是在app后面调用中,以参数的形式传递的。==为了防止大家看不懂,我这里用一张图来说明下这个代码顺序:
在这里插入图片描述
看上图,当我们发送一个请求,会先判断请求的url,选择响应路由,这是第一步;接着,第二步是执行中间件,就拿上面这个例子来说,如果code是521,则执行next(),next之后就是执行下面的路由规则啦,就是第三步,执行res.end;如果不是,那就是返回’暗号错误’。

3.5 静态资源中间件(内置)

静态资源中间件是express框架中的一个内置的中间件,用于挂载静态资源,把一些静态资源挂在在网页上,正确的url访问后就可以显示出来。

接着我们来复习一下静态资源和静态资源目录这两个概念。

静态资源是指我们在写代码的时候用到的html,css,js,图片等,这些都是静态资源。

静态资源目录可以理解为网站的根目录。

接着看一下静态资源中间件的使用。既然是静态资源的挂载,所以我们先建一个静态资源目录,public,内部有一个html文件作为静态资源:
在这里插入图片描述

在这里插入图片描述
现在我们来使用内置的静态资源中间件:

const express = require('express')
const app = express()

// 静态资源的中间件注册
app.use(express.static(__dirname + '/public'));

app.get('/admin', (req, res) => {
    res.send('222')
})

app.listen(3000, () => {
    console.log('服务器已经启动...')
})

接着,就已经把静态资源挂载到我们电脑自带的服务器上了:
在这里插入图片描述

在这里插入图片描述
使用期间的注意事项:
1.index.html文件是默认打开的资源;
2.如果静态资源与路由规则同时匹配(‘/’),谁先匹配谁就响应(跟代码顺序有关);
3.路由响应动态资源,静态资源中间件响应静态资源。

3.6 获取请求体数据中间件(外置)

这个中间件是别人写好了的,并且不是内置,所以如果我们要用,需要安装和导入。

这个中间件名为border-parser。

安装导入:
在这里插入图片描述
导入border-parser包:
在这里插入图片描述
中间件使用方式:这里有两种使用方式,一种是作为全局中间件;一种是作为路由中间件。这里更推荐路由中间件,并不是每个请求都需要这个中间件来处理,使用路由中间件(局部中间件)使得项目运行效率更高。

接着是该中间件的使用,该中间件的使用有两种方式:

//解析 JSON 格式的请求体的中间件
const jonParser = bodyParser.json()
//解析 queryString 格式请求体的中间件
const urlencodeParser = bodyParser.urlencoded({ extended: false });

如何看使用哪种方式获得请求体呢?在请求的载荷中:
在这里插入图片描述
可以看出,是querystring格式的。

如果我们要用,我们可以放到相对应位置去。

请看以下完整版代码及注释:

const express = require('express')
// 导入包
const bodyParser = require('body-parser')
const app = express()

// 使用body-parser中间件
//解析 JSON 格式的请求体的中间件
const jonParser = bodyParser.json()
//解析 queryString 格式请求体的中间件
const urlencodeParser = bodyParser.urlencoded({ extended: false });

app.get('/login', (req, res) => {
    // 响应文件内容
    res.sendFile(__dirname + '/10._form.html')
})

app.post('/login', urlencodeParser, (req, res) => {
    console.log(req.body)//多一个body属性用来存放请求体
    res.send('获取用户的数据')
})

app.listen(3000, () => {
    console.log('服务器已启动...')
})

表单页面代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>登录页面</title>
</head>
<body>
    <form action="http://127.0.0.1:3000/login" method="post">
        用户名:<input type="text" name="username"><br/>
        密码: <input type="password" name="password">
        <button>登录</button>
    </form>
</body>
</html>

最后结果:
在这里插入图片描述
这里还有一个中间件的应用,感兴趣可以查看:
一文带你搞懂防盗链

四,路由模块化

模块化编程,增加了代码的复用性,提高了每一块代码的独立性。

路由模块化,可以简单理解为,拆路由

接下来,我以一个例子来讲解路由的模块化。

这是一个完整的代码,有前台有后台,现在我们把这个代码的前后台拆分一下:

const express = require('express')
const app = express()

//前台
app.get('/home', (req, res) => {
    res.send('前台首页')
})
app.get('/search', (req, res) => {
    res.send('内容搜索')
})

//后台
app.get('/admin', (req, res) => {
    res.send('后台首页')
})

app.get('/setting', (req, res) => {
    res.send('设置页面')
})

app.all('*', (req, res) => {
    res.send('<h1>404 Not Found</h1>')
})

app.listen(3000, () => {
    console.log('服务器已经运行...')
})

我们先来拆分前台路由,新建一个文件after存放内容:
在这里插入图片描述
在after中导入express并引入router:

//导入express
const express = require('express')
//创建路由对象
const router = express.Router()

接着把跟前台有关的路由放进文件并且把app改为router:

router.get('/home', (req, res) => {
    res.send('前台首页')
})
router.get('/search', (req, res) => {
    res.send('内容搜索')
})

最后再暴露出去,下面是整体代码:

//导入express
const express = require('express')
//创建路由对象
const router = express.Router()
//创建路由规则
router.get('/home', (req, res) => {
    res.send('前台首页')
})
router.get('/search', (req, res) => {
    res.send('内容搜索')
})

//暴露router
module.exports = router;

但是还没结束,还要在all中引入并注册才能够正常使用:

const express = require('express')
// 导入前台
const homeRouter = require('./after.js')
const app = express()
//注册
app.use(homeRouter)

这样以后才可以正常使用:
在这里插入图片描述
然后是后台,直接放代码,不再赘述:

const express = require('express')
const router = express.Router()
router.get('/admin', (req, res) => {
    res.send('后台首页')
})

router.get('/setting', (req, res) => {
    res.send('设置页面')
})

module.exports = router

这是整体代码:

const express = require('express')
// 导入前台
const homeRouter = require('./after.js')
// 导入后台
const adminRouter = require('./before.js')
const app = express()
//注册
app.use(homeRouter).use(adminRouter)


app.all('*', (req, res) => {
    res.send('<h1>404 Not Found</h1>')
})

app.listen(3000, () => {
    console.log('服务器已经运行...')
})

五,模板引擎

5.1 模板引擎

模板引擎是分离用户界面和业务数据的一种技术。(用于分离html与js的)

5.2 EJS

EJS是一种高级的模板引擎。

官网:官网
中文站:中文站

文档很清楚,有需要可参考。

这里我来总结下,在EJS中有一个地方非常关键,那就是

<% %>

这个符号内部是js代码,而这个符号的外部是html的结构。

这个是我总结出来的一个点。可以方便大家学习。

5.3 EJS与express框架的结合

可参考如下代码及注释:

const express = require('express')
const ejs = require('ejs')
const path = require('path')
const app = express()

//1.设置模板引擎,模板引擎有很多种,所以要设置是哪一种,我们用的ejs
app.set('view engine', 'ejs');
// 2.设置模板文件(具有模板语法内容的文件)存放位置,模板文件一定是后缀为ejs的,不然没办法找到
app.set('views', path.resolve(__dirname, './express'))

//3.render方法进行响应
app.get('/home', (req, res) => {
    // res.render('模板的文件名', '数据')
    let title = '123'
    res.render('view', {title})
})

app.listen(3000, () => {
    console.log('已经在服务器的 3000端口 运行...')
})

六,express-generator

6.1 创建一个express项目

在前面的内容中,express是我们手写出来的。而express-generator这个工具可以帮我们创建一个express框架的标准结构。一些基本的东西我们就没必要再写。

使用这个工具,首先需要安装:

npm i express-generator -g

安装之后,利用名字可以创建一个express项目:

express -h '文件夹名'

初始化的项目结构是这样的:
在这里插入图片描述
接着来说一下项目运行,项目在运行前,需要下载一些初始化:

npm i

接着是运行:
在这里插入图片描述
在上面这个文件中已经说明,运行的指令是:

npm start

在做完上面这些后,我们可以看一看效果:
在这里插入图片描述
代表运行成功。

6.2 代码结构

app.js是项目主文件;
views目录用于存放页面文件;
routes目录用于存放路由文件;
public用于存放静态文件;
bin中的www是项目的启动文件;

6.3 url前缀

在app.js代码中,有这样一段:

var usersRouter = require('./routes/users');
app.use('/users', usersRouter);

第二个use,对应的是routes中的usersRouter,我们再看看usersRouter的内容:

var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

module.exports = router;

在这段代码中,如果单看get请求,会发现只是个斜杠。但是这个斜杠真的可以显示出send的内容么?我们试一下:
在这里插入图片描述
不行。

原因:需要加前缀,前缀是users:

app.use('/users', usersRouter);

加前缀后可以返回相应内容:
在这里插入图片描述

后记

以上就是express框架的学习内容。

如果觉得有用可以点赞收藏加关注哦,后面有相关文章会发消息推送给您。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/597928.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

“邮件营销新趋势,这个平台让你收获颇丰!

随着各媒体平台的迅速发展&#xff0c;2023年大家更专注于视频营销、网红营销、直播营销等营销方式。可以见得&#xff0c;数字媒介手段的发展&#xff0c;对于营销方式也产生了巨大的影响。但是&#xff0c;企业在拥抱新兴的营销方式的同时&#xff0c;也不要忽视传统的营销方…

好用的Chrome浏览器插件推荐(不定期更新)

好用的Chrome浏览器插件推荐 1.1 CSDN-浏览器助手1.2 Google 翻译1.3 JSON Viewer1.4 ModHeader - Modify HTTP headers1.5 Octotree - GitHub code tree 1.1 CSDN-浏览器助手 CSDN-浏览器助手 是一款集成本地书签、历史记录与 CSDN搜索(so.csdn.net) 的搜索工具 推荐&#x…

碳中和背景下我国空调系统发展趋势2022(李先庭)

碳中和背景下我国空调系统发展趋势 摘要 我国建筑空调系统在运行阶段的年碳排放量约为&#xff19;&#xff0e;&#xff19;亿&#xff54;二氧化碳&#xff0c;降低其碳排放是实现碳达峰碳中和目标的重要挑战之一。本文对我国当前空调系统碳排放量进行了拆解&#xff0c;分…

node-exporter,prometheus,grafana三者之间的联系

一、node-exporter与节点机 用于收集节点机器的数据信息&#xff0c;那么node-exporter与节点机器的连接在哪里&#xff1f; node-exporter.yaml apiVersion: apps/v1 kind: DaemonSet metadata:name: node-exporternamespace: kube-systemlabels:k8s-app: node-exporter spe…

调整直线导轨间隙有什么方法?

直线导轨作为机械行业中非常重要的传动部件&#xff0c;应用范围当然相当广泛&#xff0c;尤其是自动化设备&#xff0c;基本上我们都能看到它的作用。 在机械行业待得久的人都知道&#xff0c;直线导轨在使用的过程中&#xff0c;为了保证直线导轨的正常工作&#xff0c;直线导…

C++ string类-2

at at 函数是在C还没有支持运算符重载的时候提供的。 他可以像 [] 重载运算符一样&#xff0c;找到某个位置的字符&#xff1a; string s1("hello world");s1.at(0) x;cout << s1 << endl; 输出&#xff1a; [] 重载运算符和 at&#xff08;&#x…

GIT常见报错以及解决方法

GIT常见报错以及解决方法 Changes not staged for commit问题复现原理解决 warning: adding embedded git repository问题复现原理解决 error: src refspec master does not match any问题复现 Changes not staged for commit问题复现&#xff1a;解决 Changes not staged for …

软考A计划-电子商务设计师-电子商务基础知识

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

chatgpt赋能python:Python为什么成为不可或缺的编程语言?

Python为什么成为不可或缺的编程语言&#xff1f; Python语言在过去的十年间&#xff0c;已经成为编程领域中不可或缺的一种语言。Python语言是一种高级、通用、面向对象语言&#xff0c;并且在数据科学、机器学习、网站开发等众多领域中广泛应用。本文将探讨为什么Python成为…

保护密码安全:ADSelfService Plus的重要性与优势

引言&#xff1a; 在当今数字化时代&#xff0c;密码安全对于个人和组织而言变得愈发重要。随着互联网的普及和数据泄露事件的频发&#xff0c;传统的用户名和密码已经不再足够保护我们的个人和机密信息。为了解决这个问题&#xff0c;许多组织开始采用密码管理工具&#xff0…

Fourier分析入门——第13章——信号分析

目录 第13章 信号分析 13.1 引言 13.2 加窗(windowing) 13.3 用一系列窗口采样(Sampling with an array of windows) 13.4 混叠现象(Aliasing) 13.5 通过插值重建(Reconstruction by interpolation) 13.6 非点采样(Non-point sampling) 13.7 覆盖系数规则(The coverage …

Yolov8轻量级:VanillaNet一种新视觉Backbone,极简且强大!华为诺亚2023

简到极致、浅到极致!深度为6的网络即可取得76.36%@ImageNet的精度,深度为13的VanillaNet甚至取得了83.1%的惊人性能。 1.VanillaNet 论文:https://arxiv.org/pdf/2305.12972.pdf 来自华为诺亚、悉尼大学的研究者们提出了一种极简的神经网络模型 VanillaNet,以极简主义的设…

第十三篇、基于Arduino uno,获取薄膜压力传感器的值——结果导向

0、结果 说明&#xff1a;先来看看串口调试助手显示的结果&#xff0c;第一个值是上电后检测到的平均压力值&#xff0c;第二个值是实时的压力值&#xff0c;第三个值是平均压力值和实时压力值的差值。如果是你想要的&#xff0c;可以接着往下看。 1、外观 说明&#xff1a;…

windows上简单部署flink

Windows上部署flink1.17 flink的下载链接 进入页面后下滑找到Apache Flink&#xff0c;然后找到对应版本&#xff0c;之后点击Binaries 找到xxx-bin-scala-xxx.tgz文件下载 下载完成后直接本地解压 解压后进入bin目录新增两个.bat文件&#xff08;直接复制下面内容<注意命名…

扩展dlink-connector-phoenix使其phoenix-5.0.0支持flink1.16

感慨&#xff1a;玩大数据java必须要精通,不然遇到眼花缭乱的框架以及插件拓展的时候就会一下子傻眼了。各种框架之间版本不同有现成的插件或者方案到还可以但是没有就需要自己扩展。目前我使用的是CDH6.3.2&#xff0c;flink使用的是1.6&#xff0c;Phoenix版本的是5.0.0这有在…

数据结构入门7-1(查找)

目录 注 查找的基本概念 线性表的查找 顺序查找 折半查找 分块查找 树表的查找 二叉排序树 平衡二叉树 平衡二叉树的定义 平衡二叉树的平衡调整方式 平衡二叉树的实现 B-树 B-树的定义 B-树的示意性实现 B树 注 本笔记参考&#xff1a;《数据结构&#xff08;C…

【04】数据结构与算法基础-类C语言有关操作补充 | 数组的静态、动态定义 | C、C++中内存分配 | C++中的参数传递方式-指针、数组、引用

目录 1.元素类型说明1.1顺序表类型定义1.2数组定义1.3C语言的内存动态分配1.4C的动态存储分配1.4.1创建内存1.4.2释放内存 1.5C中的参数传递1.5.1传值方式1.5.2传地址方式-指针变量1.5.3传地址方式-数组名1.5.4传地址方式-引用类型 1.元素类型说明 1.1顺序表类型定义 typedef…

HDFS 的健壮性体现在哪里?

前言 本文隶属于专栏《大数据技术体系》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见大数据技术体系 正文 HDFS 的主要目标就是即使在出错的情况下也要保…

Linux进程间通信(消息队列)

可以用命令“ipcs”查看三种 IPC&#xff0c;“ipcrm”删除 IPC 对象。在 i.MX6ULL 终结者开发板终端输入“ipcs” 查看系统中存在的 IPC 信息&#xff1a; 这些 IPC 对象存在于内核空间&#xff0c;应用层使用 IPC 通信的步骤为&#xff1a; 1. 获取 key 值&#xff0c;内核…

【网络】交换机的原理和配置方法

目录 &#x1f341;交换机工作原理 &#x1f341;交换机接口的双工模式 &#x1f341;交换机命令行模式 &#x1f341;交换机常见命令 &#x1f9e7;帮助命令 &#x1f9e7;常用命令介绍 &#x1f341;交换机的基本配置 &#x1f9e7;配置接口的双工模式及速率 &#x1f990;博…