Gin 路由注册与请求参数获取

Gin 路由注册与请求参数获取

文章目录

  • Gin 路由注册与请求参数获取
    • 一、Web应用开发的两种模式
      • 1.前后端不分离模式
      • 2.前后端分离模式
    • 二、RESTful介绍
    • 三、API接口
      • 3.1 RESTful API设计指南
      • 3.2 API与用户的通信协议
      • 3.3 RestFul API接口设计规范
        • 3.3.1 api接口
        • 3.3.2 接口文档:
      • 3.4 restful规范(10条,规定了这么做,公司可以不采用)
    • 四、图书管理系统设计
    • 五、Gin 路由类型
        • 通配符路由
    • 六、路由参数
      • 6.1 获取URL后面的参数
      • 6.2 获取path参数
      • 6.3 取JSON参数
    • 七、路由组
      • 7.1 普通路由
      • 7.2 路由组
    • 八、重定向
      • 8.1 HTTP重定向
      • 8.2 路由重定向
    • 九、请求参数绑定
      • 9.1 获取查询参数
      • 9.2 获取表单数据
    • 十、小黄书起步:Web 接口之用户模块设计
      • 10.1 用户模块分析
      • 10.2 目录结构
      • 10.3 Handler 的用途
      • 10.4 用分组路由来简化注册
      • 10.5 接收请求数据:接收请求结构体
      • 10.6 接收请求数据:Bind 方法
      • 10.7 校验请求:正则表达式
      • 10.8 校验请求:预编译正则表达式
      • 10.9 校验请求:Go 正则表达式不支持部分语法
      • 10.10 校验请求:全部校验

一、Web应用开发的两种模式

1.前后端不分离模式

  • 也叫前后端混合开发模式, 需要后端写模板语言(dtl), 返回的是HTML页面
  • 浏览器 : 请求动态页面
  • 后端 : 返回HTML

img

  • 优点:可以直接渲染页面, 方便处理请求数据

  • 缺点:耦合度非常高, 不方便扩展

2.前后端分离模式

  • 前端 : 只写前端
  • 后端 : 只专注于写后端接口, 返回 json, xml格式数据
  • 流程 :

浏览器到静态文件服务器请求静态页面, 静态服务器返回静态页面

JS 请求达到后端, 后端再返回 JSON 或 XML格式的数据

img

  • 优点
  • 不需要管前端怎么实现, 后端开发者需要做的就是写接口
  • 只需要知道, 你前端传过来什么, 然后需要后端这边传回去什么就行了
  • 主要的就是操作逻辑, 解耦合性高
  • 缺点
  • 程序员不知道前端的具体流程, 然后对表的设计, 对业务或许就理解的没有那么透彻
  • 还存在前后端联调各种问题, 前端和后端的沟通等

二、RESTful介绍

RESTful(Representational State Transfer)代表的是一种基于HTTP协议设计的软件架构风格,它通常用于构建Web服务,是Representational State Transfer的简称,中文翻译为“表征状态转移”或“表现层状态转化”。RESTful架构的设计理念是将资源表示为URI(统一资源标识符),通过HTTP协议的GET、POST、PUT、DELETE等方法对资源进行操作。以下是RESTful架构的一些关键特点:

  1. 资源(Resource):在RESTful架构中,所有的数据或服务都被抽象为资源,每个资源都有一个唯一的标识符(URI)。
  2. 表现层(Representation):资源的表现层是指资源在不同的表示形式之间进行切换,通常使用JSON或XML格式。客户端和服务器之间通过资源的表现层进行通信。
  3. 状态转移(State Transfer):RESTful架构通过HTTP方法(GET、POST、PUT、DELETE等)实现状态的转移,对资源进行增删改查的操作。
  4. 无状态(Stateless):RESTful服务是无状态的,每个请求都包含足够的信息,使服务器能够理解和处理请求,而无需依赖之前的请求。

三、API接口

3.1 RESTful API设计指南

参考资料 阮一峰 理解RESTful架构

3.2 API与用户的通信协议

总是使用HTTPs协议。

3.3 RestFul API接口设计规范

3.3.1 api接口
  • 规定了前后台信息交互规则的url链接,也就是前后台信息交互的媒介
3.3.2 接口文档:
  • 可以手动写(公司有平台,录到平台里)
  • 自动生成(coreapi,swagger)

3.4 restful规范(10条,规定了这么做,公司可以不采用)

  1. 数据的安全保障,通常使用https进行传输

  2. 域名中会含有API标识

    https://api.example.com 尽量将API部署在专用域名

    https://127.0.0.0:8080/api/ API很简单

  3. 请求地址中带版本信息,或者在请求头中

    https://127.0.0.0:8080/api/v1/

  4. 任何东西都是资源,均使用名词表示 (尽量不要用动词)

    https://api.example.com/v1/books/

    https://api.example.com/v1/get_all_books(不符合规范)

  5. 请求方式区分不同操作

    • get获取:从服务器取出资源(一项或多项)

    • post新增数据:在服务器新建一个资源

    • put/patch:patch是局部更新,put是全部(基本上更新都用put)

    • delete:从服务器中删除

  6. 在请求路径中带过滤,通过在url上传参的形式传递搜索条件

    https://api.example.com/v1/?name=‘金’&order=asc

    https://api.example.com/v1/name?sortby=name&order=asc

    https://api.example.com/v1/zoos?limit=10:指定返回记录的数量

    https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置

    https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数

    https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序

    https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件

  7. 返回数据中带状态码

    • http请求的状态码

    • 返回的json格式中到状态码(标志当次请求成功或失败)

      200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
      201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
      202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
      204 NO CONTENT - [DELETE]:用户删除数据成功。
      400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
      401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
      403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
      404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
      406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
      410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
      422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
      500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。
      

      更多状态码参考:http://tools.jb51.net/table/http_status_code

  8. 返回数据中带错误信息

    • 错误处理,应返回错误信息,error当做key

      {error: "Invalid API key"
      }
      
  9. 对不同操作,返回数据符合如下规范(这只是规范)

    GET /books:返回资源对象的列表(数组)[{},{},{}]
    GET /books/1:返回单个资源对象    {}
    POST /books:返回新生成的资源对象  {新增的书}
    PUT /books/1:返回完整的资源对象   {返回修改后的}
    PATCH /books/1: 返回完整的资源对象  {返回修改后的}
    DELETE /books/1:  返回一个空文档           {status:100,msg:查询成功,data:null}
    
  10. 返回结果中带连接

    RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。

    {"link": {"rel":   "collection https://www.example.com/zoos","href":  "https://api.example.com/zoos","title": "List of zoos","type":  "application/vnd.yourformat+json"
    }}
    

四、图书管理系统设计

例如,我们现在要编写一个管理书籍的系统,我们可以查询对一本书进行查询、创建、更新和删除等操作,我们在编写程序的时候就要设计客户端浏览器与我们Web服务端交互的方式和路径。按照经验我们通常会设计成如下模式:

请求方法URL含义
GET/book查询书籍信息
POST/create_book创建书籍记录
POST/update_book更新书籍信息
POST/delete_book删除书籍信息

同样的需求我们按照RESTful API设计如下:

请求方法URL含义
GET/book查询书籍信息
POST/book创建书籍记录
PUT/book更新书籍信息
DELETE/book删除书籍信息

新建一个book.go文件,键入如下代码:

package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()r.GET("/book", func(c *gin.Context) {c.String(http.StatusOK, "查询书籍信息")})r.POST("/book", func(c *gin.Context) {c.String(http.StatusOK, "新增书籍信息")})r.PUT("/book", func(c *gin.Context) {c.String(http.StatusOK, "修改书籍信息")})r.DELETE("/book", func(c *gin.Context) {c.String(http.StatusOK, "删除书籍信息")})r.Run(":8080")
}

接下来我们可以使用Postman来作为客户端的来调用我们刚刚写好的接口。

五、Gin 路由类型

Gin 支持很多类型的路由:

  • 静态路由:完全匹配的路由,也就是前面 我们注册的 hello 的路由。
  • 参数路由:在路径中带上了参数的路由。
  • 通配符路由:任意匹配的路由。

通配符路由

通配符路由究竟匹配上了什么,也是通过 Param 方法获得的。

通配符路由不能注册这种 /users/*/users/*/a。也就是说,* 不能单独出现。

六、路由参数

6.1 获取URL后面的参数

  • URL参数可以通过DefaultQuery()Query()方法获取
  • DefaultQuery()若参数不存在则返回默认值,Query()若不存在,返回空串
  • 指的是URL中?后面携带的参数,例如:/user/search?username=贾维斯&address=北京
func main() {//Default返回一个默认的路由引擎r := gin.Default()r.GET("/user/search", func(c *gin.Context) {username := c.DefaultQuery("username", "贾维斯")//username := c.Query("username")address := c.Query("address")//输出json结果给调用方c.JSON(http.StatusOK, gin.H{"message":  "ok","username": username,"address":  address,})})r.Run()
}

6.2 获取path参数

请求的参数通过URL路径传递,例如:/user/search/贾维斯/北京。在Gin框架中,提供了c.Param方法可以获取路径中的参数。 获取请求URL路径中的参数的方式如下。

func main() {//Default返回一个默认的路由引擎r := gin.Default()r.GET("/user/search/:username/:address", func(c *gin.Context) {username := c.Param("username")address := c.Param("address")//输出json结果给调用方c.JSON(http.StatusOK, gin.H{"message":  "ok","username": username,"address":  address,})})r.Run(":8080")
}

6.3 取JSON参数

当前端请求的数据通过JSON提交时,例如向/json发送一个JSON格式的POST请求,则获取请求参数的方式如下:

package mainimport ("encoding/json""fmt""github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()r.POST("/json", func(c *gin.Context) {// 注意:下面为了举例子方便,暂时忽略了错误处理b, _ := c.GetRawData() // 从c.Request.Body读取请求数据fmt.Printf("raw data: %s\n", string(b))// 定义map或结构体var m map[string]interface{}// 反序列化_ = json.Unmarshal(b, &m)c.JSON(http.StatusOK, m)})r.Run(":8080")
}

七、路由组

在Gin框架中,路由组是一种用于组织和管理路由的机制。路由组可以帮助开发者更好地组织代码,提高可读性,并且能够对一组路由应用相同的中间件。以下是关于路由组的介绍:

7.1 普通路由

普通路由是指直接注册在Gin引擎上的路由,这些路由没有被分组,是独立存在的。下面是一个普通路由的简单例子:

package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {router := gin.Default()router.GET("/hello", func(c *gin.Context) {c.String(http.StatusOK, "Hello, Gin!")})router.GET("/world", func(c *gin.Context) {c.String(http.StatusOK, "World, Gin!")})router.Run(":8080")
}

上述例子中,/hello/world 是两个独立的普通路由。

7.2 路由组

路由组通过Group方法创建,可以将一组相关的路由放到同一个路由组中。通过路由组,可以更好地组织代码和应用中间件。以下是一个简单的路由组示例:

package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {router := gin.Default()// 创建一个路由组apiGroup := router.Group("/api")// 在路由组中注册路由apiGroup.GET("/users", func(c *gin.Context) {c.String(http.StatusOK, "Get Users")})apiGroup.POST("/users", func(c *gin.Context) {c.String(http.StatusOK, "Create User")})router.Run(":8080")
}

上述例子中,/api 是一个路由组,包含了两个路由 /users(GET和POST)。这样,相同业务功能的路由被组织在一起,提高了代码的可读性和可维护性。

八、重定向

8.1 HTTP重定向

HTTP 重定向很容易。 内部、外部重定向均支持。

r.GET("/test", func(c *gin.Context) {c.Redirect(http.StatusMovedPermanently, "http://www.sogo.com/")
})

8.2 路由重定向

路由重定向,使用HandleContext

r.GET("/test", func(c *gin.Context) {// 指定重定向的URLc.Request.URL.Path = "/test2"r.HandleContext(c)
})
r.GET("/test2", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"hello": "world"})
})

九、请求参数绑定

在Gin框架中,请求参数绑定是一种常见的操作,它允许你从HTTP请求中提取参数并将其绑定到Go语言结构体中。这样可以更方便地处理请求数据。以下是关于请求参数绑定的一些建议和示例:

9.1 获取查询参数

你可以使用c.Queryc.DefaultQuery方法来获取URL中的查询参数。

package mainimport ("github.com/gin-gonic/gin""net/http"
)type QueryParams struct {Name  string `form:"name"`Age   int    `form:"age"`
}func main() {router := gin.Default()router.GET("/user", func(c *gin.Context) {var queryParams QueryParams// 使用 c.ShouldBindQuery 绑定查询参数到结构体if err := c.ShouldBindQuery(&queryParams); err == nil {c.JSON(http.StatusOK, gin.H{"name": queryParams.Name,"age":  queryParams.Age,})} else {c.String(http.StatusBadRequest, "参数绑定失败")}})router.Run(":8080")
}

上述例子中,通过c.ShouldBindQuery将查询参数绑定到QueryParams结构体中,然后使用这个结构体处理请求。

9.2 获取表单数据

使用c.ShouldBindc.ShouldBindJSON方法可以将POST请求的表单数据或JSON数据绑定到结构体中。

package mainimport ("github.com/gin-gonic/gin""net/http"
)type FormData struct {Name string `form:"name"`Age  int    `form:"age"`
}func main() {router := gin.Default()router.POST("/user", func(c *gin.Context) {var formData FormData// 使用 c.ShouldBind 绑定表单数据到结构体if err := c.ShouldBind(&formData); err == nil {c.JSON(http.StatusOK, gin.H{"name": formData.Name,"age":  formData.Age,})} else {c.String(http.StatusBadRequest, "参数绑定失败")}})router.Run(":8080")
}

在上述例子中,c.ShouldBind将表单数据绑定到FormData结构体中。

十、小黄书起步:Web 接口之用户模块设计

10.1 用户模块分析

我们现在要设计一个用户模块,对于一个用户模块来说,最先要设计的接口就是:注册和登录。而后要考虑提供:编辑和查看用户信息。同样的需求我们按照RESTful API设计如下:

请求方法URL含义
GET/users/profile查询用户信息
POST/users/signup用户登录
POST/users/login用户注册
POST/users/edit编辑用户信息

首先,我们创建一个webook目录,并且初始化go mod

mkdir webook
go mod init webook

10.2 目录结构

项目目录结构如图:

在 webook 顶级目录下有:

  • main 文件,用于启动 webook。
  • 一个 internal 包,里面放着的就是我们所有的业务 代码。
  • 一个 pkg 包,这是我们用于存放公共库和包。

10.3 Handler 的用途

接着我们在user.go 中直接定义了一个 UserHandler,然后将所有 和用户有关的路由都定义在了这个 Handler 上,同时,也定义了一个 RegisterRoutes 的方法,用来注册路由。这里用定义在 UserHandler 上的方法来作为对应路由的处理逻辑。

10.4 用分组路由来简化注册

你可以注意到,就是我们所有的路由都有 /users 这个前缀,要是手一抖就有可能写错,这时候可以考虑使用 Gin 的分组路由功能,修改后如下:

image-20240104195442246

10.5 接收请求数据:接收请求结构体

一般来说,我们都是定义一个结构体来接受数据。这里我们使用了方法内部类 SignUpRequest 来接收数据。

10.6 接收请求数据:Bind 方法

Bind 方法是 Gin 里面最常用的用于接收请求的方法。

Bind 方法会根据 HTTP 请求的 Content-Type 来决定怎么处理。

比如我们的请求是 JSON 格式,Content-Typeapplication/json,那么 Gin 就会使用 JSON 来反序列化。

如果 Bind 方法发现输入有问题,它就会直接返回一个错误响应到前端。

10.7 校验请求:正则表达式

在我们这个注册的业务里面,校验分为如下:

  • 邮箱需要符合一定的格式:也就是账号这里,必须是一个合法的邮箱。
  • 密码和确认密码需要相等:这是为了确保用户没有输错。
  • 密码需要符合一定的规律:要求用户输入的密码必须不少于八位,必须要包含数字、特殊字符。

综上所述,我们用正则表达式来校验请求,正则表达式是一种用于匹配和操作文本的强大工 具,它是由一系列字符和特殊字符组成的模式,用 于描述要匹配的文本模式。正则表达式可以在文本中查找、替换、提取和验证 特定的模式。代码如图:

10.8 校验请求:预编译正则表达式

我们可以预编译正则表达式来提高校验速度。

10.9 校验请求:Go 正则表达式不支持部分语法

前面我们用的是官方自带的,但是 Go 自带的正 则表达式不支持一些语法,比如说我这里想要用 的表达式:^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$

类似于 ?=. 这种就不支持。所以我们换用另外一个开源的正则表达式匹配 库:github.com/dlclark/regexp2

10.10 校验请求:全部校验

整体的校验如图,注意我们区分了不同的错误,返回了不同的错误提示。

最后,完整代码如下:

user.go 文件

package webimport ("fmt"regexp "github.com/dlclark/regexp2""github.com/gin-gonic/gin""net/http"
)type UserHandler struct {emailExp    *regexp.RegexppasswordExp *regexp.Regexp
}func NewUserHandler() *UserHandler {const (emailRegexPattern    = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$"passwordRegexPattern = `^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$`)emailExp := regexp.MustCompile(emailRegexPattern, regexp.None)passwordExp := regexp.MustCompile(passwordRegexPattern, regexp.None)return &UserHandler{emailExp:    emailExp,passwordExp: passwordExp,}
}func (u *UserHandler) RegisterRoutes(server *gin.Engine) {ug := server.Group("/user")   //ug is user groupug.GET("/profile", u.Profile) // 查询用户信息接口ug.POST("/signup", u.SignUp)  // 注册接口ug.POST("/login", u.Login)    // 登录接口ug.POST("/logout", u.Logout)  // 登出接口ug.POST("/edit", u.Edit)      // 修改用户信息接口}func (u *UserHandler) RegisterRoutesV1(ug *gin.RouterGroup) {ug.GET("/profile", u.Profile) // 查询用户信息接口ug.POST("/signup", u.SignUp)  // 注册接口ug.POST("/login", u.Login)    // 登录接口ug.POST("/logout", u.Logout)  // 登出接口ug.POST("/edit", u.Edit)      // 修改用户信息接口}
func (u *UserHandler) Profile(ctx *gin.Context) {
}
func (u *UserHandler) SignUp(ctx *gin.Context) {type SignUpRequest struct {Email           string `json:"email"`Password        string `json:"password"`ConfirmPassword string `json:"confirmPassword"`}var request SignUpRequest// 如果 Bind 方法发现输入有问题,它就会直接返回一 个错误响应到前端。if err := ctx.Bind(&request); err != nil {return}ok, err := u.emailExp.MatchString(request.Email)if err != nil {ctx.String(http.StatusOK, "系统错误")return}if !ok {ctx.String(http.StatusOK, "邮箱格式错误")return}ok, err = u.passwordExp.MatchString(request.Password)if err != nil {ctx.String(http.StatusOK, "系统错误")return}if !ok {ctx.String(http.StatusOK, "密码必须包含至少一个数字、一个字母、一个特殊字符,并且长度至少为8位")return}if request.Password != request.ConfirmPassword {ctx.String(http.StatusOK, "两次密码不一致")return}ctx.String(http.StatusOK, "注册成功")fmt.Printf("请求体为:%v", request)
}
func (u *UserHandler) Login(ctx *gin.Context) {}func (u *UserHandler) Logout(ctx *gin.Context) {}
func (u *UserHandler) Edit(ctx *gin.Context) {}

main.go 文件:

package mainimport ("github.com/gin-gonic/gin""strings""time""webook/internal/web"
)func main() {server := gin.Default()u := web.NewUserHandler()u.RegisterRoutes(server)//ug := server.Group("/user/v1") //ug is user group//c.RegisterRoutesV1(ug)server.Run(":8080")
}

最后,我们通过postman 请求接口:http://127.0.0.1:8080/user/signup/

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

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

相关文章

viewer插件——预览图片时一直闪烁——问题修复,亲测有效

viewer插件——预览图片时一直闪烁——问题修复,亲测有效 viewer插件的介绍遇到的问题——图片会一直重复加载,造成图片在闪烁的效果解决方法 viewer插件的介绍 之前写过一篇文章,是关于v-viewer图片预览插件——vue2插件集合(elementUi中的…

JAVA 终极面试题

目录标题 一: JAVA 基础1.JDK和JRE有什么区别?2. 面向对象的特征(了解)3. 和equals的区别是什么?4.两个对象的hashCode()相同,则equals()一定为true,对吗?5.final关键字在java中的作用6.java中的Math.round…

bat批处理文件_命令汇总(1)

文章目录 1、复制文件:2、 移动文件:3、删除文件:4、创建目录:5、删除目录:6、切换目录:7、显示当前目录:8、运行程序:9、显示系统环境变量:10、设置环境变量&#xff1a…

HCIA-Datacom题库(自己整理分类的)——OSPF协议判断

1.路由表中某条路由信息的Proto为OSPF则此路由的优先级一定为10。√ 2.如果网络管理员没有配置骨干区域,则路由器会自动创建骨干区域? 路由表中某条路由信息的Proto为OSPF,则此路由的优先级一定为10。 当两台OSPF路由器形成2-WAY邻居关系时&#xff0…

Android 相机库CameraView源码解析 (四) : 带滤镜预览

1. 前言 这段时间,在使用 natario1/CameraView 来实现带滤镜的预览、拍照、录像功能。 由于CameraView封装的比较到位,在项目前期,的确为我们节省了不少时间。 但随着项目持续深入,对于CameraView的使用进入深水区,逐…

【OpenBMC】的内部README 模板

OpenBMC 本项目的AST2500分支核心代码的机型是ast2500-default,克隆代码后进入编译环境的命令为: source setup ast2500-default 一、源码下载、配置以及编译 重要:请参阅confluence 详细步骤 二、代码使用方法 目前所有自定义修改的代码…

Node.js 文件写入详解:最佳实践与示例

文件写入是 Node.js 中的一项重要任务,它允许你将数据保存到本地文件系统中,供后续使用。这个功能在许多应用中都有广泛的应用,包括数据备份、日志记录、配置文件更新等。在本文,我们将介绍如何在 Node.js 中执行文件写入操作&…

【C#】知识点实践序列之UrlEncode在线URL网址编码、解码

欢迎来到《小5讲堂》,大家好,我是全栈小5。 这是2024年第8篇文章,此篇文章是C#知识点实践序列文章, 博主能力有限,理解水平有限,若有不对之处望指正! 地址编码大家应该比较经常遇到和使用到&…

CAN数据记录仪在新能源车上的应用

随着新能源汽车的快速发展,对车辆安全和性能的要求也越来越高。在新能源车中,液位传感器是必不可少的零部件之一,用于监测电池液位、冷却液位等关键参数。在测试阶段需要工作人员花费大量时间跟车去获取它的CAN数据,从而分析是否有…

在 Linux 中开启 Flask 项目持续运行

在 Linux 中开启 Flask 项目持续运行 在部署 Flask 项目时,情况往往并不是那么理想。默认情况下,关闭 SSH 终端后,Flask 服务就停止了。这时,您需要找到一种方法在 Linux 服务器上实现持续运行 Flask 项目,并在服务器…

Dependency Dialogue Acts — Annotation Scheme and Case Study [论文解读]

原文链接:https://arxiv.org/pdf/2302.12944.pdf 摘要 在本文中,我们介绍了依存对话行为(Dependency Dialog Act, DDA),这是一个新颖的框架,旨在捕捉多方对话中说话者意图的结构。DDA结合并适应了现有对话标注框架的特点&#x…

springboot实现OCR

1、引入依赖 <dependency><groupId>net.sourceforge.tess4j</groupId><artifactId>tess4j</artifactId><version>4.5.4</version> </dependency> 2、config Configuration public class TessOcrConfiguration {Beanpublic …

旋转图像(LeetCode 48)

文章目录 1.问题描述2.难度等级3.热门指数4.解题思路参考文献 1.问题描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在「原地」旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。 示…

SpringBoot连接MySQL并整合MyBatis-Plus

SpringBoot连接MySQL并整合MyBatis-Plus 配置springboot版本目录结构pom.xml文件application.yml数据库表代码Test.javaTestMapper.javaTestMapper.xmlTestService.javaTestServiceImpl.javaTestController.java效果配置 springboot版本 <parent><groupId>org.sp…

git提交操作(不包含初始化仓库)

1.进入到本地的git仓库 查看状态 git status 如果你之前有没有成功的提交&#xff0c;直接看第5步。 2.追踪文件 git add . 不要提交大于100M的文件&#xff0c;如果有&#xff0c;看第5步 3.提交评论 git commit -m "你想添加的评论" 4.push (push之前可以再…

2024.1.4每日一题

LeetCode每日一题 2397.被列覆盖的最多行数 2397. 被列覆盖的最多行数 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你一个下标从 0 开始、大小为 m x n 的二进制矩阵 matrix &#xff1b;另给你一个整数 numSelect&#xff0c;表示你必须从 matrix 中选择的 不同 …

回首2023年,外贸行业发生了哪些大事,2024年应该如何做

莎士比亚说过&#xff1a;凡是过往,皆为序章,凡是未来,皆有可期。 2023年发生过太多的事情了&#xff0c;今天就来给大家回顾一下2023年外贸行业发生的一些事情&#xff0c;下面我会用一些关键词来概况。当然如同莎士比亚说的那样&#xff0c;回首过去是为了更好的选择未来。 …

YOLO算法入门指南:了解门槛、学习路径及其易学性

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…

【ModelScope】部署一个属于自己的AI服务

前言 技术栈是Fastapi。 FastAPI 是一个现代、快速&#xff08;基于 Starlette 和 Pydantic&#xff09;、易于使用的 Python web 框架&#xff0c;主要用于构建 RESTful API。以下是 FastAPI 的一些优势&#xff1a; 性能卓越&#xff1a; FastAPI 基于 Starlette 框架&…

Java程序设计——GUI设计

一、目的 通过用户图形界面设计&#xff0c;掌握JavaSwing开发的基本方法。 二、实验内容与设计思想 实验内容&#xff1a; 课本验证实验&#xff1a; Example10_6 图 1 Example10_7 图 2 图 3 Example10_15 图 4 设计思想&#xff1a; ①学生信息管理系统&#xff1a…