Node.js教程-express框架

news2024/11/22 20:51:16

概述

Express是基于Node.js平台(建立在Node.js内置的http模块上),快速、开放、极简的Web开发框架
中文官网 http://www.expressjs.com.cn/。
Github地址:https://github.com/orgs/expressjs。

Express核心特性:

  • 可设置中间件来响应 HTTP 请求
  • 定义了路由表用于执行不同的 HTTP 请求
  • 可通过向模板传递参数来动态渲染 HTML 页面

安装

npm i express

以上命令会将express安装在当前目录下的node_modules文件夹下,并且将其依赖的包也一并下载下来
以下几个和express搭配使用的包:

  • body-parser 用于处理 JSONRawTextURL中的请求数据
  • cookie-parser 用于处理Cookie
  • multer 用于处理**enctyoe=“multipart/form-data””**的表单数据

基本使用

基本使用步骤:

  1. 导入 express 模块
  2. 创建 express 实例
  3. 创建并启动HTTP服务
  4. 绑定请求事件
// 1. 导入 express 包
const express = require('express')

// 2. 创建 express 实例
const app = express()

// 3. 启动服务
app.listen(80, () => {
  console.log("Express server is starting ...")
})

// 4. 绑定请求事件
app.get("/", (req, res) => {
  console.log("请求进来了 >>> " + req.url)
  res.end("Hello Node.js")
})

set 方法

set方法用于指定变量的值

// 设置 端口
app.set("port", process.env.PORT)

// 设定views变量,意为视图存放的目录
app.set('views', path.join(__dirname, 'views'));

// 设定view engine变量,意为网页模板引擎
app.set('view engine', 'jade');

请求和响应

Express处理请求中回调函数的参数:requestresponse对象来处理请求和响应。

request 对象

request对象表示 HTTP请求,包含了请求查询的字符串参数内容HTTP头部等属性。常见属性:

  • request.appcallback为外部文件时,用其访问express实例
  • request.baseUrl 获取当前的 URL 路径
  • request.method 获取请求方法
  • request.body 获取请求体内容
  • request.cookie 获取 Cookie 内容
  • request.hostname 获取主机名
  • request.ip 获取IP
  • request.originalUrl 获取原始请求 URL
  • request.params 获取请求参数(动态匹配的参数)
  • request.path 获取请求路径
  • request.protocol 获取请求协议
  • request.query 获取URL的查询参数
  • request.route 获取请求匹配的路由
  • request.get() 获取指定的请求头
  • request.is() 判断请求头Content-TypeMIME类型
// http://domain:port/x1/x2/wz?age=18
request.path  // /x1/x2/wz
request.params  // wz
request.query  // age
// 引入express 模块
const express = require('express')

// 创建 实例
const app = express()

// 启动服务
app.listen(80, () => {
  console.log("Server is starting ...")
})

// 绑定 get 请求事件
app.get('/user', (req, res) => {
  // req.protocol 获取请求协议
  console.log("protocol >>> ", req.protocol)
  // req.method 获取请求方法
  console.log("method >>> ", req.method)
  // req.hostname 获取主机名
  console.log("hostname >>> ", req.hostname)
  // req.ip 获取请求 IP
  console.log("ip >>> ", req.ip)
  // req.originalUrl 获取请求原始路径
  console.log("originalUrl >>> ", req.originalUrl)
  // req.path 获取请求路径
  console.log("path >>> ", req.path)
  // req.route 获取请求路由
  console.log("route >>> ", req.route)
  // req.params 获取请求参数
  console.log("params >>> ", req.params)
  // req.query 获取请求查询参数
  console.log("query >>> ", req.query)
  // req.body 获取请求体
  console.log("body >>> ", req.body)

  res.end("GET")
})

// 绑定 post 请求事件
app.post('/user', (req, res) => {
  // req.protocol 获取请求协议
  console.log("protocol >>> ", req.protocol)
  // req.method 获取请求方法
  console.log("method >>> ", req.method)
  // req.hostname 获取主机名
  console.log("hostname >>> ", req.hostname)
  // req.ip 获取请求 IP
  console.log("ip >>> ", req.ip)
  // req.originalUrl 获取请求原始路径
  console.log("originalUrl >>> ", req.originalUrl)
  // req.path 获取请求路径
  console.log("path >>> ", req.path)
  // req.route 获取请求路由
  console.log("route >>> ", req.route)
  // req.params 获取请求参数
  console.log("params >>> ", req.params)
  // req.query 获取请求查询参数
  console.log("query >>> ", req.query)
  // req.body 获取请求体
  console.log("body >>> ", req.body)

  res.end("POST")
})

response 对象

response 对象表示 HTTP响应,即在接受到请求时向客户端发送的数据。常见属性:

  • response.appcallback为外部文件时,用其访问express实例
  • response.cookie(name, value[, options]) 设置Cookie信息
  • response.clearCookie() 清空Cookie
  • response.download() 传送指定的文件
  • response.get() 获取指定的HTTP头信息
  • response.set(name, value) 设置响应头(Header)
  • response.json() 响应JSON格式的数据
  • response.render(view[, locals], callback) 渲染网页模版
  • response.send() 发送响应
  • response.sendFile(path[, options][, fn]) 传送文件
  • response.status() 设置 HTTP 状态码
  • response.type() 设置 Content-TypeMIME类型
  • response.redirect() 设置重定向

路由

路由即路径映射。在Express中,路由指客户端的请求与服务器处理函数的映射。
Express中路由是一个单独的组件Express.Router
Express中路由由三部分组成,分别为请求类型请求URL处理函数。其格式如下:

app.method(path, handler())

路由匹配过程

  • 请求到达服务器时,先经过路由的匹配,匹配成功了,才会调用对应的处理函数
  • 在匹配时,按照定义的顺序依次匹配,仅当请求类型和请求URL同时匹配成功了,才会调用对应的处理函数

在这里插入图片描述

// 导入 express 模块
const express = require('express')

// 创建 express 实例
const app = express()

// 创建路由实例
const router = express.Router()

// 挂载路由
router.get('/user', (req, res) => {
  res.send("express router")
})

// 注册路由
app.use('/api', router)

// 启动服务
app.listen(80, () => {
  console.log("Server is starting ...")
})

// 访问路径 http://domain:port/api/user

中间件

中间件(Middleware)指业务流程的中间处理环节。其是一个函数,包含了requestrespoonsenext三个参数,其中 next() 把流转交给下一个中间件或路由。

Express 中间件调用流程
在这里插入图片描述
注意:

  1. 在注册路由之前注册中间件(错误中间件除外)
  2. 多个中间件共享requestresponse对象
  3. next() 函数后不能再写逻辑代码

全局中间件

通过app.use()注册的中间件为全局中间件

const express = require('express')

const app = express()

// 注册全局中间件
app.use((req, res, next) => {
	console.log("中间件A")
})

// 注册全局中间件
app.use((req, res, next) => {
	console.log("中间件B")
})

app.get('/user', (req, res) => {
	res.send("ok")
})

app.listen(8888)

局部中间件

const express = require('express')

const app = express()

// 定义中间件
const mw1 = (req, res, next) => {
	console.log("中间件A")
}

// 注册全局中间件
const mw2 = (req, res, next) => {
	console.log("中间件B")
}

app.get('/user', mw1, mw2, (req, res) => {
	res.send("ok")
})

app.post('/user', [mw1, mw2], (req, res) => {
	res.send("ok")
})

app.listen(8888)

中间件分类

中间件按照作用可划分为三类:应用级别中间件路由级别中间件错误级别中间件

应用级别中间件

通过app.use()app.method()注册,即绑定到app实例上的中间件即为应用级别中间件。(其中methodgetpostputdelete等请求方法)

const express = require('express')

const app = express()

// 注册路由
app.use('/', (req, res, next) => {
	next()
})
路由级别中间件

通过router.use()注册,即绑定到router实例上的中间件即为路由级别中间件

const express = require('express')

const app = express()
const router = express.Router()

// 路由上注册中间件
router.use((req, res, next) => {
	next()
})

// 注册路由
app.use('/', router)
错误级别中间件

错误级别中间件用来捕获整个项目中发生的异常,从而防止项目异常崩溃。
错误级别中间件的处理函数中必须有4个形参,即(error, request, response, next)
错误级别中间件必须注册在所有路由之后

const express = require('express')

const app = express()

// 请求处理 ...

// 注册错误中间件
app.use((err, req, res, next) => {
	next()
})

内置中间件

Express中内置了多个中间件,极大的提高了 Express 项目的开发效率。常见内置中间件:

  • express.static 快速托管静态资源

    express.static(root[, options])

  • express.json 解析JSON格式的请求体数据

  • express.urlencoded 解析 url-encoded 格式的请求体数据

// 快速托管静态资源
app.use(express.static(path))

// 通过 express.json() 这个中间件,解析表单中的 JSON 格式的数据
app.use(express.json())

// 通过 express.urlencoded() 这个中间件,来解析表单中的 url-encoded 格式的数据
app.use(express.urlencoded({ extended: false }))

第三方中间件

cookie-parser

cookie-parser 用于处理请求中的Cookie
https://github.com/expressjs/cookie-parser

设置Cookie

res.cookie(name, value[, options])

参数说明

  • name cookie名称
  • value cookie值
  • options 配置参数
    • domain 域名。默认为当前域名
    • expires 失效时间。未设置或0,表示浏览器关闭后即失效
    • maxAge 最大失效时间(指从当前时间开始多久后失效),单位毫秒
    • securetrue时,cookie 在 http 失效,https 生效
    • path cookie在什么路径下有效。默认为**/**
    • httpOnly 只能被访问,防止 XSS攻击
    • signed 是否签名。默认指为false

不签名实例

const express = require('express')
const cookieParser = require('cookie-parser')

// 创建 app 实例
const app = express()

// 注册 Cookie中间件
app.use(cookieParse())

app.get('/setCookie', (req, res) => {
	res.cookie('name', '张三', {
		maxAge: 10000
	})
	res.send('cookie set success!')
})

app.listen(8888)

签名实例

const express = require('express')
const cookieParser = require('cookie-parser')

const app = express()

app.use(cookieParser('^123$'))  // ^123$ 为签名秘钥

app.get('setCookie', (req, res) => {
    // 将cookie的name 进行签名
	res.cookie("name", "张三", {maxAge: 100000, signed: true})
})

获取Cookie

注意:Cookie签名与不签名获取的方式不一样。req.cookies获取不签名cookiereq.signedCookies获取签名cookie
不签名实例

const express = require('express')
const cookieParser = require('cookie-parser')

// 创建 app 实例
const app = express()

// 注册 Cookie中间件
app.use(cookieParser())  //

app.get('/getCookie', (req, res) => {
	console.log(req.cookies)
	res.send("cookie got")
})

app.listen(8888)

签名实例

const express = require('express')
const cookieParser = require('cookie-parser')

// 创建 app 实例
const app = express()

// 注册 Cookie中间件
app.use(cookieParser('^123$'))  // ^123$ 为签名秘钥

app.get('/getCookie', (req, res) => {
	console.log(req.signedCookies)
	res.send("cookie got")
})

app.listen(8888)
删除Cookie

res.clearCookie(name[, options])

express-session

express-session用于处理请求中的会话。
https://github.com/expressjs/session

配置 session

session(options)

参数说明:

  • options 配置参数
    • cookie cookie设置
    • genid sessionid算法。默认为uid-safe库自动生成id
    • name 会话名称。默认为 connect.sid
    • secret 会话签名秘钥
    • store 会话存储方式。默认为内存
    • resave 是否强制保存会话,及时未被修改也被保存。默认为true
    • saveUninitialized 强制将未初始化的会话保存至存储中。(会话是新的且未被修改即为未初始化)
    • unset 是否保存会话。默认为keep,不保存可设置为destory
const express = require('express')
const session = require('express-session')

const app = express()

app.use(session({
	name: "session-cookie",
	secret: "^123456$",  // 会话签名秘钥
	cookie: {
		maxAge: 2 * 60 * 60 * 1000
	}
}))

req.session

req.session可用于存储或访问会话数据,以JSON的形式序列化。

const express = require('express')
const session = require('express-session')

// 创建服务实例
const app = express()

// 配置session,并注册session中间件
app.use(session({
  name: "express",
  secret: "^123456$",
  resave: false,
  saveUninitialized: true
}))

app.get('/setSession', (req, res) => {
  // 存储会话
  req.session.name = "李四"
  res.send("set session success")
})

app.get('/getSession', (req, res) => {
  // 获取会话
  console.log(req.session)
  res.send("session got")
})


// 启动服务
app.listen(8888)
属性
属性说明
req.session.id会话ID
req.session.sessionID会话ID
req.session.cookie获取会话中的 cookie 对象, 而后可对其修改
req.session.cookie.maxAge会话有效剩余时长
req.session.cookie.originalMaxAge返回会话 cookie 的原始 maxAge, 以毫秒为单位
方法
方法说明
req.session.regenerate(callback)重新生成会话
req.session.destroy(callback)销毁会话并取消设置 req.session 属性
req.session.reload(callback)从存储重新加载会话数据并重新填充 req.session 对象
req.session.save(callback)讲会话保存至 store,用内存中的内容替换 store上的内容
req.session.touch()更新 .maxAge属性
JWT

JWT(JSON Web Token)是由三部分组成:HeaderPayload(真正的用户信息,加密后的字符串)、Signature
JWT工作原理:用户的信息以Token的字符串的形式,保存在客户端中。用户每次请求,将Token存放在请求头Authorization上,服务器拿到该值后进行解析处理。
在这里插入图片描述
Expressjsonwebtoken模块用于生成JWT字符串,express-jwt用于将JWT字符串还原成JSON对象。

使用
  1. 安装模块
    npm install jsonwebtoken express-jwt
    
  2. 引入模块
    const jwt = requre('jsonwebtoken')
    const expressJWT = require('express-jwt')
    
  3. 生成 JWT 字符串

    jwt.sign(payload, secret[, options[, callback]])

    payload 存储的对象
    secret 签名秘钥
    options 配置参数。常见有 expiresIn(过期时间)、algorithm(签名算法)
    callback 回调函数

    app.post('/api/login', (req, res) => {
    	let token = jwt.sign({username: username}, '^123456$', {expireIn: '2h'})
    })
    
  4. 还原 JWT 字符串
    // 此处的 secret 值必须和jwt 生成时所使用的秘钥相同
    // unless 指定了哪些接口无须携带Token访问
    app.use(expressJWT({secret: '^123456$'}).unless({path:[/^\/api\//]}))
    
  5. 获取 JWT 信息

    在访问权限的接口中,可通过req.user对象即可访问 JWT 字符串中解析的内容

  6. 捕获 JWT 异常
    // 通过异常中间件来处理JWT解析失败
    app.use((err, req, res, next) => {
    	if(err.name === 'UnauthorizedError') {
    	  // TODO
    	}
    	next()
    })
    
multer

multer是用于处理multipart/form-data类型的表单数据,主要用于上传文件。(不会处理任何非 multipart/form-data 的数据 )
multer在解析完请求体后,会向request对象上添加一个body对象和一个filefiles对象。body对应表单中提交的文本字段,filefiles包含了表单上传的文件。
https://github.com/expressjs/multer

multer(options)

参数说明:

  • options 参数配置
    • dest / storage 上传文件存放目录。
    • fileFilter 文件过滤器
    • limits 限制上传文件 (可有效防止Dos攻击)
      • fieldNameSize field名字最大长度。默认为 100 bytes
      • fieldSize field指最大长度。默认为1MB
      • fields 非文件field的最大数量。默认为无限
      • fileSize 文件最大长度,单位字节。默认为无限
      • files 文件最大数量。默认为无限
      • parts part传输的最大数量(field + file)。默认为无限
      • headerPairs 键值对最大组数。默认为2000
    • preservePath 保存包含文件名的完整路径
storage

storage为存储引擎,multer中具有DiskStorageMemoryStorage和第三方等引擎。

DiskStorage

DiskStorage为磁盘存储引擎,其有两个选项可用:destinationfilename
destination 用来确定上传的文件存放的位置。可提供一个 stringfunction。若没有设置则使用操作系统默认的临时文件夹。
注意:destination 是一个function,则需用手动创建文件夹;若destination 是一个string,multer 会自动创建。
filename用来确定文件夹中文件名。若未设置该参数,则文件将设置一个随机文件名且没有后缀名。

const storage = multer.DiskStorage({
	distination: function(req, file, cb) {
		cb(null, '/xxx/xxx')
	}
	filename: function(req, file, cb) {
		cb(null, file.fieldname + "_" + Date.now())
	}
})

const upload = multer({storage: storage})
MemoryStorage

MemoryStorage 为内层存储引擎(将内容存储在Buffer中)

const storage = multer.memoryStorage()
const upload = multer({storage: storage})

注意:当使用内层存储,上传文件非常大,或上传文件非常多时,可能会导致内层溢出。

方法

multer.single(fieldname)
multer.signle()接受一个以filename命名的文件,文件保存至request.file
multer.array(fieldname[, maxCount])
multer.array() 接受一个以fieldname命名的文件数组,可配置maxCount来限制上传文件数量,文件保存至request.files
multer.fields(fields)
multer.fields()接受fileds的混合文件,文件保存至request.files
multer.none()
multer.none() 只接受文本域,和multer.fields([])效果一样。若该模式有文件上传,则抛出LIMIT_UNEXPECTED_FILE
multer.any()
multer.any() 接受一切上传的文件。文件保存至request.files

const multer = require('multer')

// 存储设置
const storage = multer.DiskStorage({
	distination: function(req, file, cp) {
		cp(null, '/xxx/xx')
	}
	filename: function(req, file, cp)
})

const upload = multer({storage:storage})

app.post('/upload/photo', upload.single('avatar'), function (req, res) {
  // req.file 是 `avatar` 文件的信息
  // req.body 将具有文本域数据,如果存在的话
})

app.post('/upload/file', upload.array('file', 3), function (req, res) {
  // req.files 是 `file` 文件组的信息
  // req.body 将具有文本域数据,如果存在的话
})

app.post('/upload', upload.fields([{name: 'avatar', maxCount: 1},{name: 'file', maxCount: 3}]), function (req, res) {
  // req.files 是一个对象 (String -> Array) 键是文件名,值是文件数组
  // 	req.files['avatar'][0] -> File
  //    req.files['file'] -> Array
  // req.body 将具有文本域数据,如果存在的话
})
文件属性
属性说明
fieldname表单定义的名称
originalname文件原始名称
encoding文件编码
mimetype文件的 MIME 类型
size文件大小
distination文件保存路径
filename保存至 distination 中的文件名
path已上传文件的完整路径
buffer存放整个文件的 Buffer

自定义中间件

自定义中间件流程:

  1. 定义中间件
  2. 监听request对象的 data 事件
  3. 监听 request 对象的 end 事件
  4. 解析请求参数
  5. 封装模块

自定义中间件解析POST提交的数据

// querything 是 Node.js的内置模块
const qs = require('querything')

// 定义中间件
const bodyParser = (req, res, next) => {
	let str = ''

	// 监听 req 的 data 事件
	req.on('data', (chunk) => {
		str += chunk
	})
	
	req.on('end', () => {
		// 解析数据,并将数据放在 req 的 body 中,供下游访问
		req.body = qs.parse(str)
		next()
	})
}

module.exports = bodyParser

模板

Express模板是用于渲染视图的文件,可以包含HTMLCSSJavaScript等内容,用于构建 Web应用程序的图形界面。
使用Express模板可以快速、方便地创建Web应用程序,并可轻松地将动态数据注入到模板中,以便呈现动态效果。常见的模版引擎有:EJS、Pug、Handlebars 等。

分类

Express模板可分静态模板动态模板两类:

  1. 静态模板 预先定义好的 HTML 文件,可通过路由直接呈现
  2. 动态模板 通过模版引擎加载动态数据来生成动态内容

Express中常用的模板引擎:

  • 基于HTML的模版引擎:MustacheHandlebars
  • 基于JavaScript的模版引擎:EJSUnderscore.js
  • 基于CSS的模版引擎:LESSSASS

使用

模版使用步骤

  1. 下载模板包
  2. 配置模版引擎 app.set("view engine", "xxx")
  3. 配置模板路径 app.set("views", path.resolve(__dirname, "views")) (表示模板存放在当前目录下views文件夹中)
  4. 在请求响应中设置渲染 res.render('xx',renderDataObj)

express-generator

express-generator 是 快速创建 express 项目生成器工具。

使用

## 1. 全局安装 express-generator
npm i -g express-generator


## 2. 创建项目
#### 快速创建 [project_name[ 的项目,并且使用默认的 jade 模板引擎
express [project_name]  

#### 快速创建 [project_name[ 的项目,并且使用指定的 ejs 模板引擎
express [project_name] --view=ejs


## 3.进入到项目根目录下执行 npm install
npm install

## 4. 启动项目
#### npm 命令
npm run start   或   npm start

#### node 命令
node ./bin/www

## 5.访问 express-generator生成的项目服务默认端口为 3000 

项目结构

在这里插入图片描述

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

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

相关文章

关于“Python”的核心知识点整理大全40

目录 alien_invasion.py game_functions.py 14.3.3 在外星人被消灭时更新得分 settings.py game_functions.py game_functions.py alien_invasion.py 14.3.4 将消灭的每个外星人的点数都计入得分 game_functions.py 14.3.5 提高点数 settings.py settings.py 注意…

【Java JVM】Java 实例对象的访问定位

Java 程序会通过栈上的 reference 数据来操作堆上的具体对象。 但是 reference 类型在《Java虚拟机规范》里面只规定了它是一个指向对象的引用, 并没有定义这个引用应该通过什么方式去定位, 访问到堆中对象的具体位置, 所以对象访问方式也是由虚拟机实现而定的,主流…

iApp最新版无服务器多功能软件库源码

无需服务器的多功能软件库源码分享,仅需添加一个后台应用和一个文档即可 使用教程如下: 在浏览器中打开理想后台地址:http://apps.xiaofei.run/user/ 如果没有账号,请注册一个免费账号。 登录账号后,添加一个后台应…

web架构师编辑器内容-HTML2Canvas 截图的原理

HTML2Canvas 截图的原理 目的:一个canvas元素,上面有绘制一系列的HTML节点 局限:canvas中没法添加具体的Html节点,它只是一张画布 通过canvas.getContext(‘2d’)可以拿到canvas提供的2D渲染上下文,然后在里面绘制形…

洛谷 P3397 地毯 刷题笔记 二维差分矩阵

P3397 地毯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 方法1 欺负数据小 暴力水过 #include<iostream> using namespace std; const int N1010; int a[N][N]; int main(){ int n,m; cin>>n>>m; for(int i0;i<m;i){ int x1,y1,…

基于STM32的DS1302实时时钟模块应用

DS1302是一款低功耗的实时时钟芯片&#xff0c;被广泛应用于各种电子产品中。它具有准确计时、多种时间格式表示、定时报警等功能&#xff0c;适用于记录时间、日期和闹钟。在本文中&#xff0c;我们将介绍如何在基于STM32的开发环境中使用DS1302实时时钟模块&#xff0c;并给出…

【重点!!!】【单调栈】84.柱状图中最大矩形

题目 法1&#xff1a;单调栈[原版] O(N)O(N) 必须掌握算法&#xff01;&#xff01;&#xff01; class Solution {public int largestRectangleArea(int[] heights) {int n heights.length, res 0;int[] leftMin new int[n], rightMin new int[n];Stack<Integer>…

开源项目解读 —— Self-Operating Computer Framework # 长期主义 # 价值

价值&#xff1a;生成主函数业务逻辑函数思维导图&#xff0c;帮助理解&#xff0c;PR到开源项目&#xff0c;希望帮助大家理解IPA工作原理&#xff0c;国内没有好的开源项目&#xff0c;我就来翻译分析解读&#xff0c;给大家抛砖引玉。思维导图用文心一言配合其思维导图插件实…

jar 运行清单文件MANIFEST.MF生成定义Main-Class Premain-Class IDEA maven-assembly-plugin

可运行jar文件中的启动清单文件 META-INF/MANIFEST.MF 内容自定义生成 清单文件中的 Main-Class: Premain-Class: Can-Retransform-Classes: 在maven-assembly-plugin插件中的生成配置如下, 注意命名 <archive> <manifest> <mainClass>c…

华为设备VRP系统管理

为了满足企业业务对网络的需求&#xff0c;网络设备中的系统文件需要不断进行升级。另外&#xff0c;网络设备中的配置文件也需要时常进行备份&#xff0c;以防设备故障或其他灾害给业务带来损害。在升级和备份系统文件或配置文件时&#xff0c;经常会使用FTP和TFTP来传输文件。…

浅谈Springboot默认logger函数的使用

目录 前言1. logger日志2. 补充 前言 原先写过一篇logger日志函数的总结&#xff0c;不同的引用来源&#xff1a;java常见log日志的使用方法详细解析 但是为了不引入依赖包&#xff0c;更好的直接使用&#xff0c;总结了如下博文 1. logger日志 Spring Boot使用Spring框架中…

基于阿里云服务网格流量泳道的全链路流量管理(二):宽松模式流量泳道

作者&#xff1a;尹航 在前文基于阿里云服务网格流量泳道的全链路流量管理&#xff08;一&#xff09;&#xff1a;严格模式流量泳道中&#xff0c;我们介绍了使用服务网格 ASM 的严格模式流量泳道进行全链路灰度管理的使用场景。该模式对于应用程序无任何要求&#xff0c;只需…

语法树的画法(根据文法求字符串)

目录 1.语法树的画法 2.语法树的短语 3.直接短语&#xff08;直接到根部&#xff09; 4.素短语 5.句柄 6.算符优先分析句型 1.语法树的画法 文法G[E]:E->EE | E*E | (E) | i ,字符串 ii*i 推导方式有两种最左推导和最右推导&#xff08;推导的技巧就是逐步靠近字符串…

数禾使用 Knative 加速 AI 模型服务部署丨KubeCon China 2023

作者&#xff1a;李鹏&#xff08;阿里云&#xff09;、魏文哲&#xff08;数禾科技&#xff09;&#xff0c; 此文基于 KubeCon China 2023 分享整理 摘要 AI 服务的数据、训练、推理等都需要消耗大量的计算资源以及运维成本&#xff0c;在数禾科技的金融业务场景下&#xf…

LaTex中参考文献引用

一、引用参考文献 这里我们使用的是BibTeX的引用格式&#xff0c;因此文件中应包括两个文件&#xff08;.bib-参考文献 和 .bst-文献格式&#xff09;。 有了这两个文件后&#xff0c;我们在bib文件中创建参考文献&#xff1a;&#xff08;注意&#xff0c;作者的名字是逗号前…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Image图片组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之Image图片组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Image组件 Image 用来加载并显示图片的基础组件&#xff0c;它支持从内存、本…

Ps:图框工具

图框工具 Frame Tool是自 Ps 2019 版开始新增的一个工具。 图框 Frame可用于限制图像的显示范围&#xff0c;在设计过程中&#xff0c;还常常可起到占位符的功能。 快捷键&#xff1a;K 使用图框工具&#xff0c;对于快速相册排版、创建某种形式的特效等有一定的帮助。比起使用…

变量的存储类型(storage class)

变量的存储类型(storage class) 对于变量的存储类型&#xff0c;前面遇到过一些疑惑&#xff0c;再简单的在这里说一下。存储类型是指存储变量值的内存类型&#xff0c;它用来决定存储空间的大小。变量的存储类型决定着变量的存储器和作用域。有三个地方可以用于存储变量&#…

java进阶(二)-java小干货

java一些精干知识点分享 2. java小干货2.1循环遍历2.2可变参数2.3 list和数组转化2.3.1 数组转list2.3.2 list转数组 2.4 值传递和地址传递2.4.1值传递2.4.2 地址传递2.4.3易错点总结 2.5 数组数组帮助类Arrays 2.5 基本数据类型和包装类2.5集合2.6文件流2.7java代码块、内部类…

MQ(消息队列)相关知识

1. 什么是mq 消息队列是一种“先进先出”的数据结构 2. 应用场景 其应用场景主要包含以下3个方面 应用解耦 系统的耦合性越高&#xff0c;容错性就越低。以电商应用为例&#xff0c;用户创建订单后&#xff0c;如果耦合调用库存系统、物流系统、支付系统&#xff0c;任何…