18.3 HTTP服务器-响应不同类型的内容和请求、获取请求数据

news2024/11/15 3:53:56

1. 响应不同类型的内容

在向客户端返回响应时,服务器应根据客户端的具体需求,为其提供不同类型的内容。一些常见的内容类型包括:

  • text/plain —— 纯文本格式
  • text/html —— HTML格式
  • application/json —— JSON格式
  • application/xml —— XML格式

服务器通过查询请求头的"Accept"字段,获悉客户端期望接受的内容类型,并返回相应类型的数据内容。

  • switch r.Header.Get("Accept") { //  r是指 *http.Request
  • case "application/json":
  •         w.Header().Set("Content-Type", "application/json; charset=utf-8")
  •         w.Write([]byte(`{"Greeting": "Hello World!"}`))
  • case "application/xml":
  •         w.Header().Set("Content-Type", "application/xml; charset=utf-8")
  •       w.Write([]byte(`<?xml version="1.0" encoding="utf-8"?>
  • <Greeting>Hello World!</Greeting>`))
  • default: // 如何客户端请求的内容类型服务器无法满足时,我们可以以缺省的方式,以纯文本形式返回
  •         w.Header().Set("Content-Type", "text/plain; charset=utf-8")
  •         w.Write([]byte("Hello World!"))
  • }
// 响应不同的内容
// 服务器根据请求报头中的Accept字段,向客户机发送与其要求类型一致的数据
//
// 通过curl发起HTTP请求,可执行如下命令: 
// 通过curl向服务器发起请求,可使用-H选项设置请求头中的特定字段
// curl -is -H "Accept: application/json" "http://localhost:8000"
// curl -is -H "Accept: application/xml" "http://localhost:8000"
// curl -is -H "Accept: dummy/dummy" "http://localhost:8000"
package main
import "net/http"
func rootHandler(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path != "/" {
        http.NotFound(w, r)
        return
    }
	switch r.Header.Get("Accept") {
    case "application/json":
        w.Header().Set("Content-Type", "application/json; charset=utf-8")
        w.Write([]byte(`{"Greeting": "Hello World!"}`))

    case "application/xml":
        w.Header().Set("Content-Type", "application/xml; charset=utf-8")
        w.Write([]byte(`<?xml version="1.0" encoding="utf-8"?><Greeting>Hello World!</Greeting>`))

    default:
        w.Header().Set("Content-Type", "text/plain; charset=utf-8")
        w.Write([]byte("Hello World!"))
    }
}
func main() {
    http.HandleFunc("/", rootHandler)
    http.ListenAndServe(":8000", nil)
}

 通过curl向服务器发起请求,可使用-H选项设置请求头中的特定字段。

2. 响应不同类型的请求

为了获知来自客户端的请求类型,可以访问Request中的Method,并通过switch语句针对不同类型的请求,执行不同的操作,例如:

  • switch r.Method { //  r是指 *http.Request
  • case "GET":
  •         w.Write([]byte("Receive a GET request: Hello World!"))
  • case "POST":
  •         w.Write([]byte("Receive a POST request: Hello World!"))
  • default:
  •  w.WriteHeader(http.StatusNotImplemented) // 对于无法出路的请求,以StatusNotImplemented予以响应
  •         w.Write([]byte(http.StatusText(http.StatusNotImplemented)))
  • }

HTTP协议中的GET请求一般用于从服务器获取数据,而POST请求则意在向服务器提交要被处理的数据,返回的响应里面含有被获取到或处理过的数据。

// 响应不同类型的请求
// 在路由处理函数中,借助switch语句,根据HTTP请求的不同类型,做出不同处理
// 
// 通过curl发起HTTP请求,可执行如下命令: 
// 通过curl向服务器发起请求,可使用-X选项设置请求的类型
// curl -is -X GET "http://localhost:8000"
// curl -is -X POST "http://localhost:8000"
// curl -is -X DUMMY "http://localhost:8000"
package main

import "net/http"

func rootHandler(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path != "/" {
        http.NotFound(w, r)
        return
    }
	switch r.Method {
    case "GET":
        w.Write([]byte("Receive a GET request: Hello World!"))

    case "POST":
        w.Write([]byte("Receive a POST request: Hello World!"))

    default:
        w.WriteHeader(http.StatusNotImplemented)
        w.Write([]byte(http.StatusText(http.StatusNotImplemented)))
    }
}

func main() {
    http.HandleFunc("/", rootHandler)
    http.ListenAndServe(":8000", nil)
}

通过curl向服务器发起请求,可使用-X选项设置请求的类型。

3. 获取请求数据

对于GET请求,其携带的数据通常就位于查询字符串中。

  • http://localhost:8000/?username=yanan&password=123456
  • 对于这样的数据,可通过调用Request.URL.Query()方法获得。
    • for k, v := range r.URL.Query() { ... }
    • 请求中的每个数据项均被视为一个键值对,等号左边为键(k),右边为值(v)

对于POST请求,数据通常放在请求体中。

  • 对于这样的数据,可通过读取Request.Body获得
    • reqBody, err := ioutil.ReadAll(r.Body)
    • 这样得到的请求数据是一个字节切片,其内部格式需要自行解析。

注意所有进入服务器的数据都应被视为是不安全的,需经过滤后再使用

// 处理请求中的数据
// GET请求的数据通常以查询字符串的形式跟URL连
// 在一起,而POST请求的数据则位于请求报文体中
// 
// 通过curl发起HTTP请求,可执行如下命令: 
// curl -is -X GET "http://localhost:8000/?username=yanan&password=123456"
// curl -is -X POST -d "some data to send" "http://localhost:8000"
package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)
func rootHandler(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path != "/" {
        http.NotFound(w, r)
        return
    }

    switch r.Method {
    case "GET":
        for k, v := range r.URL.Query() {
            fmt.Printf("%v: %v\n", k, v)
        }
        w.Write([]byte("Receive a GET request: Hello World!"))

	case "POST":
        reqBody, err := ioutil.ReadAll(r.Body)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("%s\n", reqBody)
        w.Write([]byte("Receive a POST request: Hello World!"))

    default:
        w.WriteHeader(http.StatusNotImplemented)
        w.Write([]byte(http.StatusText(http.StatusNotImplemented)))
    }
}

func main() {
    http.HandleFunc("/", rootHandler)
    http.ListenAndServe(":8000", nil)
}
// 用户输入:
GET:username: yanan
	 password: 123456 
POST:some data to send

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

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

相关文章

Java多线程CompletableFuture使用

引言 一个接口可能需要调用N个其他服务的接口&#xff0c;这在项目开发中非常常见。如果是串行执行的话&#xff0c;接口的响应速度会很慢。考虑到这些接口之间有大部分都是无前后顺序关联的&#xff0c;可以并行执行。就比如说调用获取商品详情的时候&#xff0c;可以同时调用…

高效换热管

绕管式高效换热器 绕管换热器是一种结构紧凑&#xff0c;传热效率高的新型高效换热器。换热管按螺旋线形状交替缠绕在芯筒与外筒之间&#xff0c;相邻两层螺旋状换热管旋向相反&#xff0c;并采用一定形状的定距元件使之保持一定间距。层与层间换热管反向缠绕&#xff0c;极大…

解决python import时ModuleNotFoundError异常

文章目录 前言 一 import索引机制二 ModuleNotFoundError原因及其解决办法1. 模块&#xff0c;包名字错误2. 模块&#xff0c;包未导入或未安装3. 模块&#xff0c;包命名冲突4. 模块&#xff0c;包路径不在import索引范围内(常见且重点) 前言 在学习和使用python import xxx时…

“改进型”Howland 电流泵电路

“改进型”Howland 电流泵电路 “改进型”Howland 电流泵是一种使用差分放大器在分流电阻器 (Rs) 上施加电压的电路&#xff0c;从而产生能够驱动大范 围负载电阻的双极性&#xff08;拉电流或灌电流&#xff09;压控电流源。 设计注释 确保运算放大器的输入端&#xff08;V…

Spring应用如何打印access日志和out日志(用于分析请求总共在服务耗费多长时间)

我们经常会被问到这样一个问题。你接口返回的好慢呀&#xff0c;能不能提升一下接口响应时间啊&#xff1f;这个时候我们就需要去分析&#xff0c;为什么慢&#xff0c;慢在哪。而这首先应该做的就是确定接口返回时间过长确实是在服务内消耗的时间。而不是我们将请求发给网关或…

STM32高级篇—按键FIFO

想成问一名非常优秀的嵌入式软件工程师&#xff0c;是需要掌握很多知识的。 完成STM32的基础内容的学习后&#xff0c;我们也进入到学习STM32高级的内容上。 本人也是一名嵌入式的初级入坑人&#xff0c;写的内容可能会有错误&#xff0c;或者不正确的地方也请大家多多指教&…

1.0 Android中Activity的基础知识

一&#xff1a;Activity的定义 Activity是一个应用组件&#xff0c;它提供了一个用户界面&#xff0c;允许用户执行一个单一的、明确的操作&#xff0c;用户看的见的操作都是在activity中执行的。Activity的实现需要在manifest中进行定义&#xff0c;不让会造成程序报错。 1.…

【动态规划】| 路径问题之不同路径 力扣62

&#x1f397;️ 主页&#xff1a;小夜时雨 &#x1f397;️ 专栏&#xff1a;动态规划 &#x1f397;️ 如何活着&#xff0c;是我找寻的方向 目录 1. 题目解析2. 代码 1. 题目解析 题目链接: https://leetcode.cn/problems/unique-paths/description/ 通常动态规划的题目有…

【Linux】解决由于 network和 NetworkManager不兼容,导致的网络服务错误

今天尝试启动在虚拟机中启动一些中间件环境&#xff08;用docker管理&#xff09;&#xff0c;使用ssh连接虚拟机&#xff0c;却始终无法连接 我怀疑是不是虚拟机的ip地址改变了&#xff0c;但是之前我的虚拟机ip已经在 /etc/sysconfig/network-scripts 目录下&#xff0c;创…

PCA与LDA

共同点 降维方法&#xff1a; PCA和LDA都是数据降维的方式&#xff0c;它们都能通过某种变换将原始高维数据投影到低维空间。 数学原理&#xff1a; 两者在降维过程中都使用了矩阵特征分解的思想&#xff0c;通过对数据的协方差矩阵或类间、类内散度矩阵进行特征分解&#xff…

Vue项目实践:使用滚动下拉分页优化大数据展示页面【通过防抖加标志位进行方案优化】

Vue项目实践&#xff1a;使用滚动下拉分页优化大数据展示页面 前言 传统的分页机制通过点击页码来加载更多内容&#xff0c;虽然直观&#xff0c;但在处理大量数据时可能会导致用户体验不佳。相比之下&#xff0c;滚动下拉分页能够在用户滚动到页面底部时自动加载更多内容&…

实现JWT认证与授权的Spring Boot项目详解

我们将详细介绍如何使用JWT&#xff08;JSON Web Tokens&#xff09;结合Spring Boot框架实现用户认证和授权系统。此方案将包括用户注册、登录以及通过JWT令牌进行后续请求的身份验证过程。我们将从引入必要的依赖开始&#xff0c;然后逐步构建项目的各个部分&#xff0c;包括…

如何查看当前的gruop_id 的kafka 消费情况 这个可以查看到是否存在消费阻塞问题

如何查看当前的gruop_id 的kafka 消费情况 这个可以查看到是否存在消费阻塞问题 命令如下: /kafka/bin/kafka-consumer-groups.sh --bootstrap-server 127.0.0.1:9092 --group GWW --describe 其中 127.0.0.1 为zookeeper 服务器ip GWW 为对应要查看的group_id 如下…

从零到一建设数据中台(番外篇)- 数据中台UI欣赏

番外篇 - 数据中台 UI 欣赏 话不多说&#xff0c;直接上图。 数据目录的重要性&#xff1a; 数据目录是一种关键的信息管理工具&#xff0c;它为组织提供了一个全面的、集中化的数据资产视图。 它不仅记录了数据的存储位置&#xff0c;还详细描述了数据的结构、内容、来源、使…

800W-2300W-4500W-7000W线绕电阻器的选型参考

EAK线绕电阻器将普通电阻器材料的高脉冲稳定性与优化的导热和高度保护相结合。安装在导热表面上可进一步改善散热并提高稳定性。 EAK提供各种外壳设计和材料&#xff08;如铝和钢&#xff09;的导线电阻器。它们符合 UL508 的要求&#xff0c;在用作制动、充电、放电或加热电阻…

Java面试八股之静态变量和实例变量的区别有哪些

Java静态变量和实例变量的区别有哪些 存储位置和生命周期&#xff1a; 静态变量&#xff1a;静态变量属于类级别&#xff0c;存储在Java的方法区&#xff08;或称为类区&#xff0c;随JVM实现而异&#xff0c;现代JVM中通常在元数据区内&#xff09;&#xff0c;并且在类首次…

Rocky Linux 9.4 部署Zabbix 7.0

文章目录 Zabbix基本概念zabbix介绍zabbix特性zabbix结构 安装Zabbix主机名配置配置Zabbix-Server(1)禁用EPEL提供的Zabbix软件包(2)安装Zabbix Server、Web前端、Agent(3)创建初始数据库(4)Zabbix server配置数据库(5)为Zabbix前端配置PHP(6)启动Zabbix server和agent进程(7)放…

Windows电脑清理C盘内存空间

ps&#xff1a;过程截图放在篇末 一、%tmp%文件 win R键呼出运行窗口&#xff0c;输入 %tmp% 自动进入tmp文件夹&#xff0c;ctrl A全选删除 遇到权限不足&#xff0c;正在运行&#xff0c;丢失的文件直接跳过即可 二、AppData文件夹 1、pipcache 在下列路径下面&…

Amortized bootstrapping via Automorphisms

参考文献&#xff1a; [MS18] Micciancio D, Sorrell J. Ring packing and amortized FHEW bootstrapping. ICALP 2018: 100:1-100:14.[GPV23] Guimares A, Pereira H V L, Van Leeuwen B. Amortized bootstrapping revisited: Simpler, asymptotically-faster, implemented. …

代理设计模式之JDK动态代理CGLIB动态代理原理与源码剖析

代理设计模式 代理模式(Proxy),为其它对象提供一种代理以控制对这个对象的访问。如下图 从上面的类图可以看出,通过代理模式,客户端访问接口时的实例实际上是Proxy对象,Proxy对象持有RealSubject的引用,这样一来Proxy在可以在实际执行RealSubject前后做一些操作,相当于…