对相同对象值的不同 api 响应

Different api responses for same object values

这是代码示例:

func GetValue(c echo.Context) error {
    //other implementation details
    
    value, err := service.GetValue()
    if err != nil {
        return c.JSON(http.StatusBadRequest, errorresponse.Error(4003, err))
    }

    //if I set same value here, it works as expected
    //value.Value = []int8{48, 48, 48, 54, 54, 49, 56, 54, 32, 32, 32, 32, 32, 32, 32}

    return c.JSON(http.StatusOK, value)
}
 
//this is type service.GetValue() returns
type ValueGetResponse struct {
    Value     interface{}
    ValueType string
}

如果我使用来自 service.GetValue() 方法的值,API 会给我如下的响应。它将它转换为某种我不知道的字符串。当我检查 value.Value 属性 时,reflect.TypeOf(value.Value) 说,它是 []int8 作为类型。 VSCode 调试器也批准了它。

请求中使用的对象:

响应:

{
    "Value": "MDAwNjYxODYgICAgICAg",
    "ValueType": "[]uint8"
}

如果我手动设置预期值,它会按预期工作,我不明白为什么第一个不是。

value.Value = []int8{48, 48, 48, 54, 54, 49, 56, 54, 32, 32, 32, 32, 32, 32, 32}

请求中使用的对象:

响应:

{
    "Value": [
        48,
        48,
        48,
        54,
        54,
        49,
        56,
        54,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32
    ],
    "ValueType": "[]uint8"
}

在 Golang 中,byteuint8 的别名,当您使用 json.Marshal 时,它 returns []byte 与您的数据类型相同。所以当你收到这种类型的数据时,它会被翻译成字符串。

您需要将 uint8 转换为其他 int 类型或实现 Marshaler interface

演员表

bytes, err := service.GetValue()
value := make([]int8, 0)
for _, v := range bytes {
    value = append(value, int8(v))
}

编组器

type CustomType []uint8

func (u CustomType) MarshalJSON() ([]byte, error) {
    var result string
    if u == nil {
        result = "null"
    } else {
        result = strings.Join(strings.Fields(fmt.Sprintf("%d", u)), ",")
    }
    return []byte(result), nil
}

func GetValue(c echo.Context) error {
    var value CustomType
    bytes, err := service.GetValue()
    value = bytes

    return c.JSON(http.StatusOK, value)
}