How to create a struct with different structs of one members of struct in go?

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

How to create a struct with different structs of one members of struct in go?

问题

在解析登录响应时,可以将loginData结构添加到response结构的RespData字段中。类似地,在解析用户数据响应时,可以将userdata结构添加到response结构的RespData字段中。

以下是示例代码:

type loginData struct {
    Token        string `json:"token"`
    RefreshToken string `json:"refresh-token"`
}

type userdata struct {
    FirstName string `json:"first-name"`
    LastName  string `json:"last-name"`
    Age       string `json:"age"`
    Phone     string `json:"phone"`
    Address   string `json:"address"`
}

type response struct {
    Status      string      `json:"status"`
    ErrorCode   string      `json:"error-code"`
    RespMessage string      `json:"message"`
    RespData    interface{} `json:"data"`
}

// 解析登录响应
loginResponse := response{}
err := json.Unmarshal([]byte(loginResponseJSON), &loginResponse)
if err != nil {
    // 处理解析错误
}

// 检查响应状态
if loginResponse.Status == "success" {
    // 解析登录数据
    loginData := loginData{}
    loginDataJSON, err := json.Marshal(loginResponse.RespData)
    if err != nil {
        // 处理解析错误
    }
    err = json.Unmarshal(loginDataJSON, &loginData)
    if err != nil {
        // 处理解析错误
    }
    // 使用登录数据
    fmt.Println("Token:", loginData.Token)
    fmt.Println("Refresh Token:", loginData.RefreshToken)
}

// 解析用户数据响应
userDataResponse := response{}
err = json.Unmarshal([]byte(userDataResponseJSON), &userDataResponse)
if err != nil {
    // 处理解析错误
}

// 检查响应状态
if userDataResponse.Status == "success" {
    // 解析用户数据
    userData := userdata{}
    userDataJSON, err := json.Marshal(userDataResponse.RespData)
    if err != nil {
        // 处理解析错误
    }
    err = json.Unmarshal(userDataJSON, &userData)
    if err != nil {
        // 处理解析错误
    }
    // 使用用户数据
    fmt.Println("First Name:", userData.FirstName)
    fmt.Println("Last Name:", userData.LastName)
    fmt.Println("Age:", userData.Age)
    fmt.Println("Phone:", userData.Phone)
    fmt.Println("Address:", userData.Address)
}

在上面的代码中,我们首先将响应JSON解析到response结构中。然后,我们检查响应状态是否为"success",如果是,则将RespData字段的值解析为相应的结构(loginDatauserdata)。最后,我们可以使用解析后的数据进行进一步的处理。

英文:

I am getting a json response from a server with three fix json object field and one field with different json objects.

Example - Response 1

{
status : "success",
error-code : "",
message : "login successful",
data : {
token : "token value",
refresh-token : "refresh token value"
}
}

Example - Response 2

{
status : "success",
error-code : "",
message : "user data fetched",
data : {
first-name: "josh",
last-name : "walter",
age : "30",
phone: 1234567890,
address : "x street, dc"
}
}

for above json response created struct as follows

type loginData struct {
Token string `json:"token"`
RefreshToken string `json:"refresh-token"`
}
type userdata {
FirstName string    `json:"first-name"`
LastName string     `json:"refresh-token"`
Age string          `json:"age"`
Phone string        `json:"phone"`
Address string      `json:"address"`
}
type response struct {
Status string       `json:"status"`
ErrorCode string    `json:"error-code"`
RespMessage string  `json:"message"`
RespData string     `json:"data"`
}

How to add logindata struct while unmarshaling during login response and userdata struct while unmarshaling userdata response in "RespData" field in response struct

答案1

得分: 2

首先,更改RespData字段的类型:

type response struct {
    Status      string      `json:"status"`
    ErrorCode   string      `json:"error-code"`
    RespMessage string      `json:"message"`
    RespData    interface{} `json:"data"`
}

然后,根据您所发出的请求,将RespData字段设置为预分配的指向预期类型的指针实例:

r, err := http.Get("https://some_api.com/loginData")
if err != nil {
    return err
}
defer r.Body.Close()

// 检查 r.StatusCode 并确保它是正确的

data := loginData{}
resp := response{RespData: &data}
if err := json.NewDecoder(r.Body).Decode(&resp); err != nil {
    return err
}

fmt.Println(data)
英文:

First change the RespData field's type:

type response struct {
    Status      string      `json:"status"`
    ErrorCode   string      `json:"error-code"`
    RespMessage string      `json:"message"`
    RespData    interface{} `json:"data"`
}

Then, depending on what request you are making, set the RespData field to a pre-allocated instance of a pointer to the expected type:

r, err := http.Get("https://some_api.com/loginData")
if err != nil {
    return err
}
defer r.Body.Close()

// check r.StatusCode and make sure it's correct

data := loginData{}
resp := response{RespData: &data}
if err := json.NewDecoder(r.Body).Decode(&resp); err != nil {
    return err
}

fmt.Println(data)

答案2

得分: 0

根据我的理解,你应该使用两个不同的structs来完成这个任务。一个原因是关注点的分离,因为这些响应的结构可能在将来发生变化,并且这些响应来自两个不同的API,所以最好维护不同的响应对象。

type loginData struct {
	Token        string `json:"token"`
	RefreshToken string `json:"refresh-token"`
}

type userdata struct {
	FirstName string `json:"first-name"`
	LastName  string `json:"refresh-token"`
	Age       string `json:"age"`
	Phone     string `json:"phone"`
	Address   string `json:"address"`
}

type response struct {
	Status      string `json:"status"`
	ErrorCode   string `json:"error-code"`
	RespMessage string `json:"message"`
}

type userResponse struct {
	response
	RespData userdata `json:"data"`
}

type loginResponse struct {
	response
	RespData loginData `json:"data"`
}
英文:

According to me, you should have two different structs to do this. One reason is separation of concern, as the structure of these responses may change in the future and these are responses from two different apis so its better to maintain different response objects.

type loginData struct {
	Token        string `json:"token"`
	RefreshToken string `json:"refresh-token"`
}

type userdata struct {
	FirstName string `json:"first-name"`
	LastName  string `json:"refresh-token"`
	Age       string `json:"age"`
	Phone     string `json:"phone"`
	Address   string `json:"address"`
}

type response struct {
	Status      string `json:"status"`
	ErrorCode   string `json:"error-code"`
	RespMessage string `json:"message"`
}

type userResponse struct {
	response
	RespData userdata `json:"data"`
}

type loginResponse struct {
	response
	RespData loginData `json:"data"`
}

答案3

得分: 0

package main

import (
	"encoding/json"
	"fmt"
	"strings"
)

type loginData struct {
	Token        string `json:"token"`
	RefreshToken string `json:"refresh-token"`
}

type userdata struct {
	FirstName string `json:"first-name"`
	LastName  string `json:"last-name"`
	Age       string `json:"age"`
	Phone     string `json:"phone"`
	Address   string `json:"address"`
}

type response struct {
	Status      string      `json:"status"`
	ErrorCode   string      `json:"error-code"`
	RespMessage string      `json:"message"`
	RespData    interface{} `json:"data"`
}

func main() {
	jsonresp_1 := `{
		"status" : "success",
		"error-code" : "",
		"message" : "login successful",
		"data" : {
				"token" : "token value",
				"refresh-token" : "refresh token value"
			   }
	 }`

	jsonresp_2 := `{
		"status" : "success",
		"error-code" : "",
		"message" : "user data fetched",
		"data" : {
				"first-name": "josh",
				"last-name" : "walter",
				"age" : "30",
				"phone": "1234567890",
				"address" : "x street, dc"
			   }
	 }`
	resp1 := strings.NewReader(jsonresp_1)
	data1 := loginData{}
	respdata1 := response{RespData: &data1}

	if err := json.NewDecoder(resp1).Decode(&respdata1); err != nil {
		fmt.Println(err)
	}
	fmt.Printf("token : %s \nrefreshtoken : %s \n", data1.Token, data1.RefreshToken)

	fmt.Println("-------------------")

	resp2 := strings.NewReader(jsonresp_2)
	data2 := userdata{}
	respdata2 := response{RespData: &data2}

	if err := json.NewDecoder(resp2).Decode(&respdata2); err != nil {
		fmt.Println(err)
	}
	fmt.Printf("firstname : %s \nlastname : %s ", data2.FirstName, data2.LastName)
}

输出

⚡ ⇒  go run main.go 
token : token value 
refreshtoken : refresh token value 
-------------------
firstname : josh 
lastname : walter
英文:

@mkopriva as you said tried this suggestion it worked.

package main

import (
	"encoding/json"
	"fmt"
	"strings"
)

type loginData struct {
	Token        string `json:"token"`
	RefreshToken string `json:"refresh-token"`
}

type userdata struct {
	FirstName string `json:"first-name"`
	LastName  string `json:"last-name"`
	Age       string `json:"age"`
	Phone     string `json:"phone"`
	Address   string `json:"address"`
}

type response struct {
	Status      string      `json:"status"`
	ErrorCode   string      `json:"error-code"`
	RespMessage string      `json:"message"`
	RespData    interface{} `json:"data"`
}

func main() {
	jsonresp_1 := `{
		"status" : "success",
		"error-code" : "",
		"message" : "login successful",
		"data" : {
				"token" : "token value",
				"refresh-token" : "refresh token value"
			   }
	 }`

	jsonresp_2 := `{
		"status" : "success",
		"error-code" : "",
		"message" : "user data fetched",
		"data" : {
				"first-name": "josh",
				"last-name" : "walter",
				"age" : "30",
				"phone": "1234567890",
				"address" : "x street, dc"
			   }
	 }`
	resp1 := strings.NewReader(jsonresp_1)
	data1 := loginData{}
	respdata1 := response{RespData: &data1}

	if err := json.NewDecoder(resp1).Decode(&respdata1); err != nil {
		fmt.Println(err)
	}
	fmt.Printf("token : %s \nrefreshtoken : %s \n", data1.Token, data1.RefreshToken)

	fmt.Println("-------------------")

	resp2 := strings.NewReader(jsonresp_2)
	data2 := userdata{}
	respdata2 := response{RespData: &data2}

	if err := json.NewDecoder(resp2).Decode(&respdata2); err != nil {
		fmt.Println(err)
	}
	fmt.Printf("firstname : %s \nlastname : %s ", data2.FirstName, data2.LastName)
}

Output

⚡ ⇒  go run main.go 
token : token value 
refreshtoken : refresh token value 
-------------------
firstname : josh 
lastname : walter

huangapple
  • 本文由 发表于 2022年2月22日 00:30:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/71209800.html
匿名

发表评论

匿名网友

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

确定