当前位置: 首页 > 编程日记 > 正文

go的HTTP网络编程

欢迎大家到我的博客浏览。go的HTTP网络编程 | YinKai's Blog

go的HTTP网络编程

1、http编程--server示例

package main
​
import (
    "fmt"
    "net/http"
)
​
func main() {
    // 注册处理函数,定义 URL 路由和对应的处理函数
    http.HandleFunc("/", Hello)         // 根路径 "/" 的请求交给 Hello 函数处理
    http.HandleFunc("/login", Login)   // "/login" 路径的请求交给 Login 函数处理
​
    // 启动 HTTP 服务器,监听指定的地址和端口
    err := http.ListenAndServe("0.0.0.0:8080", nil)   // 启动服务器,监听地址 "0.0.0.0:8080",使用默认的路由器和处理器
    if err != nil {
        fmt.Println("HTTP 服务器启动失败", err)
    }
}
​
func Hello(w http.ResponseWriter, r *http.Request) {
    // 处理根路径 "/" 的请求
    fmt.Fprintf(w, "Hello, World!")   // 将 "Hello, World!" 写入 http.ResponseWriter,作为 HTTP 响应的内容
}
​
func Login(w http.ResponseWriter, r *http.Request) {
    // 处理 "/login" 路径的请求
    fmt.Fprintf(w, "Login page")   // 将 "Login page" 写入 http.ResponseWriter,作为 HTTP 响应的内容
}
​

示例说明:

  • http.HandleFunc("/", Hello):注册处理函数 Hello,将根路径 "/" 的请求交给 Hello 函数处理。

  • http.HandleFunc("/login", Login):注册处理函数 Login,将 "/login" 路径的请求交给 Login 函数处理。

  • http.ListenAndServe("0.0.0.0:8080", nil):启动一个 HTTP 服务器,监听地址为 "0.0.0.0:8080",传入 nil 作为处理器,表示使用默认的路由器和处理器。

  • Hello 函数和 Login 函数分别是处理根路径和 "/login" 路径请求的处理函数,它们接收一个 http.ResponseWriter 和一个 http.Request 参数,分别用于写入响应和读取请求信息。

  • fmt.Fprintf(w, ...):使用 Fprintf 函数将字符串写入到 http.ResponseWriter 中,作为 HTTP 响应的内容。

2、http编程--Client示例

package main
​
import (
    "fmt"
    "io/ioutil"
    "net/http"
)
​
func main() {
    // 创建一个 HTTP 客户端
    client := http.Client{}
​
    // 构建 GET 请求
    req, err := http.NewRequest("GET", "https://www.example.com", nil)
    if err != nil {
        fmt.Println("创建请求失败", err)
        return
    }
​
    // 发送请求
    res, err := client.Do(req)
    if err != nil {
        fmt.Println("请求失败", err)
        return
    }
    defer res.Body.Close() // 在函数结束时关闭响应的 Body
​
    // 读取响应的内容
    data, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Println("读取响应失败", err)
        return
    }
​
    // 输出响应的内容
    fmt.Println(string(data))
}

示例说明:

  • http.Client{}:创建一个 HTTP 客户端,用于发送 HTTP 请求。

  • http.NewRequest("GET", "https://www.example.com", nil):构建一个 GET 请求,并指定请求的 URL、请求方法和请求体。

  • client.Do(req):发送请求并获取响应,返回一个 http.Response 对象。

  • defer res.Body.Close():在函数结束时关闭响应的 Body,确保资源被正确释放。

  • ioutil.ReadAll(res.Body):从响应的 Body 中读取内容,返回一个字节数组。

  • fmt.Println(string(data)):将读取到的响应内容转换为字符串并输出。

3、常见HTTP请求方法

  1. GET:从服务器获取资源。客户端向服务器请求获取指定 URL 对应的资源,并从服务器返回该资源的内容。GET 请求通常用于获取数据,而不对服务器上的资源进行修改。

  2. POST:向服务器提交数据。客户端向服务器提交数据,请求服务器对该数据进行处理。POST 请求通常用于向服务器提交数据,如表单数据、上传文件等。

  3. PUT:更新服务器上的资源。客户端向服务器传送数据,请求服务器更新指定 URL 对应的资源。PUT 请求通常用于更新资源。

  4. DELETE:删除服务器上的资源。客户端向服务器请求删除指定 URL 对应的资源。DELETE 请求通常用于删除资源。

  5. HEAD:类似于 GET 请求,但只返回响应头部,不返回响应体。用于获取资源的元信息,如文件大小、文件类型等,而不获取实际的资源内容。

  6. OPTIONS:请求服务器返回对指定 URL 支持的通信选项。服务器将返回支持的 HTTP 请求方法、头部字段等信息,用于客户端了解服务器的功能和约束。

  7. PATCH:对服务器上的资源进行部分更新。客户端向服务器传送数据,请求服务器对指定 URL 对应的资源进行部分更新。

  8. CONNECT:建立网络隧道。通常用于代理服务器,用于在客户端和目标服务器之间建立隧道,用于安全的加密通信。

  9. TRACE:用于调试,请求服务器返回对请求和响应的诊断信息。不常用于实际生产环境。

4、下面是一个简单的 Go 语言程序,演示了如何使用 HTTP 请求方法进行基本的 HTTP 请求:

package main
​
import (
    "fmt"
    "net/http"
    "io/ioutil"
)
​
func main() {
    // GET 请求示例
    resp, err := http.Get("https://jsonplaceholder.typicode.com/posts/1") // 发起 GET 请求
    if err != nil {
        fmt.Println("GET 请求错误:", err)
        return
    }
    defer resp.Body.Close() // 确保在函数退出前关闭响应体
​
    data, err := ioutil.ReadAll(resp.Body) // 读取响应体数据
    if err != nil {
        fmt.Println("读取响应数据错误:", err)
        return
    }
​
    fmt.Println("GET 请求响应数据:", string(data)) // 打印响应数据
​
    // POST 请求示例
    resp, err = http.Post("https://jsonplaceholder.typicode.com/posts", "application/json", nil) // 发起 POST 请求
    if err != nil {
        fmt.Println("POST 请求错误:", err)
        return
    }
    defer resp.Body.Close()
​
    data, err = ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("读取响应数据错误:", err)
        return
    }
​
    fmt.Println("POST 请求响应数据:", string(data))
​
    // PUT 请求示例
    req, err := http.NewRequest("PUT", "https://jsonplaceholder.typicode.com/posts/1", nil) // 创建 PUT 请求
    if err != nil {
        fmt.Println("创建 PUT 请求错误:", err)
        return
    }
​
    client := &http.Client{}
    resp, err = client.Do(req) // 发起 PUT 请求
    if err != nil {
        fmt.Println("PUT 请求错误:", err)
        return
    }
    defer resp.Body.Close()
​
    data, err = ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("读取响应数据错误:", err)
        return
    }
​
    fmt.Println("PUT 请求响应数据:", string(data))
​
    // DELETE 请求示例
    req, err = http.NewRequest("DELETE", "https://jsonplaceholder.typicode.com/posts/1", nil) // 创建 DELETE 请求
    if err != nil {
        fmt.Println("创建 DELETE 请求错误:", err)
        return
    }
​
    resp, err = client.Do(req) // 发起 DELETE 请求
    if err != nil {
        fmt.Println("DELETE 请求错误:", err)
        return
    }
    defer resp.Body.Close()
​
    data, err = ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("读取响应数据错误:", err)
        return
    }
​
    fmt.Println("DELETE 请求响应数据:", string(data))
}

相关文章:

【Mongdb之数据同步篇】什么是Oplog、Mongodb 开启oplog,java监听oplog并写入关系型数据库、Mongodb动态切换数据源

oplog是local库下的一个固定集合,Secondary就是通过查看Primary 的oplog这个集合来进行复制的。每个节点都有oplog,记录这从主节点复制过来的信息,这样每个成员都可以作为同步源给其他节点。Oplog 可以说是Mongodb Replication的纽带了。

Rust XTask 模式介绍与应用

XTask(扩展任务)是一种在Rust项目中定义和执行自定义构建任务的方式。它通过创建一个独立的Rust库或二进制项目来封装这些任务,利用Rust语言的强类型、安全性和跨平台能力,使得构建流程更加健壮、可读和可维护。

SpringBoot系列教程之Bean之指定初始化顺序的若干姿势

之前介绍了@Order注解的常见错误理解,它并不能指定 bean 的加载顺序,那么问题来了,如果我需要指定 bean 的加载顺序,那应该怎么办呢?本文将介绍几种可行的方式来控制 bean 之间的加载顺序。

SpringBoot接口防抖(防重复提交)的一些实现方案

作为一名老码农,在开发后端Java业务系统,包括各种管理后台和小程序等。在这些项目中,我设计过单/多租户体系系统,对接过许多开放平台,也搞过消息中心这类较为复杂的应用,但幸运的是,我至今还没有遇到过线上系统由于代码崩溃导致资损的情况。这其中的原因有三点:一是业务系统本身并不复杂;二是我一直遵循某大厂代码规约,在开发过程中尽可能按规约编写代码;三是经过多年的开发经验积累,我成为了一名熟练工,掌握了一些实用的技巧。啥是防抖所谓防抖,一是防用户手抖,二是防网络抖动。

SpringBoot请求转发与重定向

但是可能由于B网址相对于A网址过于复杂,这样搜索引擎就会觉得网址A对用户更加友好,因而在重定向之后任然显示旧的网址A,但是显示网址B的内容。在平常使用手机的过程当中,有时候会发现网页上会有浮动的窗口,或者访问的页面不是正常的页面,这就可能是运营商通过某种方式篡改了用户正常访问的页面。重定向,是指在Nginx中,重定向是指通过修改URL地址,将客户端的请求重定向到另一个URL地址的过程,Nginx中实现重定向的方式有多种,比如使用rewrite模块、return指令等。使用场景:在返回视图的前面加上。

SpringBoot 中实现订单30分钟自动取消的策略

在电商和其他涉及到在线支付的应用中,通常需要实现一个功能:如果用户在生成订单后的一定时间内未完成支付,系统将自动取消该订单。本文将详细介绍基于Spring Boot框架实现订单30分钟内未支付自动取消的几种方案,并提供实例代码。

SpringBoot 优雅实现超大文件上传,通用方案

通俗的说,你把要上传的东西上传,服务器会先做MD5校验,如果服务器上有一样的东西,它就直接给你个新地址,其实你下载的都是服务器上的同一个文件,想要不秒传,其实只要让MD5改变,就是对文件本身做一下修改(改名字不行),例如一个文本文件,你多加几个字,MD5就变了,就不会秒传了。分片上传,就是将所要上传的文件,按照一定的大小,将整个文件分隔成多个数据块(我们称之为Part)来进行分别上传,上传完之后再由服务端对所有上传的文件进行汇总整合成原始的文件。

Springboot + oauth2 单点登录 - 原理篇

OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准,允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容,OAuth2.0是OAuth协议的延续版本,但不向后兼容OAuth 1.0即完全废止了OAuth1.0。授权码模式(authorization code)密码模式(resource owner password credentials)客户端模式(client credentials) 不常用。

Spring AOP 技术实现原理

Spring AOP的实现基于代理模式,通过代理对象来包装目标对象,实现切面逻辑的注入。通过本文,我们深入了解了Spring AOP是如何基于JDK动态代理和CGLIB代理技术实现的。通过详细的示例演示,希望读者能更清晰地理解Spring AOP的底层原理,并在实际项目中灵活应用这一强大的技术。

Golang 搭建 WebSocket 应用(八) - 完整代码

本文应该是本系列文章最后一篇了,前面留下的一些坑可能后面会再补充一下,但不在本系列文章中了。

深入浅出:Golang内存逃逸机制与性能优化技巧

内存逃逸发生在编译期间,当编译器判断一个变量的生命周期超出了其当前作用域,它会将该变量分配到堆上,而非栈上。这种情况虽然保证了程序的正确性,但会增加垃圾回收的负担,从而影响程序性能。通过本文的深入探讨,我们了解了Golang内存逃逸的基本原理,以及它是如何影响程序性能的。我们探讨了内存逃逸的常见场景,并通过具体的代码示例展示了这些问题的出现和解决方法。最重要的是,我们学习了一系列性能优化技巧,包括数据结构优化、减少不必要的指针使用、利用栈空间、使用内存池,以及定期进行性能分析。

Java基本数据类型/包装类/对象/数组默认值

不管程序有没有显示的初始化,Java 虚拟机都会先自动给它初始化为默认值。1、整数类型(byte、short、int、long)的基本类型变量的默认值为0。2、单精度浮点型(float)的基本类型变量的默认值为0.0f。3、双精度浮点型(double)的基本类型变量的默认值为0.0d。4、字符型(char)的基本类型变量的默认为 “/u0000”。5、布尔性的基本类型变量的默认值为 false。6、引用类型的变量是默认值为 null。7、数组引用类型的变量的默认值为 null。

编码技巧:如何在Golang中高效解析和生成XML

在本文中,我们详细探讨了在Golang中高效处理XML的各个方面。从基础的XML概念到解析和生成XML文件的具体步骤,再到错误处理、调试技巧以及一些高级技巧和最佳实践,我们提供了一个全面的指南,旨在帮助读者掌握在Golang中处理XML的技能。理解Golang中XML处理的基本概念和方法。使用包来解析和生成XML文件。有效地处理常见的XML解析和生成中的错误。应用最佳实践和高级技巧来优化XML处理的性能和安全性。

如何用pthon连接mysql和mongodb数据库【极简版】

发现宝藏 前言 1. 连接mysql 1.1 安装 PyMySQL 1.2 导入 PyMySQL 1.3 建立连接 1.4 创建游标对象 1.5 执行查询 1.6 关闭连接 1.7 完整示例 2. 连接mongodb 2.1 安装 PyMongo 2.2 导入 PyMongo 2.3 建立连接 2.4

SpringBoot 使用过滤器、拦截器、切面(AOP),及其之间的区别和执行顺序

Servlet(Server Applet),全称是Java Servlet,是提供基于协议请求/响应服务的Java类。在JavaEE中是Servlet规范,即是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的Java类,一般人们理解是后者。是什么。

【总结】SpringBoot 中过滤器、拦截器、监听器的基本使用

拦截器是在面向切面编程中应用的,就是在你的service或者一个方法前调用一个方法,或者在方法后调用一个方法。是基于JAVA的反射机制。1)预处理preHandle()方法用户发送请求时,先执行preHandle()方法。会先按照顺序执行所有拦截器的preHandle方法,一直遇到return false为止,比如第二个preHandle方法是return false,则第三个以及以后所有拦截器都不会执行。若都是return true,则执行用户请求的url方法。2)后处理postHandle()方法。

Springboot支付宝沙箱支付---完整详细步骤

两种方式进行配置。这里我采取的是默认方式: 开发者如需使用系统默认密钥/证书,可在开发信息中选择系统默认密钥。注意:使用API在线调试工具调试OpenAPI必须使用系统默认密钥。

SpringBoot--过滤器/拦截器/AOP--区别/使用/顺序

​ 本文介绍SpringMVC(SpringBoot)中的过滤器、拦截器、AOP的区别及其用法。​ 如果监听器、过滤器、 拦截器、 AOP都存在,则它们的执行顺序为:监听器 => 过滤器=> 拦截器=> AOP。

Linux安装MongoDB教程

将解压后的 mongodb-linux-x86_64-rhel70-4.2.23 中的所有文件全部移动到 /usr/local/mongodb 中 :注意/*是所有子文件。也可以不用设置环境变量进行启动,但是不设置环境变量启动的话要每次启动写很多启动参数,比较麻烦,所以做好配置环境变量。在 mongodb 下创建 data 和 logs 目录,以及日志文件mongodb.log。在 /usr/local 目录中创建 mongodb 文件夹。启动 MongoDB(-conf 使用配置文件方式启动)

websocket介绍并模拟股票数据推流

Websockt是一种网络通信协议,允许客户端和服务器双向通信。最大的特点就是允许服务器主动推送数据给客户端,比如股票数据在客户端实时更新,就能利用websocket。

最简单的设计模式是单例?

单例模式可以说是Java中最简单的设计模式,但同时也是技术面试中频率极高的面试题。因为它不仅涉及到设计模式,还包括了关于线程安全、内存模型、类加载等机制。所以说它是最简单的吗?

TCP中的三次握手和四次挥手

我们知道TCP是运输层的面向连接的可靠的传输协议。**面向连接的**,指的就是在两个进程发送数据之前,必须先相互“握手”,确保两进程可以进行连接。并且这个传输是点对点的,即一个TCP连接中只有一个发送方和接收方;**可靠的**,指的是在任何网络情况下,在TCP传输中数据都将完整的发送到接收方。

基于SpringBoot的校园二手闲置交易平台

基于SpringBoot的校园二手闲置交易平台的设计与实现~

SpringBoot 中获取 Request 的四种方法

Controller中获取request对象后,如果要在其他方法中(如service方法、工具类方法等)使用request对象,需要在调用这些方法时将request对象作为参数传入。如果其他方法(如工具类中static方法)需要使用request对象,则需要在调用这些方法时将request参数传递进去。下面介绍的方法4,则可以直接在诸如工具类中的static方法中使用request对象(当然在各种Bean中也可以使用)。该方法实现的原理是,在Controller方法开始处理请求时,对象是方法参数,相当于。

thinkphp操作mongo数据的三种方法

'hostname' => '10.10.10.10', // MongoDB服务器地址。'hostport' => 2017, // MongoDB服务器端口。'database' => 'chatname', // 数据库名称。后面接着就可以任意使用Connection各类方法。后面接着就可以任意使用Collection各类方法。使用MongoDB PHP驱动程序,方法三。后面接着就可以任意使用db下的增删改查。使用tp中的db类,方法二。使用tp中的扩展,方法一。

java中代理的实现并在spring的应用

Java代理机制是一种在运行时创建一个代理对象来代替原始对象的方法。代理对象通常用于在调用原始对象的方法之前或之后执行一些额外的操作,例如日志记录、性能监控等。

gin实现登录逻辑,包含cookie,session

1. 客户端发起`http://localhost/`请求。2. 请求须经过后端AuthRequired中间件鉴权。该中间件查看session中是否保存了请求携带的cookie对应的用户信息,若有。则登录成功;若没有,则重定向到`http://localhost/login`进行登录。3. GET方法请求`http://localhost/login`时只返回页面,不需鉴权逻辑。4. POST方法请求`http://localhost/login`时,不需鉴权逻辑。进行登录验证,并记录session

java并发编程九 ABA 问题及解决,原子数组和字段更新

它指的是一个共享变量的值在操作期间从A变为B,然后再从B变回A,而CAS操作可能会错误地认为没有其他线程修改过这个值。AtomicStampedReference 可以给原子引用加上版本号,追踪原子引用整个的变化过程,如: A -> B -> A ->C,通过AtomicStampedReference,我们可以知道,引用变量中途被更改了几次。只要有其它线程【动过了】共享变量,那么自己的 cas 就算失败,这时,仅比较值是不够的,需要再加一个版本号 AtomicStampedReference。

java并发编程八 CAS 与 volatile和原子整数与原子引用

它可以用来修饰成员变量和静态成员变量,他可以避免线程从自己的工作缓存中查找变量的值,必须到主存中获取它的值,线程操作 volatile 变量都是直接操作主存。在java并发编程七六中,可以看到的 AtomicInteger 的解决方法,内部并没有用锁来保护共享变量的线程安全。那么它是如何实现的呢?其中的关键是 compareAndSet,它的简称就是 CAS (也有 Compare And Swap 的说法),它必须是原子操作。获取共享变量时,为了保证该变量的可见性,需要使用 volatile 修饰。

Springboot应用中过滤器chain.doFilter后设置header无效&filterChain.doFilter后使用response对象引起的问题&Filter过滤器执行流程

本文是在使用过滤器添加动态header过程中遇到设置header无效,经过研究源码而产生。因为特殊需求,自定义的header必须在经过Controller处理之后,才能确定,所以不能在请求处理之前设置,必须在请求处理之后。于是出现了这个坑。