在go

时间:2015-06-10 05:41:48

标签: xml go base64 gorp

这是我开发的函数的完整代码:

package main

import (
    "database/sql"
    "log"
    "encoding/xml"
    "github.com/gin-gonic/gin" //golang frameworks
    _ "github.com/go-sql-driver/mysql"
    "gopkg.in/gorp.v1"        //work with database(mysql, etc.)
)

type Genre struct {
    Title string `xml:"genre"`
}

type GenreArray struct {
    Auth_state int `xml:"auth_state"`
    Count int64 `xml:"count"`
    Item genreAPI `xml:"item"`
}

type UserPass struct {
    Username string `xml:"username"`
    Password string `xml:"password"`
}

type ErrorMessage struct {
    XMLName xml.Name `xml:"error"`
    Error string `xml:"error_code"`
    Message string `xml:"message"`
}

type Auth struct {
    XMLName xml.Name `xml:"config"`
    Nas_SharingEmpty  int `xml:"nas_sharing>auth_state"`
}

type ConfigGenre struct {
    XMLName xml.Name `xml:"config"`
    Nas_Sharing  GenreArray `xml:"nas_sharing"`
}

type genreAPI []Genre

var dbmap = initDb()

func initDb() *gorp.DbMap {

    db, err := sql.Open("mysql", "root@tcp(localhost:3306)/mymusic")
    checkErr(err, "sql.Open failed")
    dbmap := &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{"InnoDB", "UTF8"}}

    return dbmap
}

func checkErr(err error, msg string) {
    if err != nil {
        log.Fatalln(msg, err)
    }
}

func main() {
    r := gin.Default()
    r.POST("/nas_sharing", myMusicXML)
    r.Run(":9999")
}

func myMusicXML(c *gin.Context) {

    c.Request.ParseForm()
    cmd := c.Request.Form.Get("cmd")
    usernamepost := c.Request.Form.Get("user")
    passwordpost := c.Request.Form.Get("passwd")

    if cmd == "36" {
    //Music Genre List API

        var genre []Genre
        var userpass []UserPass
        var count int64
        var countAuth int64

        //Query the post username and password
        _, errAuth := dbmap.Select(&userpass, "SELECT username, password FROM user WHERE username=? and password=?", usernamepost, passwordpost)

        //Check if post username and password exist
        countAuth, errAuth = dbmap.SelectInt("select count(*) FROM user WHERE username=? and password=?", usernamepost, passwordpost)
        if countAuth == 0 {
            //If no rows detected, output a message
            c.XML(404, Auth{Nas_SharingEmpty: 0})
        }else{
            //Check if query is valid
            if errAuth == nil {
                log.Println("auth_state :", countAuth)
            }else{
                c.XML(404, gin.H{"error": "sql query error found"})
            }

            //Query genre list
            _, err := dbmap.Select(&genre, "SELECT Title FROM genre_cntr_tbl")

            //Count genres
            count, err = dbmap.SelectInt("select count(*) FROM genre_cntr_tbl")
            if count == 0 {
                //If no rows detected, output a message
                c.XML(404, ErrorMessage{Error:"404", Message: "no genre found"})
            }else{
                //Check if query is valid
                if err == nil {
                    log.Println("Genres :", genre)
                    c.XML(200, ConfigGenre{Nas_Sharing: GenreArray{Auth_state: 1, Count: count, Item: genre,}})
                }else{
                    c.XML(404, gin.H{"error": "sql query error found"})
                }
            }
        }
    }else{
        c.XML(404, ErrorMessage{Error:"404", Message: "command not found"})
    }
}

这是输出:

<config>
<nas_sharing>
    <auth_state>1</auth_state>
    <count>8</count>
    <item>
        <genre>Pop</genre>
    </item>
    <item>
        <genre>Rock</genre>
    </item>
    <item>
        <genre>Dance</genre>
    </item>
    <item>
        <genre>Opera</genre>
    </item>
    <item>
        <genre>Techno</genre>
    </item>
    <item>
        <genre>Hip Hop</genre>
    </item>
    <item>
        <genre>Jazz</genre>
    </item>
    <item>
        <genre>Reggae</genre>
    </item>
</nas_sharing>

以下是我输出到日志的类型的值(注意:它来自数据库):

Genres : [{Pop} {Rock} {Dance} {Opera} {Techno} {Hiphop} {Jazz} {Reggae}]  

但是,我想将输出转换为base64格式。这是一个用于编码到base64的示例代码,但给出的数据是string,与我开发的数据不同。我怎么能实现那个输出?

data := "/MyMusic/images/_albums/albums_nophoto.png"
sEnc := b64.StdEncoding.EncodeToString([]byte(data))
fmt.Println(sEnc)

这是我期望的输出

<config>
<nas_sharing>
    <auth_state>1</auth_state>
    <count>8</count>
    <item>
        <genre>UG9w</genre>
    </item>
    <item>
        <genre>Um9jaw==</genre>
    </item>
    <item>
        <genre>RGFuY2U=</genre>
    </item>
    <item>
        <genre>T3BlcmE=</genre>
    </item>
    <item>
        <genre>VGVjaG5v</genre>
    </item>
    etc...

1 个答案:

答案 0 :(得分:1)

前言:第一部分回答原始问题(将数组编码为Base64)。如果您只希望单个string字段在输出中显示为Base64字符串,请参阅第2部分。

[]string编码为Base64格式

Base64是一种编码,一种用于使用一组定义良好的字符将任意字节序列转换为文本的函数。

因此,您必须决定/想出一种将[]string数组或切片转换为字节序列的方法。

一种简单方便的方法是将您的[]string转换为JSON文本,该文本也会处理带有引号"的字符串。结果string可以使用您描述的方法轻松编码:

genre := []string{"Pop", "Rock", "Dance", "Opera", "Techno", "Hiphop", "Jazz", "Reggae"}

data, _ := json.Marshal(&genre)
fmt.Println(string(data))
sEnc := base64.StdEncoding.EncodeToString(data)
fmt.Println(sEnc)

输出(在Go Playground上尝试):

["Pop","Rock","Dance","Opera","Techno","Hiphop","Jazz","Reggae"]
WyJQb3AiLCJSb2NrIiwiRGFuY2UiLCJPcGVyYSIsIlRlY2hubyIsIkhpcGhvcCIsIkphenoiLCJSZWdnYWUiXQ==

解码

有了这样的Base64结果,你可以这样解码:

data2, err := base64.StdEncoding.DecodeString(sEnc)
if err != nil {
    panic(err)
}
var genre2 []string
if err = json.Unmarshal(data2, &genre2); err != nil {
    panic(err)
}
fmt.Println(genre2)

输出:

[Pop Rock Dance Opera Techno Hiphop Jazz Reggae]

备注:

当然,您可以选择任何其他转换来将[]string转换为字节序列。您可以将其转换为XML,或使用encoding/binary或其他任何内容。我之所以选择JSON,是因为它是一个单线程,紧凑,快速,并且几乎支持所有编程语言,所以如果另一个程序必须解码它就不会有问题。

使单个string字段显示为Base64

您可以通过在类型上实现Marshaler界面(或封闭struct)来实现此目的:

func (g *Genre) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
    g2 := *g
    g2.Title = base64.StdEncoding.EncodeToString([]byte(g.Title))
    return e.EncodeElement(g2, start)
}

基本上这样做会创建Genre的副本,将Title字段(副本)的值更改为其原始值的Base64表示形式并对此副本进行编码。

输出(部分),在Go Playground上尝试:

<GenreArray>
    <item>
        <genre>UG9w</genre>
    </item>
    <item>
        <genre>Um9jaw==</genre>
    </item>
</GenreArray>