Golang的json marshal和encoding输出结果奇怪。

huangapple go评论85阅读模式
英文:

Golang json marshal and encoding give weird output

问题

我正在尝试自定义我的数据库查询的错误消息。以下是我正在做的:首先创建一个名为Errormessage的结构体。接下来,如果在db.query中出现错误,我会进行编组、编码然后返回。但是,我最终得到的输出是“e30=”,这是在我的Postman测试中。可能出了什么问题?我检查了一些示例并遵循了它们展示的机制。

error1 := Errormessage{"Error in select"}
error1_enc, errEn := json.Marshal(error1)
if errEn != nil {
    // 如果错误不为空
    // 打印错误
    fmt.Println(errEn)
}
json.NewEncoder(w).Encode(error1_enc)
return
// 声明一个结构体
type Errormessage struct {
    // 定义结构体变量
    errormessage string
}

func checkExistUser(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()
    fmt.Println("File Name :", r.FormValue("email"))

    result, err := db.Query("SELECT * from userDetailsss")
    if err != nil {
        //http.Error(w, err, 500)
        w.Header().Set("Content-Type", "application/json; charset=utf-8")
        w.Header().Set("X-Content-Type-Options", "nosniff")
        w.WriteHeader(400)
        fmt.Println(err)
        error1 := Errormessage{"Error in select"}
        error1_enc, errEn := json.Marshal(error1)
        if errEn != nil {
            // 如果错误不为空
            // 打印错误
            fmt.Println(errEn)
        }
        json.NewEncoder(w).Encode(error1_enc)
        return
        //panic(err.Error())
    }
}

这部分是我定义和打开数据库的方式:

var db *sql.DB
var err error

func main() {
    db, err = sql.Open("mysql", "******#@tcp(127.0.0.1:3306)/****")
    if err != nil {
        panic(err.Error())
    }
    defer db.Close()
    router := mux.NewRouter()
    router.HandleFunc("/", DoHealthCheck).Methods("POST")
    router.HandleFunc("/checkExistUser", checkExistUser).Methods("POST")
    log.Fatal(http.ListenAndServe(":8080", router))
}

希望对你有帮助!

英文:

I am trying to customise error message for my db query . Following is what I am doing first I create struct Errormessage . Next if there is error in db.query I do this marshaling then encoding and return. But I end up getting this output "e30=" on my postman testing. What could be wrong I check and followed few examples are showing this mechanism ?

 error1 := Errormessage{"Error in select"}
        error1_enc,errEn := json.Marshal(error1)
        if errEn != nil {
                
          // if error is not nil
          // print error
          fmt.Println(errEn)
      }
        json.NewEncoder(w).Encode(error1_enc)
    		return

/

/ declaring a struct
type Errormessage struct{
        
  // defining struct variables
  errormessage string
}
func checkExistUser(w http.ResponseWriter, r *http.Request) {
 
  r.ParseForm()
  fmt.Println("File Name :", r.FormValue("email"))

  result, err := db.Query("SELECT * from userDetailsss")
  if err != nil {
    //http.Error(w, err, 500)
    w.Header().Set("Content-Type", "application/json; charset=utf-8")
    w.Header().Set("X-Content-Type-Options", "nosniff")
    w.WriteHeader(400)
    fmt.Println(err)
    error1 := Errormessage{"Error in select"}
    error1_enc,errEn := json.Marshal(error1)
    if errEn != nil {
            
      // if error is not nil
      // print error
      fmt.Println(errEn)
  }
    json.NewEncoder(w).Encode(error1_enc)
		return
    //panic(err.Error())
  }

// This part is how my db is defined and opened

var db *sql.DB
var err error

func main() {
  db, err = sql.Open("mysql", "******#@tcp(127.0.0.1:3306)/****")
  if err != nil {
    panic(err.Error())
  }
  defer db.Close()
  router := mux.NewRouter()
  router.HandleFunc("/", DoHealthCheck).Methods("POST")
  router.HandleFunc("/checkExistUser", checkExistUser).Methods("POST")
  log.Fatal(http.ListenAndServe(":8080", router))
  
}

答案1

得分: 2

你的代码有两个问题:

  1. 你对已经进行了 JSON 编码的错误进行了第二次 JSON 编码。这意味着你正在对原始的 JSON 字节进行 JSON 编码,这就是奇怪输出的原因。
  2. 你的 Errormessage 结构体的字段是未导出的。未导出的字段将不会被 encoding/json 包编码。

要解决问题 #1,你可以这样做:

func checkExistUser(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	fmt.Println("File Name :", r.FormValue("email"))

	result, err := db.Query("SELECT * from userDetailsss")
	if err != nil {
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		w.Header().Set("X-Content-Type-Options", "nosniff")
		w.WriteHeader(400)
		
		// 只使用 Encode,不需要调用 json.Marshal
		if err := json.NewEncoder(w).Encode(Errormessage{"Error in select"}); err != nil {
			log.Println("failed to send response:", err)
		}
		return
	}
	
	// ...
}

要解决问题 #2,你可以这样做:

type Errormessage struct {
	// 导出字段,即将其改为以大写字母开头
	Errormessage string `json:"errormessage"`
}
英文:

There are two issues with your code:

  1. You are json encoding the already json encoded error. This means that you are json encoding raw json bytes, which is the reason for the weird output.
  2. Your Errormessage struct's field is unexported. Unexported fields will not be encoded by the encoding/json package.

To fix #1 you can do:

func checkExistUser(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	fmt.Println("File Name :", r.FormValue("email"))

	result, err := db.Query("SELECT * from userDetailsss")
	if err != nil {
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		w.Header().Set("X-Content-Type-Options", "nosniff")
		w.WriteHeader(400)
		
		// use only Encode, no need to call json.Marshal
		if err := json.NewEncoder(w).Encode(Errormessage{"Error in select"}); err != nil {
			log.Println("failed to send reposnse:", err)
		}
		return
	}
	
	// ...
}

To fix #2 you can do:

type Errormessage struct {
	// export the field, i.e. change it to start with an upper case letter
	Errormessage string `json:"errormessage"`
}

huangapple
  • 本文由 发表于 2022年3月24日 01:34:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/71591621.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定