来自我的 Android 应用程序时,POST 到 Gin 失败,但来自 Postman 时成功

问题描述 投票:0回答:1

我不太确定问题的原因是哪一方,但似乎

Gin
收到了请求,但不允许来自
android
应用程序的请求。我尝试
POST
的端点与具有类型字段的整体模型相关,并且该类型字段“告诉”
Gin
哪些是必需的字段(对于我的系统的这一部分来说,我的工作流程有点复杂)。在
android
方面,我有一个该整体模型的对应模型,因为我将它用于应用程序中的某些内容。以前,我只需要从服务器获取与整体模型相关的数据。现在,我正在为其实现
POST
。服务器模型的
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
)

这是单体服务器模型的一个片段:

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"`
}

然后我像这样使用

POST
Thing
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,
    )

//then the usual Retrofit boilerplate

使用这些代码,我只看到请求收到 201,但没有错误,即使我为进程中出现的每个错误对象返回一些内容。

这是 golang 代码顺便说一句:

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,
        //other field association
    }

    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,
    })
})
android go retrofit go-gin grpc-go
1个回答
0
投票

终于找到这个问题的答案了,我觉得和

gorm
有关。因此,在我实际的 Android 模型中,我添加了
created_at
,因为我需要它在 Android 端进行一些排序。因为它是
gorm
自动添加的字段,所以我认为在
POST
处理
Thing
时,我真的不需要为它提供值,我什至不需要将它传递给
Postman
。最初,我只是向它传递一个空字符串,但它不喜欢它。然后我想有

var thing_info models.ThingInfo

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

在我的代码中会给我返回错误,就像我迄今为止遇到的所有其他错误一样。但事实并非如此,不知何故,之前的错误没有返回给我。然后我插入了一个很好的ol'

fmt.Printf("thing_info bind err: %v\n", err)

在 if 语句中,最终得到一个错误(讽刺的是很高兴发现错误)。看起来,尽管

created_at
是一个
gorm
添加的字段,但它试图将我从 Android 应用程序传递的空字符串转换为日期和时间。经过一些测试,似乎传递一个看起来像
2023-08-07T4:46:00Z
的字符串是可以接受的,幸运的是,
gorm
似乎忽略了该值并放置了记录的实际创建日期时间。

© www.soinside.com 2019 - 2024. All rights reserved.