go-gin响应被覆盖为400,即使正常返回

embedded/2024/9/18 23:58:26/ 标签: golang, gin, 开发语言

问题描述及排查过程

一个正常响应里,http状态码为400,但实际已经成功返回了数据,且无论是自己写的业务逻辑代码还是中间件都没有返回400(bad request)这个状态码。

而且gin debug日志中也提示说有操作试图将状态码400覆盖为200,这个操作肯定就是我们的正常业务响应了,那么这个400状态码是哪里来的呢?

答案是gin框架,因为在json unmarshal的时候有一个字段出错了,但是其他字段是可以正常使用的,而后面的业务逻辑中又没有使用这个没成功反序列化的字段,所以响应一直都是正常的。

接收前端请求的代码如下

func PostProj(c *gin.Context) {dto := PostReq{}// _ = c.BinJSON(&dto) 原来并没有判断错误,如果有err,还是会正常执行,而且出错的字段没有被业务逻辑使用到,一切就会很正常if err := c.BindJSON(&dto); err != nil {logrus.Error(err)c.JSON(http.StatusOK, HttpRespBody{Code: http.StatusBadRequest,Msg:  "",})return}...
}

但是BindJSON这个方法使用了MustBindJSON,要求更严格,

// BindJSON is a shortcut for c.MustBindWith(obj, binding.JSON).
func (c *Context) BindJSON(obj any) error {return c.MustBindWith(obj, binding.JSON)
}
// MustBindWith binds the passed struct pointer using the specified binding engine.
// It will abort the request with HTTP 400 if any error occurs.
// See the binding package.
func (c *Context) MustBindWith(obj any, b binding.Binding) error {if err := c.ShouldBindWith(obj, b); err != nil {c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheckreturn err}return nil
}

可以看到如果序列化过程有任何错误,就会中断请求并且设置状态码为400.

ShouldBind方法就没有这个限制了。

解决方案

一是加好err判断,如果反序列化失败,不管是哪个字段失败了,都立刻返回错误。而且建议状态码为400,更清晰。

如果业务要求全都返回http.StatusOK(200),那么这个BindJSON一定会将状态码改写为400,这时候就要看这个不符合要求的请求体是什么情况了,

如果能接受非法请求体,或者要求全部返回200状态码,就用ShouldBind(不推荐),它不会改写状态码

一般情况下,是要拒绝非法请求体的,还是要前端传一个合法的请求体,所以就继续用BindJSON,然后如果出错返回400 bad request就好了。


http://www.ppmy.cn/embedded/107348.html

相关文章

mysql5.7 TIMESTAMP NOT NULL DEFAULT ‘0000-00-00 00:00:00‘ 换版8版本 引发的问题

mysql5.7 TIMESTAMP NOT NULL DEFAULT 0000-00-00 00:00:00 换版引发的问题 问题背景sql_mode上机演示5.78.4 问题背景 在项目mysql版本由5.7 换版到8.4版本后,我们进行回归测试时,却发现一个积年代码报错了,是数据库插入报的错 xxx can not…

计算机知识科普问答--1

1、在CPU中,汇编语言程序猿可见的寄存器有哪些?(MAR、MDR、IR、PC) 在CPU中,汇编语言程序员可见的寄存器主要包括通用寄存器、程序计数器(PC)、标志寄存器等。像MAR(内存地址寄存器)、MDR(内存数据寄存器)、IR(指令寄存器)等寄存器,虽然在CPU内部起着重要的作用,…

后台框架-统一数据格式

现在BS架构的应用一般都采用前后端分离的架构,前端技术框架可采用VUE等,后端框架目前成熟且使用广泛的就是基于SpringBoot开发的后端微服务框架。 数据格式 这里主要介绍一下如何实现返回统一的数据格式,比如返回的样例数据如下图所示&…

2024 年高教社杯全国大学生数学建模竞赛 A 题 “板凳龙” 闹元宵思路分析

🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。 “板凳龙”,又称“盘龙”&#…

垃圾收集器

文章目录 SerialParNewParallel ScavengeSerial OldParallel OldCMSG1G1区域划分内存模型传统分区GC的内存G1的内存分区管理的影响分代下的分区管理回收机制Minor GC和Mixed GCNUMA-Aware支持云场景支持 基本配置参数 ZGC内存管理 ShenandoahEplison 垃圾收集器(Gar…

驱动开发系列14 - Linux Graphics Wayland 详解

目录 一:概述 二:操作系统如何支持 Wayland 三:显卡驱动如何支持 Wayland 四:Wayland 协议介绍 一:概述 Wayland 是一种通信协议,规定了显示服务器与其客户端之间的通信,以及该协议的 C 语言库实现。使用 Wayland 协议的显示服务器称为 Wayland 合成器,因…

Go入门:gin框架极速搭建图书管理系统

Go入门:gin框架极速搭建图书管理系统 前言 本项目适合 Golang 初学者,通过简单的项目实践来加深对 Golang 的基本语法和 Web 开发的理解。 项目源码请私信,欢迎前往博主博客torna.top免费查看。 项目结构 D:. ├─ go.mod ├─ go.sum │ ├─ cmd │ └─ main │ …

ClickHousez中如何定时清理过期数据库?

一、脚本清理 要在ClickHouse中自动删除过期的数据库,你可以使用ClickHouse的SQL命令结合外部脚本(如Shell脚本)和计划任务(如cron)来实现。下面是一个示例,展示如何创建一个Shell脚本来检查数据库的创建时…

Drools规则引擎入门及实战

目录 一、Drools简介 二、创建spring boot项目引入Drools依赖 三、创建Drools配置类 四、创建Order实体类 五、在resource目录下创建规则文件 六、编写测试类 七、规则引擎的构成 八、KIE介绍 九、Drools基础语法 一、Drools简介 drools是一款由JBoss组织提供的基于ja…

【Next】2. 项目构建

打开 Next.js 的官方文档:https://nextjs.org/docs/getting-started/installation(国内文档不够新) Next.js 版本 14.2 , Node.js 的版本要求必须 > 18.18。 Next 有两种开发模式,下面讲新的 APP Router。 创建项…

conda create创建失败

如图一样,每次创建环境都显示连接不上,换了各种源各种方法都不行,最后把.condarc给删掉就能正常下载了,我类目了

42次9.4(k8s环境安装)

一、前期准备 1.系统环境 k8s-master 192.168.1.11 k8s-node1 192.168.1.22 k8s-node2 192.168.1.33 2.配置主句映射 [rootk8s-master ~]# vim /etc/hosts 192.168.1.11 k8s-master 192.168.1.22 k8s-node1 192.168.1.33 k8s-node2 #测试 [rootk8s-master ~]# p…

【代码随想录训练营第42期 Day46打卡 - 回文问题 - LeetCode 647. 回文子串 516.最长回文子序列

目录 一、做题心得 二、题目与题解 题目一:647. 回文子串 题目链接 题解1:动态规划 题解2:中心扩展法 题目二:516.最长回文子序列 题目链接 题解1:反转LCS 题解2:动态规划 三、小结 一、做题心得…

【Python基础】循环控制语句

本文收录于 《Python编程入门》专栏,从零基础开始,分享一些Python编程基础知识,欢迎关注,谢谢! 文章目录 一、前言二、for循环三、while循环四、循环控制语句五、循环的高级应用六、总结 一、前言 ​ 在Python编程中&…

【串的相关概念】

1.前情回顾: 2.串的定义 注意这里的字符是任意字符:包括特殊字符和空格 2.1串的相关术语 2.2分析如下: 子串与主串 可以类比 子集与集合的关系 且空串也是子串的一种 注意空格串与空串的区别 位置是从1开始设定的(第一个位置开始…

(二十九)STL map容器(映射)与STL pair容器(值对)

C中的map容器是什么?可以说这个是python中的字典(dict) T {1:5, 3:7, 5:4, 4:9, 2:6} print(T)学过python的都知道字典的每一项都有一个键(key)和一个值(value),而且键是不能重复的…

vue 踩坑记录

本地开发没有cookie 解决方案 设置代理,并把changeOrigin设为true proxy的changeOrigin如果设置为false:请求头中host仍然是浏览器发送过来的host; 如果设置成true:发送请求头中host会设置成target。 允许axios请求携带cookie等凭…

Linux字符设备驱动 -- regulator子系统

文章目录 环境regulator子系统简介:Regulator设备的注册Consumer设备的注册 环境 linux 4.9 armv8-A regulator子系统简介: 关于regulator子系统,可以看下这这些博客: Linux驱动之Regulator子系统Linux 内核之电源篇(加载流程…

乐鑫ESP-HMI方案人机交互,设备彩屏显示新体验,启明云端乐鑫代理商

在数字化浪潮的推动下,人机交互的方式正在经历一场深刻的变革。用户对于智能设备的需求不再局限于基本的功能操作,而是期望能够通过更加直观、自然的方式与设备进行交流。 这种需求催生了一系列创新的芯片方案,它们通过集成高性能的计算核心…

MacOS通过Docker部署安装zookeeper、dubbo-admin,以及Docker Desktop进行管理

1.建立一个网络桥接zk docker network create -d bridge zk我们通过docker安装dubbo-admin和zookeeper,为了保证他们能够正常通信,需要使用同一个网络 2.创建zookeeper的docker卷 docker volume create zookeeper_data 3.启动zookeeper,并指定网络和卷 docker run -d \--n…