英文:
Different api responses for same object values
问题
这是代码示例:
func GetValue(c echo.Context) error {
    //其他实现细节
    value, err := service.GetValue()
    if err != nil {
        return c.JSON(http.StatusBadRequest, errorresponse.Error(4003, err))
    }
    //如果我在这里设置相同的值,它会按预期工作
    //value.Value = []int8{48, 48, 48, 54, 54, 49, 56, 54, 32, 32, 32, 32, 32, 32, 32}
    return c.JSON(http.StatusOK, value)
}
//这是service.GetValue()方法返回的类型
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"
}
英文:
This is the code example:
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
}
If I use the value which comes from service.GetValue() method, the API gives me a response like bellow. It converts it to a some kind of string which I don't know. When I check the value.Value property, the reflect.TypeOf(value.Value) says, it is a []int8 as type. Also the VSCode debugger approves it.
THE OBJECT USED IN REQUEST:
THE RESPONSE:
{
    "Value": "MDAwNjYxODYgICAgICAg",
    "ValueType": "[]uint8"
}
If I set expected value manually, it works as expected and I do not understand why the first one is not.
value.Value = []int8{48, 48, 48, 54, 54, 49, 56, 54, 32, 32, 32, 32, 32, 32, 32}
THE OBJECT USED IN REQUEST:
THE RESPONSE:
{
    "Value": [
        48,
        48,
        48,
        54,
        54,
        49,
        56,
        54,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32
    ],
    "ValueType": "[]uint8"
}
答案1
得分: 0
在Golang中,byte是uint8的别名,当你使用json.Marshal时,它返回的是[]byte类型,与你的数据类型相同。所以当你接收到这种类型的数据时,它会被转换为字符串。
你需要将uint8转换为其他整数类型,或者实现Marshaler接口。
转换
bytes, err := service.GetValue()
value := make([]int8, 0)
for _, v := range bytes {
	value = append(value, int8(v))
}
Marshaler
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)
}
英文:
In Golang byte is alias for uint8 and when you use json.Marshal it returns []byte which is same type as your data. So when you receive this type of data it is translated to string.
You need to cast uint8 to other int type or implement Marshaler interface
Cast
bytes, err := service.GetValue()
value := make([]int8, 0)
for _, v := range bytes {
	value = append(value, int8(v))
}
Marshaler
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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。




评论