Golang从JSON中提取数据的详细方法

Golang从JSON中提取数据的详细方法 大家好,我是Go语言的新手。

package main

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/gorilla/websocket"
)

func main() {
	dialer := websocket.DefaultDialer
	wsSubscriber, _, err := dialer.Dial("wss://api.blxrbdn.com/ws", http.Header{"Authorization": []string{"MzVkNWIzMDgoqTNhNS00MjVjLTswN2EtZTZjOGU5N2Q3Yzk5OjFkZDhjMDZkYjk1NDcwYTQyNWI5ZmYzZTc1NDYxZWFh"}})

	if err != nil {
		fmt.Println(err)
		return
	}
	subRequest := `{"id": 1, "method": "subscribe", "params": ["newTxs", {"include": ["tx_contents"]}]}`

	err = wsSubscriber.WriteMessage(websocket.TextMessage, []byte(subRequest))
	if err != nil {
		fmt.Println(err)
		return
	}

	for {
		_, nextNotification, err := wsSubscriber.ReadMessage()
		if err != nil {
			fmt.Println(err)

		}
		fmt.Println(string(nextNotification))

	}
}

我得到以下输出: {"id":1,"result":"3b6d9090-2757-47b5-95c1-d02a7f753e45","jsonrpc":"2.0"} {"id":1,"method":"subscribe","params":{"subscription":"3b6d9090-2757-47b5-95c1-d02a7f753e45","result":{"txContents":{"accessList":[],"chainId":"0x1","from":"0x1f922a3854e8cf160b294af56f980f92f7a4409f","gas":"0x39567","hash":"0xd85de6b1a33744a0c2985945c199a83788d2309594f0f6daf6a4aaec9e9979d8","input":"0x5ae401dc0000000000000000000000000000000000000000000000000000000063218a1900000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e4472b43f300000000000000000000000000000000000000000000000000354a6ba7a180000000000000000000000000000000000000000000000000000000015134c8ea9f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000001f922a3854e8cf160b294af56f980f92f7a4409f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000008eb18e507ae851740ede9a4ce2e594b05981de6d00000000000000000000000000000000000000000000000000000000","maxFeePerGas":"0x2b02a98dc","maxPriorityFeePerGas":"0x59682f00","nonce":"0xa7","r":"0x699a733ef2c9b4e484d2f47a44b86e27cd249e9ca839dbb43ab7201a17f27656","s":"0x6cba1515c0a284ccbc722c41ecb972ed889175560217ff5970e7d64a27c526c8","to":"0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45","type":"0x2","v":"0x1","value":"0x354a6ba7a18000"}}}}

第一部分是关于我的订阅。 第二部分是 subRequest 的输出。 我需要仅输出从 "result":{"txContents":{"accessList":[],"chainId":"0x1","from":"0x1f922a3854e8cf160b294af56f980f92f7a4409f"...}}} 开始的 subRequest 中的详细信息。

我通过以下方式实现:

myResponse := make(map[string]interface{})
err2 := json.Unmarshal([]byte(nextNotification), &myResponse)
if err2 != nil {
	fmt.Println(err2)
}

	txC := myResponse["params"]

	jsonTx, _ := json.Marshal(txC)

	fmt.Println(string(jsonTx))
}

输出是: null {"result":{"txContents":{"from":"0xcac76b259ad18a269be1987c0e8a07a2b855f7b6","gas":"0xc350","gasPrice":"0x1e7a775d0","hash":"0xc21e74b18a09d0dffe0ebd581317882bcc5479448575ba44ffd4e1ef611b998d","input":"0x","nonce":"0x6d0a","r":"0xac50fe84bf5f31c11142dc349553ce1c0ba23ef10b51936032710fed8c15bf9f","s":"0x4e250ae37e452cd71386aa6c445b69076e26c514719bbab4768f1d100fbf086f","to":"0x12396dcdb6d82adb7126707f191ebcfb7d9803fb","type":"0x0","v":"0x26","value":"0x18de76816d8000"}},"subscription":"a20fe909-998b-4f7d-82ac-2f7a3c7e45a7"}

如何从输出中删除 null 并从以下内容开始输出: {"txContents:{"from":"0xcac76b259ad18a269be1987c0e8a07a2b855f7b6","gas":"0xc350","gasPrice":"0x1e7a775d0","hash":"0xc21e74b18a09d0dffe0ebd581317882bcc5479448575ba44ffd4e1ef611b998d","input":"0x","nonce":"0x6d0a","r":"0xac50fe84bf5f31c11142dc349553ce1c0ba23ef10b51936032710fed8c15bf9f","s":"0x4e250ae37e452cd71386aa6c445b69076e26c514719bbab4768f1d100fbf086f","to":"0x12396dcdb6d82adb7126707f191ebcfb7d9803fb","type":"0x0","v":"0x26","value":"0x18de76816d8000"}},"subscription":"a20fe909-998b-4f7d-82ac-2f7a3c7e45a7"}


更多关于Golang从JSON中提取数据的详细方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang从JSON中提取数据的详细方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中从JSON提取数据时,建议使用结构体定义来精确解析。以下是针对您需求的解决方案:

package main

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/gorilla/websocket"
)

// 定义完整的响应结构
type Response struct {
	ID      int             `json:"id"`
	Method  string          `json:"method"`
	Params  json.RawMessage `json:"params"`
	Result  string          `json:"result"`
	Jsonrpc string          `json:"jsonrpc"`
}

// 定义params内部结构
type Params struct {
	Subscription string          `json:"subscription"`
	Result       json.RawMessage `json:"result"`
}

// 定义txContents结构
type TxContents struct {
	AccessList           []interface{} `json:"accessList"`
	ChainID              string        `json:"chainId"`
	From                 string        `json:"from"`
	Gas                  string        `json:"gas"`
	Hash                 string        `json:"hash"`
	Input                string        `json:"input"`
	MaxFeePerGas         string        `json:"maxFeePerGas"`
	MaxPriorityFeePerGas string        `json:"maxPriorityFeePerGas"`
	Nonce                string        `json:"nonce"`
	R                    string        `json:"r"`
	S                    string        `json:"s"`
	To                   string        `json:"to"`
	Type                 string        `json:"type"`
	V                    string        `json:"v"`
	Value                string        `json:"value"`
}

// 定义result内部结构
type Result struct {
	TxContents TxContents `json:"txContents"`
}

func main() {
	dialer := websocket.DefaultDialer
	wsSubscriber, _, err := dialer.Dial("wss://api.blxrbdn.com/ws", http.Header{"Authorization": []string{"MzVkNWIzMDgoqTNhNS00MjVjLTswN2EtZTZjOGU5N2Q3Yzk5OjFkZDhjMDZkYjk1NDcwYTQyNWI5ZmYzZTc1NDYxZWFh"}})

	if err != nil {
		fmt.Println(err)
		return
	}
	subRequest := `{"id": 1, "method": "subscribe", "params": ["newTxs", {"include": ["tx_contents"]}]}`

	err = wsSubscriber.WriteMessage(websocket.TextMessage, []byte(subRequest))
	if err != nil {
		fmt.Println(err)
		return
	}

	for {
		_, nextNotification, err := wsSubscriber.ReadMessage()
		if err != nil {
			fmt.Println(err)
			continue
		}

		// 解析完整响应
		var resp Response
		err = json.Unmarshal(nextNotification, &resp)
		if err != nil {
			fmt.Println("解析响应失败:", err)
			continue
		}

		// 只处理包含params的消息
		if len(resp.Params) > 0 {
			var params Params
			err = json.Unmarshal(resp.Params, &params)
			if err != nil {
				fmt.Println("解析params失败:", err)
				continue
			}

			// 解析result字段
			if len(params.Result) > 0 {
				var result Result
				err = json.Unmarshal(params.Result, &result)
				if err != nil {
					fmt.Println("解析result失败:", err)
					continue
				}

				// 输出txContents的JSON
				txJSON, _ := json.Marshal(result.TxContents)
				fmt.Println(string(txJSON))
			}
		}
	}
}

如果您只需要输出特定格式,可以使用更简洁的方法:

// 方法2:使用匿名结构体直接提取
for {
	_, nextNotification, err := wsSubscriber.ReadMessage()
	if err != nil {
		fmt.Println(err)
		continue
	}

	var data map[string]interface{}
	err = json.Unmarshal(nextNotification, &data)
	if err != nil {
		fmt.Println(err)
		continue
	}

	// 检查是否有params字段
	if params, ok := data["params"].(map[string]interface{}); ok {
		if result, ok := params["result"].(map[string]interface{}); ok {
			if txContents, ok := result["txContents"].(map[string]interface{}); ok {
				txJSON, _ := json.Marshal(txContents)
				fmt.Println(string(txJSON))
			}
		}
	}
}

要输出包含subscription的完整结构:

// 方法3:输出包含subscription的结构
for {
	_, nextNotification, err := wsSubscriber.ReadMessage()
	if err != nil {
		fmt.Println(err)
		continue
	}

	var resp struct {
		Params struct {
			Subscription string `json:"subscription"`
			Result       struct {
				TxContents map[string]interface{} `json:"txContents"`
			} `json:"result"`
		} `json:"params"`
	}

	err = json.Unmarshal(nextNotification, &resp)
	if err != nil {
		// 跳过订阅确认消息
		continue
	}

	// 检查是否有数据
	if len(resp.Params.Subscription) > 0 && resp.Params.Result.TxContents != nil {
		output := map[string]interface{}{
			"txContents":   resp.Params.Result.TxContents,
			"subscription": resp.Params.Subscription,
		}
		
		outputJSON, _ := json.Marshal(output)
		fmt.Println(string(outputJSON))
	}
}

这些方法可以避免输出null,并精确提取您需要的JSON数据。

回到顶部