You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android端Retrofit向Gin服务POST请求失败,Postman请求正常

问题描述

不确定问题出在哪一端,但Gin已接收到Android应用的请求却未正常处理。我在实现一个POST接口,接口关联的单体模型带有type字段,用来告知Gin哪些是必填字段(这部分系统流程较复杂)。Android端有对应此模型的本地实体类,之前仅实现了从服务器拉取数据的功能,现在要完成POST提交逻辑。

请求返回201状态码,但未出现预期的错误信息,尽管流程中每个错误分支都做了返回处理。


Android端模型代码

@Entity(tableName = "thing", indices = [Index(value = ["id"], unique = true)])
data class Thing(
    @PrimaryKey(autoGenerate = false) @ColumnInfo(name = "id") var id: String,
    @SerializedName("CreatedAt") @ColumnInfo(name = "created_at") var created_at: String,
    @ColumnInfo(name = "name") var name: String,
    @ColumnInfo(name = "type_id") var type_id: String,
    @ColumnInfo("type") var type: ThingType? = null,
    @ColumnInfo(
        name = "some_field_1",
        defaultValue = "0"
    ) var some_field_1: Float = 0.0f,
    @ColumnInfo(
        name = "some_field_2",
        defaultValue = "0"
    ) var some_field_2: Float = 0.0f,
    @ColumnInfo(
        name = "some_field_3",
        defaultValue = "0"
    ) var some_field_3: Float = 0.0f,
    @ColumnInfo(
        name = "some_field_4",
        defaultValue = "0"
    ) var some_field_4: Float = 0.0f,
    @ColumnInfo(
        name = "some_field_5",
        defaultValue = "0"
    ) var some_field_5: Float = 0.0f,
    @ColumnInfo(
        name = "parent_id",
        defaultValue = "0"
    ) var parent_id: String
)

服务端Go模型代码片段

type Thing struct {
    gorm.Model
    ID            string    `gorm:"primarykey; size:40;" json:"id"`
    Name          string    `json:"name"`
    TypeId        string    `gorm:"size:40; index; not null" json:"type_id"`
    Type          Type      `gorm:"foreignKey:TypeId; constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"type"`
    SomeField1    float32   `json:"some_field_1"`
    SomeField2    float32   `json:"some_field_2"`
    SomeField3    float32   `json:"some_field_3"`
    SomeField4    float32   `json:"some_field_4"`
    SomeField5    float32   `json:"some_field_5"`
    ParentId      float32   `json:"parent_id"`
}

Android Retrofit请求代码

@POST("/thing_info")
suspend fun postThingInfo(
    @HeaderMap headers: Map<String, String>,
    @Body data: Thing
): Response<Thing>

val thing =
    Thing(
        "",
        "",
        name = binding.txtName.text.toString(),
        type_id = typeId,
        some_field_1 = binding.txtSomeField1.text.toString()
            .toFloat(),
        some_field_2 = binding.txtSomeField2.text.toString()
            .toFloat(),
        some_field_3 = binding.txtSomeField3.text.toString()
            .toFloat(),
        parent_id = parentId,
    )

// Retrofit常规初始化代码省略

Gin端接口处理代码

ginGine.POST("/thing_info", func(ctx *gin.Context) {
    errMsg := clnHelpers.ValidateAccessToken(ctx.GetHeader("access_token"))

    if errMsg != "" {
        ctx.JSON(http.StatusBadRequest, gin.H{
            "error": errMsg,
        })
        return
    }

    var thing_info models.Thing

    err := ctx.ShouldBind(&thing_info)
    if err != nil {
        ctx.JSON(http.StatusBadRequest, gin.H{
            "error": err.Error(),
        })
        return
    }

    data := &pb.ThingInfo{
        Name:                        thing_info.Name,
        TypeId:                      thing_info.TypeId,
        // 其他字段映射省略
    }

    res, err := srvClient.service.CreateThingInfo(ctx, &pb.CreateThingInfoRequest{
        ThingInfo: data,
    })

    if err != nil {
        ctx.JSON(http.StatusBadRequest, gin.H{
            "error": err.Error(),
        })
        return
    }

    ctx.JSON(http.StatusCreated, gin.H{
        "thing_info": res.ThingInfo,
    })
})

排查方向

  • 字段类型不匹配:服务端ParentId是float32类型,但Android端parent_id是String类型,可能导致JSON反序列化异常,或数据转换后不符合下游服务要求。
  • type字段缺失:Android端创建Thing对象时未设置type字段(默认传null),而服务端依赖该字段判断必填项,但Gin的ShouldBind默认不会校验字段非空,需检查是否添加了binding:"required"这类校验标签。
  • 日志缺失:在Gin各个分支添加日志,打印thing_info绑定结果、下游gRPC请求参数,确认数据是否正确传递。
  • 下游服务无校验:如果CreateThingInfo接口本身未校验必填字段,即使数据缺失也会返回成功,导致Gin返回201,需检查下游服务逻辑。
  • Android序列化问题:确认Retrofit使用的JSON序列化器(如Gson)是否正确处理type字段的null值,是否将其序列化为null或直接忽略,导致服务端接收不到该字段。

内容的提问来源于stack exchange,提问作者rminaj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 07:46:51