Go学习第十四章——Gin请求与响应

Go web框架——Gin请求与响应

    • 1 响应
      • 1.1 String
      • 1.2 JSON(*)
      • 1.3 HTML(*)
      • 1.4 XML
      • 1.5 文件(*)
    • 2 请求
      • 2.1 请求参数
        • 查询参数 (Query)
        • 动态参数 (Param)
        • 表单参数 (PostForm)
        • 原始参数 (GetRawData)
      • 2.2 请求头
      • 2.3 响应头

1 响应

在Gin中,我们可以使用不同的方法设置请求的响应值,包括String、JSON、HTML和XML等。

1.1 String

使用String方法返回字符串类型的响应内容。

func main() {
    r := gin.Default()

    r.GET("/users", func(c *gin.Context) {
        c.String(http.StatusOK, "Users")
    })

    r.Run(":8080")
}

当我们访问http://localhost:8080/users时,就能够在浏览器上看到输出了"Users"。

补充:这里的http.StatusOK,是可以修改的,可以直接写200,因为200对应就是响应成功。

1.2 JSON(*)

使用JSON方法返回JSON类型的响应内容。

这里把结构体混进来,一般都会去拿结构体的JSON内容

这段代码:c.JSON(http.StatusOK, stu)的JSON方法是自动转换的

func (c *Context) JSON(code int, obj any) {
    c.Render(code, render.JSON{Data: obj})
}

可以看到可以传任意对象,然后都会通过反射转换为JSON数据格式

type student struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

func _json(c *gin.Context) {
	stu := student{"张三", 18}
	c.JSON(http.StatusOK, stu)
}

func main() {
	r := gin.Default()
	r.GET("/users", _json)

	r.Run(":8000")
}

当我们访问http://localhost:8080/users时,就能够在浏览器上看到JSON格式的输出内容。

进阶使用方式:

我们传JSON的时候,可以对结构体不想渲染的字段进行隐藏,例如:密码

只需要再结构体的标签里,修改成这样即可:Password string json:"-"

type user struct {
    Username string `json:"username,omitempty"`
    Password string `json:"-"`// 忽略转换为json
}

func _json(c *gin.Context) {
    userInfo := user{"张三", "123456"}
    c.JSON(http.StatusOK, userInfo)
}

func main() {
    r := gin.Default()
    r.GET("/users", _json)

    r.Run(":8000")
}

然后游览器就不会渲染出来了,并且相应的数据里也没有

image-20231027225356894

ps:这里可以传结构体,也可以传Map,包括直接传JSON,都会进行渲染

1.3 HTML(*)

使用HTML方法返回HTML类型的响应内容。

先在文件夹下面创建一个templates文件夹,再创建一个index.html文件,

写上<header>你好啊, {{.username}}</header>,因为这里可以使用插值语法进行传参

image-20231027230941273

写main函数的时候,注意需要告诉服务器index文件在哪,所以需要使用这个函数进行加载

func main() {
	r := gin.Default()
	r.LoadHTMLGlob("GinStudy01_HelloWord/templates/*") // 加载目录下的所有文件(全局加载)
	r.GET("/users", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", gin.H{
			"username": "张三",
		})
	})

	r.Run(":8000")
}

当我们访问http://localhost:8000/users时,就能够在浏览器上看到HTML格式的输出内容。

image-20231027231642921

1.4 XML

使用XML方法返回XML类型的响应内容。

func main() {
    r := gin.Default()

    r.GET("/users", func(c *gin.Context) {
        c.XML(http.StatusOK, gin.H{
            "name": "Tom",
            "age":  18,
        })
    })

    r.Run(":8080")
}

当我们访问http://localhost:8080/users时,就能够在浏览器上看到XML格式的输出内容。

1.5 文件(*)

将文件服务于指定的URL路径上,可以用于提供静态资源(如图片、CSS文件、JavaScript文件等)

创建一个文件夹static,然后放一个文件进去,例如:我放了一个图片,image.jpg文件

StaticFile提供的是一个单个文件的静态服务,将指定的文件服务于指定的URL路径上,使用这个方法时,只需指定文件的绝对路径和访问路径即可:

func main() {
    r := gin.Default()
    r.StaticFile("static/image.jpg", "GinStudy01_HelloWord/static/image.jpg")

    r.Run(":8000")
}

然后我们访问http://localhost:8000/static/image.jpg,就可以响应到对应的图片

StaticFs 提供的是一个基于http.FileSystem的静态文件服务,可以将多个静态文件目录映射到不同的访问路径下

func main() {
    r := gin.Default()
    fs := http.Dir("GinStudy01_HelloWord/static")
    r.StaticFS("/static", fs)
    r.Run(":8000")
}

然后,我们可以再static文件夹下面再放其他的文件,例如:我放了一个text.txt文件

访问:http://localhost:8000/static/text.txt

image-20231027234019639

如果你想要访问图片,就直接访问http://localhost:8000/static/image.jpg即可

2 请求

2.1 请求参数

查询参数 (Query)
func _query(c *gin.Context) {
    // 使用query
    name := c.Query("name")
    age := c.Query("age")
    // 处理查询参数
    c.JSON(http.StatusOK, gin.H{
       "name": name,
       "age":  age,
    })
    fmt.Printf("name=%v, age=%v", name, age)
}

func main() {
    router := gin.Default()
    router.GET("/query", _query)
    router.Run(":8080")
}

访问:http://127.0.0.1:8080/query?name=张三&age=18,就会看到结果,并且打印在Goland上面

动态参数 (Param)
func _param(c *gin.Context) {
    // 使用Param方法
    id := c.Param("id")
    // 处理动态参数
    c.JSON(http.StatusOK, gin.H{
       "id": id,
    })
}

func main() {
    router := gin.Default()
    // 注意:这里动态参数是这里不同
    router.GET("/user/:id", _param)
    router.Run(":8080")
}

访问:http://127.0.0.1:8080/user/1,就能看到结果

表单参数 (PostForm)
func _postForm(c *gin.Context) {
    // 使用PostForm方法
    name := c.PostForm("name")
    age := c.PostForm("age")
    // 处理表单参数
    c.JSON(http.StatusOK, gin.H{
       "name": name,
       "age":  age,
    })
    fmt.Printf("name=%v, age=%v", name, age)
}

func main() {
    router := gin.Default()
    // 表单是POST请求
    router.POST("/users", _postForm)
    router.Run(":8080")
}

这里我使用Apifox调用接口,比较方便,用游览器比较麻烦

  1. 先创建一个项目,我写了一个Gin学习,不重要~
  2. 左边有个接口管理,在快捷请求里新建,然后使用POST,并且写上对应的url和下面选择Body,点击form-data

image-20231028152758905

然后点击发送,下面就是响应的JSON数据

原始参数 (GetRawData)
func _raw(c *gin.Context) {
    body, _ := c.GetRawData()
    fmt.Println(string(body))
}

func main() {
    router := gin.Default()
    router.POST("/raw", _raw)
    router.Run(":8080")
}

访问http://127.0.0.1:8080/raw,打印的数据如图

image-20231028155626168

2.2 请求头

请求头参数获取

GetHeader,可以大小写不分,且返回切片中的第一个数据

func _header(c *gin.Context) {
    // 首字母大小写不区分  单词与单词之间用 - 连接
    // 用于获取一个请求头
    fmt.Println(c.GetHeader("User-Agent"))
    //fmt.Println(c.GetHeader("user-agent"))

    // Header 是一个普通的 map[string][]string
    fmt.Println(c.Request.Header)

    // 如果是使用 Get方法或者是 .GetHeader,那么可以不用区分大小写,并且返回第一个value
    fmt.Println(c.Request.Header.Get("User-Agent"))
    fmt.Println(c.Request.Header["User-Agent"])

    // 如果是用map的取值方式,请注意大小写问题
    fmt.Println(c.Request.Header["user-agent"])

    // 自定义的请求头,用Get方法也是免大小写
    fmt.Println(c.Request.Header.Get("Token"))
    fmt.Println(c.Request.Header.Get("token"))
    c.JSON(200, gin.H{"msg": "成功"})
}

func main() {
    router := gin.Default()
    router.GET("/header", _header)
    router.Run(":8080")
}

打开F12,再访问:http://127.0.0.1:8080/header,通过对比看到对应的结果

image-20231028162412900

2.3 响应头

设置响应头的方式

func _header(c *gin.Context) {
    c.Header("Token", "jhgeu%hsg845jUIF83jh")
    c.Header("Content-Type", "application/text; charset=utf-8")
    c.JSON(0, gin.H{"data": "看看响应头"})
}

func main() {
    router := gin.Default()
    router.GET("/header", _header)
    router.Run(":8080")
}

一样使用F12,访问进行查看~

image-20231028162627447

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在el-dialog中使用tinymce 点击工具栏下拉框被遮挡

在el-dialog中使用tinymce控件时&#xff0c;会出现点击工具栏下拉框出现在弹窗下一层&#xff0c;审查元素之后发现是tinymce的下拉框z-index优先级低于el-dialog的z-index导致的&#xff0c;所以需要增加tinymce的下拉框的z-index值。 通过审查元素得到&#xff0c;需要修改t…

【C语言】free()函数详解(动态内存释放函数)

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:C语言 ⚙️操作环境:Visual Studio 2022 目录 一.free()函数简介 1.函数功能 2.函数参数 void * ptr 3.函数返回值 4.函数头文件 二.free()函数的具体使用 1.使用free()函数完成malloc()开辟空间的释放 2.使用fr…

Spring Cloud Alibaba Seata 实现 SAGA 事物

Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式&#xff0c;为用户打造一站式的分布式解决方案 Seata 官网&#xff1a;https://seata.io/zh-cn/ Spring Cloud Alibaba 官…

[Java/力扣100]判断两棵二叉树是否相同

我希望通过这道题&#xff0c;能进一步了解递归思想和“树是递归定义的”这句话 分析 我们的目的是写一个方法来检验两棵树是否相同 什么叫“两棵树相同”&#xff1f;——相同的位置存在相同的结点 有三种情况&#xff1a;1、两棵树一颗为空一颗不为空——不相同&#xff…

分类预测 | Matlab实现KOA-CNN-BiGRU-selfAttention多特征分类预测(自注意力机制)

分类预测 | Matlab实现KOA-CNN-BiGRU-selfAttention多特征分类预测&#xff08;自注意力机制&#xff09; 目录 分类预测 | Matlab实现KOA-CNN-BiGRU-selfAttention多特征分类预测&#xff08;自注意力机制&#xff09;分类效果基本描述程序设计参考资料 分类效果 基本描述 1.M…

oracle,CLOB转XML内存不足,ORA-27163: out of memory ORA-06512: at “SYS.XMLTYPE“,

通过kettle采集数据时&#xff0c;表输入的组件&#xff0c;查询报错。 ORA-27163: out of memory ORA-06512: at “SYS.XMLTYPE”, line 272 ORA-06512: at line 1 通过 ALTER SESSION SET EVENTS ‘31156 trace name context forever, level 0x400’; 修改会话配置 或直接修改…

工作组与域

目录 内网环境 内网环境分类 工作组 域 域的组成 域中的信任关系 父域与子域 域的结构 林中信任关系特点 域中的域名 活动目录&#xff08;AD&#xff09; 域中活动目录下的账号登录域中计算机过程 组织单位&#xff08;OU&#xff09; 组策略&#xff08;GPO&am…

Vue全局事件总线实现任意组件间通信

一、安装全局事件总线 全局事件总线就像是一个工具&#xff0c;专门用于挂载自定义事件和。 想要所有的组件都能使用这个全局事件总线&#xff0c;就只有在Vue的原型身上添加一个能够绑定自定义事件的属性。 所以我们在创建Vue实例对象的时候就可以添加如下代码&#xff1a;…

Pytorch:model.train()和model.eval()用法和区别,以及model.eval()和torch.no_grad()的区别

1 model.train() 和 model.eval()用法和区别 1.1 model.train() model.train()的作用是启用 Batch Normalization 和 Dropout。 如果模型中有BN层(Batch Normalization&#xff09;和Dropout&#xff0c;需要在训练时添加model.train()。model.train()是保证BN层能够用到每一…

【网络编程】传输层——UDP协议

文章目录 一、传输层1. 再谈端口号2. 端口号范围划分3. 认识知名端口号4. 两个问题5. netstat 与 pidof 二、UDP协议1. UDP协议格式2. UDP协议的特点3. 面向数据报4. UDP的缓冲区5. UDP使用注意事项6. 基于UDP的应用层协议 一、传输层 传输层 负责负责两台计算机之间的端到端的…

java原子类-Atomic

什么是原子类&#xff1f; java 1.5引进原子类&#xff0c;具体在java.util.concurrent.atomic包下&#xff0c;atomic包里面一共提供了13个类&#xff0c;分为4种类型&#xff0c;分别是&#xff1a; 原子更新基本类型&#xff0c;原子更新数组&#xff0c;原子更新引用&…

Pritunl搭建OpenVPN服务器详细流程,快速实现公网远程连接!

文章目录 前言1.环境安装2.开始安装3.访问测试4.创建连接5.局域网测试连接6.安装cpolar7.配置固定公网访问地址8.远程连接测试 前言 Pritunl是一款免费开源的 VPN 平台软件&#xff08;但使用的不是标准的开源许可证&#xff0c;用户受到很多限制&#xff09;。这是一种简单有…

GO学习之 通道(nil Channel妙用)

GO系列 1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 10、GO学习之 网络通信(Net/Htt…

STM32F4VGT6-DISCOVERY:uart1驱动

对于这款板子&#xff0c;官方并没有提供串口例程&#xff0c;只能自行添加。 一、PA9/PA10复用成串口1功能不可用 驱动测试代码如下&#xff1a; main.c: #include "main.h" #include <stdio.h>void usart1_init(void) {GPIO_InitTypeDef GPIO_InitStruct…

前端 : 用html ,css,js写一个你画我猜的游戏

1.HTML&#xff1a; <body><div id "content"><div id "box1">计时器</div><div id"box"><div id "top"><div id "box-top-left">第几题:</div><div id "box…

linux-磁盘应用

目录 一、磁盘内容简述 1、一些基本概念 2、分区简述 3、常见文件系统 4、linux硬盘文件 二、对linux系统进行分区 1、用fdisk进行分区 2、用parted进行分区 一、磁盘内容简述 1、一些基本概念 - 扇区大小&#xff1a;512Btyes&#xff0c;0.5KB - 磁盘最小存储单位&…

小黑子—spring:第一章 Bean基础

spring入门1.0 一 小黑子对spring基础进行概述1.1 spring导论1.2 传统Javaweb开发困惑及解决方法1.3 三大的思想提出1.3.1 IOC入门案例1.3.2 DI入门案例 1.4 框架概念1.5 初识spring1.5.1 Spring Framework 1.6 BeanFactory快速入门1.7 ApplicationContext快速入门1.8 BeanFact…

python之计算平面点集的的面积

在当今数据驱动的世界中&#xff0c;计算平面点集的最小外接轮廓面积被广泛应用于各种实际场景中。它是一项重要而魅力十足的任务&#xff0c;旨在找到一个最小的矩形或多边形区域&#xff0c;能够完全包围给定的离散点集。这个看似简单的问题背后隐藏着许多挑战&#xff0c;需…

HTML5+CSS3+Vue小实例:路飞出海的动画特效

实例:路飞出海的动画特效 技术栈:HTML+CSS+Vue 效果: 源码: 【HTML】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content=&…

windows下OOM排查

如下有一段代码 package com.lm.demo.arthas.controller;import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.util.A…