我正在使用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
}
答案 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))
}