Go 中 `json.NewEncoder/Decoder` 与 `json.Marshal/Unmarshal` 的区别与实践
Go 中 json.NewEncoder/Decoder
与 json.Marshal/Unmarshal
的区别与实践(HTTP 示例)
在 Go 中处理 JSON 有两种主要方式:使用 json.Marshal/Unmarshal
和使用 json.NewEncoder/Decoder
。它们都能完成 JSON 的序列化与反序列化,但使用场景和优势略有不同。
🌱 一、整体概念对比
功能 | json.Marshal / json.Unmarshal | json.NewEncoder / json.NewDecoder |
---|---|---|
输入输出 | []byte / string | io.Writer / io.Reader |
性能 | 一次性读写,适合小数据 | 流式处理,适合大数据、网络请求体 |
易用性 | 简洁直观,适合内存中的 JSON 数据 | 可处理流式数据、更适合 HTTP 读写场景 |
典型应用 | JSON API 响应构建、配置文件加载等 | HTTP 请求/响应处理、文件流读取 |
🚀 二、HTTP 示例对比
我们用两个示例分别展示:
json.NewEncoder/Decoder
:直接读写http.Request.Body
和http.ResponseWriter
json.Marshal/Unmarshal
:先读完整体,再解析和返回
🧾 公共结构体定义:
type User struct {ID int `json:"id"`Name string `json:"name"`Email string `json:"email"`
}
🧪 方法一:使用 json.NewDecoder
和 json.NewEncoder
func handlerWithEncoderDecoder(w http.ResponseWriter, r *http.Request) {var user Userif err := json.NewDecoder(r.Body).Decode(&user); err != nil {http.Error(w, "invalid json", http.StatusBadRequest)return}response := map[string]interface{}{"status": "received","user": user,}w.Header().Set("Content-Type", "application/json")if err := json.NewEncoder(w).Encode(response); err != nil {http.Error(w, "encode error", http.StatusInternalServerError)}
}
🧪 方法二:使用 json.Unmarshal
和 json.Marshal
func handlerWithMarshal(w http.ResponseWriter, r *http.Request) {bodyBytes, err := io.ReadAll(r.Body)if err != nil {http.Error(w, "read error", http.StatusInternalServerError)return}var user Userif err := json.Unmarshal(bodyBytes, &user); err != nil {http.Error(w, "invalid json", http.StatusBadRequest)return}response := map[string]interface{}{"status": "received","user": user,}w.Header().Set("Content-Type", "application/json")jsonData, err := json.Marshal(response)if err != nil {http.Error(w, "encode error", http.StatusInternalServerError)return}w.Write(jsonData)
}
⚖️ 三、对比总结
对比点 | Encoder/Decoder | Marshal/Unmarshal |
---|---|---|
使用便捷性 | 可直接对接 HTTP 输入输出流 | 需要读取/写入中间变量 []byte |
适合大数据 | ✅ 是(流式处理) | ❌ 需一次性加载全部数据 |
性能优势 | 节省内存,特别适合大请求/响应 | 适合结构简单或数据量小的应用 |
调试方便 | 较复杂(不便打印中间数据) | 中间变量可供调试、日志记录 |
💡 实际建议
- 接收请求体(尤其大数据或长连接):建议使用
json.NewDecoder
- 返回响应数据(动态生成):建议使用
json.NewEncoder
- 处理缓存、小数据、临时结构体转换:使用
json.Marshal/Unmarshal
更方便
🧪 curl 测试命令
curl -X POST http://localhost:8080/encoder \-H "Content-Type: application/json" \-d '{"id": 1, "name": "Alice", "email": "alice@example.com"}'
📚 参考文档
- encoding/json 包官方文档
希望这篇文章能帮助你理解 json.Marshal/Unmarshal
和 json.NewEncoder/Decoder
的差异,并选择适合你项目场景的方式。
相关文章:
Go 中 `json.NewEncoder/Decoder` 与 `json.Marshal/Unmarshal` 的区别与实践
Go 中 json.NewEncoder/Decoder 与 json.Marshal/Unmarshal 的区别与实践(HTTP 示例) 在 Go 中处理 JSON 有两种主要方式:使用 json.Marshal/Unmarshal 和使用 json.NewEncoder/Decoder。它们都能完成 JSON 的序列化与反序列化,但…...

UE5 2D角色PaperZD插件动画状态机学习笔记
UE5 2D角色PaperZD插件动画状态机学习笔记 0.安装PaperZD插件 这是插件下载安装地址 https://www.fab.com/zh-cn/listings/6664e3b5-e376-47aa-a0dd-f7bbbd5b93c0 1.右键创建PaperZD 动画序列 2.添加动画序列 3,右键创建PaperZD AnimBP (动画蓝图&am…...

Ubuntu 16.04 密码找回
同事整理的供参考: 进入GRUB菜单 重启系统,在启动过程中长按Shift键(或Esc键)进入GRUB引导菜单。 若未显示GRUB菜单,可尝试在启动时连续按多次Shift/Esc键。 在GRUB菜单中选择默认的Ubuntu启动项(第一…...

【论文阅读】DanceGRPO: Unleashing GRPO on Visual Generation
DanceGRPO: Unleashing GRPO on Visual Generation 原文摘要 研究背景与问题 生成模型的突破:扩散模型和整流流等生成模型在视觉内容生成领域取得了显著进展。核心挑战:如何让模型的输出更好地符合人类偏好仍是一个关键问题。现有方法的局限性࿱…...

CentOS在vmware局域网内搭建DHCP服务器【踩坑记录】
1. 重新设置环境 配置dhcp服务踩了不少坑,这里重头搭建记录一下: 1.1 centos 网卡还原 如果之前搭了乱七八糟的环境,导致NAT模式也没法上网,这里重新还原 我们需要在NAT模式下联网,下载DHCP服务 先把centos的网卡还…...

AI炼丹日志-28 - Audiblez 将你的电子书epub转换为音频mp3 做有声书
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 大模型与Java双线更新中! 目前《大语言模型实战》已连载至第22篇,探索 MCP 自动操作 FigmaCursor 实…...
图像处理篇---face_recognition库实现人脸检测
以下是使用face_recognition库实现人脸检测的详细步骤、实例代码及解释: 一、环境准备 1. 安装依赖库 pip install face_recognition opencv-python # 核心库 pip install matplotlib # 用于显示图像(可选)2. 依赖说明 face_recognitio…...

74. 搜索二维矩阵 (力扣)
给你一个满足下述两条属性的 m x n 整数矩阵: 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 false 。…...

8088单板机C语言sprintf()格式化串口输出---Prj04
#include "tiny_stdarg.h" // 使用自定义可变参数实现#define ADR_273 0x0200 #define ADR_244 0x0400 #define LED_PORT 0x800 #define PC16550_THR 0x1f0 #define PC16550_LSR 0x1f5 / //基本的IO操作函数 / char str[]"Hello World! 20250531 Ve…...

板凳-------Mysql cookbook学习 (九)
第4章:表管理 4.0 引言 MySQL :: 员工样例数据库 :: 3 安装 https://dev.mysql.com/doc/employee/en/employees-installation.html Employees 数据库与几种不同的 存储引擎,默认情况下启用 InnoDB 引擎。编…...
深入解析 Flask 命令行工具与 flask run命令的使用
Flask 是一个轻量级的 Python Web 应用框架,其内置的命令行工具(CLI)基于 Click 库,提供了方便的命令行接口,用于管理和运行 Flask 应用程序。本文将详细介绍 Flask 命令行工具的功能,以及如何使用 flask r…...
第6篇:中间件 SQL 重写与语义分析引擎实现原理
6.1 章节导读 SQL 是数据库中间件的“输入语言”。 在一个真正强大的中间件系统中,SQL 语句的执行通常不再是“原封不动”地传递给数据库,而是需要先经过: 语义分析:解析 SQL 的结构和含义。 SQL 重写:根据中间件逻辑…...

基于SpringBoot的“嗨玩旅游”网站设计与实现(源码+定制+开发)嗨玩旅游平台开发:景点展示与个性化推荐系统(SpringBoot)
博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…...

python版若依框架开发:python版若依部署
python版若依框架开发 从0起步,扬帆起航。 python版若依部署文章目录 python版若依框架开发1.源码2.概述3.部署1.源码 https://gitee.com/insistence2022/RuoYi-Vue-FastAPI 请诸君移步上述链接,即可对python版若依项目进行初步了解。 2.概述 若依框架本身基于java,可以快…...
React进阶:状态管理选择题
React进阶:状态管理选择题 引言 随着React应用复杂度增加,选择合适的状态管理方案成为我们面临的关键决策。 状态管理本质上是解决"谁来存储数据"以及"如何更新和分发这些数据"的问题。在React生态中,随着应用规模扩大…...

h5的aliplayer-min.js 加密视频会走到debugger
h5的aliplayer-min.js 如果 https://g.alicdn.com/apsara-media-box/imp-web-player/2.19.0/aliplayer-min.js走加密视频的话会有debugger 更换aliplayer-min.js版本解决了 https://g.alicdn.com/apsara-media-box/imp-web-player/2.25.1/aliplayer-min.js 对应css:…...
第5篇《中间件负载均衡与连接池管理机制设计》
5.1 章节导读 在数据库中间件中,如何高效地管理数据库连接与请求调度至关重要。 本节围绕两个核心模块展开: 连接池管理:提升连接复用能力,避免频繁建立/断开连接。 负载均衡策略:合理调度 SQL 请求,提升…...

DashBoard安装使用
DashBoard安装使用 一、实验目的 1、掌握dashboard 的安装部署 2、熟悉图像化部署任务:产生pod---定义服务--验证访问 二、实验内容: 1、配置步骤 1.1、Helm安装 离线安装(适用于内网/离线环境) # 根据系统架构选择版本&am…...

极客大挑战 2019 EasySQL 1(万能账号密码,SQL注入,HackBar)
题目 做法 启动靶机,打开给出的网址 随便输点东西进去,测试一下 输入1、1’、1"判断SQL语句闭合方式 输入以上两个都是以下结果 但是,输入1’时,出现的是另外结果 输入1,1"时,SQL语句没有…...
C# CallerMemberName特性
当你在一个方法运用了CallerMemberName特性,编译器会自动将调用该方法的方法或属性的名称作为该参数的默认值,可应用于MVVM框架。 代码: using System.ComponentModel; using System.Runtime.CompilerServices;public class Person : INoti…...

采用 Docker GPU 部署的 Ubuntu 或者 windows 桌面环境
# 国内下载不了 docker pull gezp/ubuntu-desktop:24.04-cu12.6.2# 阿里云镜像 docker pull registry.cn-hongkong.aliyuncs.com/gezp/ubuntu-desktop:24.04-cu12.6.2# create container with nomachine docker run -d --restarton-failure --name myubuntu --shm-size1024m -e…...

关于面试找工作的总结(四)
不同情况下收到offer后的处理方法 1.不会去的,只是面试练手2.还有疑问,考虑中3.offer/职位不满足期望的4.已确认,但又收到更好的5.还想挽回之前的offer6.确认,准备入职7.还想拖一下的1.不会去的,只是面试练手 HR您好,非常荣幸收到贵司的offer,非常感谢一直以来您的帮助,…...

分布式拜占庭容错算法——实现工作量证明(PoW)算法详解
Java 实现工作量证明(PoW)算法详解 一、PoW 核心原理 #mermaid-svg-AAj0Pvst1PVcVy5v {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-AAj0Pvst1PVcVy5v .error-icon{fill:#552222;}#mermaid…...

深度解析Mysql中MVCC的工作机制
MVCC,多版本并发控制 定义:维护一个数据的多个版本,使读写操作没有冲突,依赖于:隐藏字段,undo log日志,readView MVCC会为每条版本记录保存三个隐藏字段 DB_TRX_ID: 记录最近插入或修改该记录的事务IDDB_R…...

MP4文件声音与视频分离
最近学习PR剪辑 要添加视频文件和音频文件 但是直接给MP4文件 得到的是一个整体 不管怎么切分 都是无法得到单独的整体 这就需要将视频文件和音频文件分离 我推荐使用ffmpeg工具进行分离 迅雷链接:https://pan.xunlei.com/s/VORu5x64jjL-gXFd_VTpYjRPA1?pwd8wec#…...

接口自动化测试之pytest 运行方式及前置后置封装
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、Pytest 优点认知 1.可以结合所有的自动化测试工具 2.跳过失败用例以及失败重跑 3.结合allure生产美观报告 4.和Jenkins持续集成 5.很多强大的插件 pytest-htm…...
服务器被攻击了怎么办
可以上一个高防IP或者AI云防护都是可以的。(有效防御CC、APl接口、http、tcp、WEB应用扫描/爬虫、SYN、WAF、DDOS、UDP、入侵、渗透、SQL注入、XSS跨站脚本攻击、远程恶意代码执行、session fixation、Webshell攻击、恶意请求,恶意扫描、暴力破解、CSRF等…...

06-排序
排序 1. 排序的概念及其应用 1.1 排序的概念 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 稳定性:假定在待排序的记录序列中,存在多个具有相同的关键…...
python,shell,linux,bash概念的不同和对比联系
一、基本概念理解 1. Linux 是一个 操作系统内核,常与 GNU 工具集成组成完整的 Linux 操作系统。 提供对硬件的管理能力与系统调用接口。 用户通过 Shell 或 GUI 与 Linux 交互。 2. Shell 是用户与 Linux 内核之间的 命令行解释器(CLI)…...

FPGA管脚类型,及选择
fpga的IO Type选择,如下: 具体的定义:...