Go sqlx库提供奇怪的base64编码结果
我正在从使用此库进行查询。根据文档,我找到了下面的代码Go sqlx库提供奇怪的base64编码结果,go,Go,我正在从使用此库进行查询。根据文档,我找到了下面的代码 func cities(w http.ResponseWriter, r *http.Request, _ httprouter.Params) error { var main string var secondary string var limit string queryParams := make(map[string]interface{}) if k := r.PostFormValu
func cities(w http.ResponseWriter, r *http.Request, _ httprouter.Params) error {
var main string
var secondary string
var limit string
queryParams := make(map[string]interface{})
if k := r.PostFormValue("keyword"); k != "" {
main = "city.name LIKE :keyword"
queryParams["keyword"] = k + "%"
}
if sk := r.PostFormValue("secondaryKeyword"); sk != "" && sk != "null" {
secondary = "OR city.name = :secondaryKeyword"
queryParams["secondaryKeyword"] = sk
}
if mr := r.PostFormValue("maxResults"); mr != "" {
limit = "LIMIT :maxResults"
queryParams["maxResults"] = mr
}
if lr := r.PostFormValue("lastRequest"); lr != "" && lr == "1" {
limit = ""
}
query := fmt.Sprintf(`
SELECT
city.geonameid AS cityId,
city.name AS cityName,
COALESCE(admin1.name_local, '') AS admin1Name,
country.name AS countryName,
CONCAT_WS(' ', city.name, city.asciiname, country.name) AS searchString
FROM geonames_cities1000 AS city
INNER JOIN geonames_countryinfo AS country
ON city.iso_alpha2 = country.iso_alpha2
LEFT OUTER JOIN geonames_admin1_codes_ascii as admin1
ON admin1.code = CONCAT(city.iso_alpha2, '.', city.admin1_code)
WHERE %s %s
ORDER BY city.name ASC %s;
`, main, secondary, limit)
nstmt, err := sql.DB.PrepareNamed(query)
if err != nil {
return err
}
rows, err := nstmt.Queryx(queryParams)
if err != nil {
return err
}
results := []interface{}{}
for rows.Next() {
row := make(map[string]interface{})
err := rows.MapScan(row)
if err != nil {
return err
}
results = append(results, row)
}
b, err := json.Marshal(results)
if err != nil {
return err
}
w.Write(b)
return nil
}
发送具有以下值的POST request postman chrome插件:
keyword: "tron"
maxResults: 7
lastRequest: 0
给出了此JSON输出:
[
{
"admin1Name": "VXR0YXJhZGl0",
"cityId": 1605268,
"cityName": "VHJvbg==",
"countryName": "VGhhaWxhbmQ=",
"searchString": "VHJvbiBUcm9uIFRoYWlsYW5k"
},
{
"admin1Name": "Q2FsYWJyaWE=",
"cityId": 8949073,
"cityName": "VHJvbmNh",
"countryName": "SXRhbHk=",
"searchString": "VHJvbmNhIFRyb25jYSBJdGFseQ=="
},
{
"admin1Name": "QXJhZ29u",
"cityId": 3107444,
"cityName": "VHJvbmNow7Nu",
"countryName": "U3BhaW4=",
"searchString": "VHJvbmNow7NuIFRyb25jaG9uIFNwYWlu"
},
{
"admin1Name": "UHVlYmxh",
"cityId": 8859151,
"cityName": "VHJvbmNvbmFs",
"countryName": "TWV4aWNv",
"searchString": "VHJvbmNvbmFsIFRyb25jb25hbCBNZXhpY28="
},
{
"admin1Name": "U2NobGVzd2lnLUhvbHN0ZWlu",
"cityId": 2821000,
"cityName": "VHLDtm5kZWw=",
"countryName": "R2VybWFueQ==",
"searchString": "VHLDtm5kZWwgVHJvbmRlbCBHZXJtYW55"
},
{
"admin1Name": "U8O4ci1UcsO4bmRlbGFn",
"cityId": 3133880,
"cityName": "VHJvbmRoZWlt",
"countryName": "Tm9yd2F5",
"searchString": "VHJvbmRoZWltIFRyb25kaGVpbSBOb3J3YXk="
},
{
"admin1Name": "VG9uZ3Nh",
"cityId": 1252408,
"cityName": "VHJvbmdzYQ==",
"countryName": "Qmh1dGFu",
"searchString": "VHJvbmdzYSBUcm9uZ3NhIEJodXRhbg=="
}
]
为什么结果是这样?将结果放入spew.Dump()中
将给出如下内容(我只是输出其中一行):
我在这里做错了什么?”
编辑:
我试着用structs代替Elwinar的建议。但有些事情真的很奇怪
此代码适用于:
type City struct {
AdminName string `json:"admin1Name" db:"admin1Name"`
CityID int64 `json:"cityId" db:"cityId"`
CityName string `json:"cityName" db:"cityName"`
CountryName string `json:"countryName" db:"countryName"`
SearchString string `json:"searchString" db:"searchString"`
}
但此代码不起作用,并输出错误“缺少目标名称cityId”:
有什么区别
解决方案:必须用空格键分隔标签。不能使用tab键进行空格,也不能使用逗号分隔标记。包编码/json将封送
[]字节
切片base64编码(请参阅)。所以问题就出在通过json.Marshal(results)
的输出中
在某个地方,您的代码调用一个函数,该函数生成一个[]字节
,该字节很好地隐藏在其中一个{}接口
中。去掉每个空接口,在适当的地方使用字符串,问题要么消失,要么解决方案显而易见
(调用
json.marshall
并出于调试目的输出结果可能不是一个好主意,尤其是如果您不知道实际的封送是什么。)正如spew.Dump
告诉您的那样,SQL驱动程序返回文本列的[]uint8
。事实上,它相当于[]字节
,它将json.Marshal
编码为base64字符串
解决这一问题的最简单方法是将行扫描到一个真正的结构中(sqlx在StructScan
方面做得很好),该结构将具有string
字段,以便json.Marshal
按预期显示它们。您可以使用标记控制字段的SQL和JSON名称,这样您的实体就可以有每种语言的约定名称
例如:
type City struct {
AdminName string `json:"admin1Name" sql:"admin1Name"`
CityID int64 `json:"cityId" sql:"cityId"`
CityName string `json:"cityName" sql:"cityName"`
CountryName string `json:"countryName" sql:"countryName"`
SearchString string `json:"searchString" sql:"searchString"`
}
在您的数据库架构中,哪种类型是,例如,
countryName
?我尝试过这样做,但不断出现“缺少目标名称cityId”错误。好了,现在可以了,我需要将sql标记更改为db标记!谢谢顺便问一句,您知道我是否应该推迟rows.Close()和额外的err=rows.err()检查,正如这里强调的:我一直得到“缺少目标名称cityId”错误当结构没有与结果列匹配的字段时,会发生此错误。因此,请仔细检查标记(我不记得它是db
还是sql
,我用了很长时间)和结果名称。这件事…
type City struct {
CityId int64 `json:"cityId" db:"cityId"`
CityName string `json:"cityName" db:"cityName"`
Admin1Name string `json:"admin1Name" db:"admin1Name"`
CountryName string `json:"countryName" db:"countryName"`
SearchString string `json:"searchString" db:"searchString"`
}
type City struct {
AdminName string `json:"admin1Name" sql:"admin1Name"`
CityID int64 `json:"cityId" sql:"cityId"`
CityName string `json:"cityName" sql:"cityName"`
CountryName string `json:"countryName" sql:"countryName"`
SearchString string `json:"searchString" sql:"searchString"`
}