JSON编组接口字节切片时出现奇怪的结果

时间:2016-05-13 18:22:09

标签: go

我正在使用Redigo Redis库并尝试使用json.Marshal从排序集中获得的结果,但我得到的结果如下:

"eyJmcm9tSWQiOjEsInRvSWQiOjUsInR5cGUiOjMsInBvc3RJZCI6MSwiY29tbWVudElkIjo0NCwiY3JlYXRlZFRpbWUiOjE0NjMxNTY0ODQsImlzVmlld2VkIjpmYWxzZSwidXNlcm5hbWUiOiJBZG1pbiIsImltYWdlIjoiaHc2ZE5EQlQtMzZ4MzYuanBnIn0="

当我得到这个时:

"{"fromId":5,"toId":1,"type":3,"postId":4,"commentId":49,"createdTime":1463161736,"isViewed":false,"username":"Alexander","image":"JZIfHp8i-36x36.png"}"

我有一个Notification struct

type Notification struct {
    FromId int64 `json:"fromId"`
    ToId   int64 `json:"toId"`
    OfType int64 `json:"type"`

    PostId       int64  `json:"postId"`
    CommentId    int64  `json:"commentId"`
    CreatedTime  int64  `json:"createdTime"`
    IsViewed     bool   `json:"isViewed"`
    FromUsername string `json:"username"`
    FromImage    string `json:"image"`
}

func New() *Notification {
    return &Notification{
        CreatedTime: time.Now().Unix(),
    }
}

它有一个将json字符串保存到Redis排序集中的方法。

func (n *Notification) Create(pool *redis.Pool, multicast chan<- []byte) error {
    var err error
    n.FromUsername, err = validation.FilterUsername(n.FromUsername)
    if err != nil {
        return err
    }
    // We can use the same validation as for a username here.
    n.FromImage, err = validation.FilterUsername(n.FromImage)
    if err != nil {
        return err
    }
    key := fmt.Sprintf("user:%d:notification", n.ToId)
    b, err := json.Marshal(n)
    if err != nil {
        return err
    }
    c := pool.Get()
    defer c.Close()
    c.Send("ZADD", key, n.CreatedTime, string(b))
    // Limiting to the top ranked 50 items.
    c.Send("ZREMRANGEBYRANK", key, 0, -50)
    if err := c.Flush(); err != nil {
        return err
    }
    multicast <- b
    return nil
}

这一切都很好。但后来我想获取这些结果,然后作为json格式化字符串数组发送到客户端。我保存在有序集中的json格式化字符串。

我正在做这样简单的事情。

func ByUserId(userId int64, pool *redis.Pool) (interface{}, error) {
    key := fmt.Sprintf("user:%d:notification", userId)
    c := pool.Get()
    defer c.Close()
    c.Send("ZREVRANGE", key, 0, -1)
    c.Flush()
    return c.Receive()
}

但它不起作用。

当我json.Marshal结果时,我得到一个像这样的字符串数组:

"eyJmcm9tSWQiOjEsInRvSWQiOjUsInR5cGUiOjMsInBvc3RJZCI6MSwiY29tbWVudElkIjo0NCwiY3JlYXRlZFRpbWUiOjE0NjMxNTY0ODQsImlzVmlld2VkIjpmYWxzZSwidXNlcm5hbWUiOiJBZG1pbiIsImltYWdlIjoiaHc2ZE5EQlQtMzZ4MzYuanBnIn0="

如果我spew.Dump()结果我得到这个输出:

([]interface {}) (len=1 cap=1) {
 ([]uint8) (len=149 cap=149) {
  00000000  7b 22 66 72 6f 6d 49 64  22 3a 35 2c 22 74 6f 49  |{"fromId":5,"toI|
  00000010  64 22 3a 31 2c 22 74 79  70 65 22 3a 33 2c 22 70  |d":1,"type":3,"p|
  00000020  6f 73 74 49 64 22 3a 34  2c 22 63 6f 6d 6d 65 6e  |ostId":4,"commen|
  00000030  74 49 64 22 3a 34 39 2c  22 63 72 65 61 74 65 64  |tId":49,"created|
  00000040  54 69 6d 65 22 3a 31 34  36 33 31 36 31 37 33 36  |Time":1463161736|
  00000050  2c 22 69 73 56 69 65 77  65 64 22 3a 66 61 6c 73  |,"isViewed":fals|
  00000060  65 2c 22 75 73 65 72 6e  61 6d 65 22 3a 22 53 74  |e,"username":"Al|
  00000070  61 72 64 75 73 6b 22 2c  22 69 6d 61 67 65 22 3a  |exander","image":|
  00000080  22 4a 5a 49 66 48 70 38  69 2d 33 36 78 33 36 2e  |"JZIfHp8i-36x36.|
  00000090  70 6e 67 22 7d                                    |png"}|
 }
}

我该怎么办?

编辑:

这是我最后所做的,但感觉很多不必要的转换。

func ByUserId(userId int64, pool *redis.Pool) ([]string, error) {
    key := fmt.Sprintf("user:%d:notification", userId)
    c := pool.Get()
    defer c.Close()
    c.Send("ZREVRANGE", key, 0, -1)
    c.Flush()
    reply, err := c.Receive()
    if err != nil {
        return nil, nil
    }
    arr, ok := reply.([]interface{})
    if !ok {
        return nil, err
    }
    ss := []string{}
    for _, v := range arr {
        b, ok := v.([]byte)
        if !ok {
            return nil, nil
        }
        ss = append(ss, string(b))
    }
    return ss, nil
}

在句柄上:

func notifications(w http.ResponseWriter, r *http.Request, _ httprouter.Params) error {
    userId, err := user.LoggedIn(r)
    if err != nil {
        return unauthorized
    }
    jsonResp := make(map[string]interface{})
    jsonResp["notifications"], err = notification.ByUserId(userId, redisPool)
    if err != nil {
        return err
    }
    jsonResp["success"] = true
    b, err := json.Marshal(jsonResp)
    if err != nil {
        return err
    }
    w.Write(b)
    return nil
}

1 个答案:

答案 0 :(得分:0)

函数ByUserId可以写成:

func ByUserId(userId int64, pool *redis.Pool) ([]string, error) {
  key := fmt.Sprintf("user:%d:notification", userId)
  c := pool.Get()
  defer c.Close()
  return redis.Strings(c.Do("ZREVRANGE", key, 0, -1))
}