无法使用 Golang 从具有 mySQL 后端的 gorilla/sessions 获取值

Can't get value from gorilla/sessions with mySQL backend using Golang

我试图在具有 mySQL 后端的大猩猩会话中为我的模型保存一个结构,但当我尝试检索它时,venueID 只得到 0。我可以毫不费力地保存和获取即显消息。我的目标是在会话中保存模型结构并检索它以获取编辑、更新和删除功能中的 ID 号。

这是我的代码:

type appResource struct {
    tmpl  *template.Template // net/http
    store *mysqlstore.MySQLStore
    db    *sql.DB // database/sql
}

// newAppResource function to pass global var
func newAppResource(store *mysqlstore.MySQLStore, db *sql.DB, tmpl *template.Template) *appResource {
    return &appResource{
        store: store,
        db:    db,
        tmpl:  tmpl,
    }
}

func main() {

sessionKey := os.Getenv("sessionKey")

    endpoint := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?parseTime=true&loc=Local", dbUser, dbPass, dbHost, dbPort, dbName)
    tableName := "sessions"
    path := "/"
    maxAge := 3600
    codecs := []byte(sessionKey)

    store, err := mysqlstore.NewMySQLStore(endpoint, tableName, path, maxAge, codecs)
    if err != nil {
        log.Println("SESSIONS STORE error")
        log.Fatal(err)
....
    }

}


type Venue struct {
    VenueID int
    Name    string
    Email   string
    Phone   string
    Active  bool
}

// VenueData template variable for show and edit
type VenueData struct {
    Venue   Venue
    Flashes []interface{}
}

func (rs *appResource) venuesShow(w http.ResponseWriter, r *http.Request) {

    var venue Venue

    var data VenueData

    id := r.URL.Query().Get("id")

    venueID, err := strconv.Atoi(id)
    if err != nil {
        log.Println("show venue ID not > 0")
        http.Redirect(w, r, "/login", http.StatusUnauthorized)
        return
    }

    if !(venueID > 0) {
        log.Println("update venue ID not > 0")
        http.Redirect(w, r, "/login", http.StatusUnauthorized)
        return
    }

    query, err := rs.db.Query("SELECT id, name, email, phone, active FROM Venues WHERE id=?", venueID)
    if err != nil {
        log.Fatal(err)
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    for query.Next() {

        err = query.Scan(&venue.VenueID, &venue.Name, &venue.Email, &venue.Phone, &venue.Active)
        if err != nil {
            log.Fatal(err)
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
    }

    data.Venue = venue

    session, err := rs.store.Get(r, "admin-data")
    if err != nil {
        log.Fatal(err)
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    log.Println(venue.VenueID)

    if flashes := session.Flashes(); len(flashes) > 0 {
        for _, message := range flashes {
            data.Flashes = append(data.Flashes, message)
        }
    }

    session.Values["venue"] = venue

    session.Save(r, w)
    if err != nil {
        log.Fatal(err)
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    if err := rs.tmpl.ExecuteTemplate(w, "venues-show", data); err != nil {
        log.Fatal(err)
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}


func (rs *appResource) venuesEdit(w http.ResponseWriter, r *http.Request) {

    var data VenueData

    session, err := rs.store.Get(r, "admin-data")
    if err != nil {
        log.Fatal(err)
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    venue := getVenue(session)

    venueID := venue.VenueID

    query, err := rs.db.Query("SELECT id, name, email, phone, active FROM Venues WHERE id=?", venueID)
    if err != nil {
        log.Fatal(err)
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    for query.Next() {

        err = query.Scan(&venueID, &venue.Name, &venue.Email, &venue.Phone, &venue.Active)
        if err != nil {
            log.Fatal(err)
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }

        data.Venue = venue
    }

    if err := rs.tmpl.ExecuteTemplate(w, "venues-edit", data); err != nil {
        log.Fatal(err)
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}


func getVenue(s *sessions.Session) Venue {
    val := s.Values["venue"]
    var venue = Venue{}
    venue, ok := val.(Venue)
    if !ok {
        log.Println("no venue found")
        return Venue{}
    }
    return venue
}

事实证明,我需要注册一个结构才能在 Gorilla 会话中使用它。

import (
"encoding/gob"
)

func main() {
 gob.Register(Venue{})
}