Golang中JSON与结构体的相互转换及结构体渲染到HTML的实现
Golang中JSON与结构体的相互转换及结构体渲染到HTML的实现 我拥有以下结构体:
type Data struct {
Data1 int
Data2 int
ImpData []struct {
Title string
ID string
TextS string
}
}
我将JSON代码解组到变量 o 中
var o Data
err = json.Unmarshal(output, &o)
if err != nil {
panic(err.Error())
}
我使用一个for循环来获取数据
for i := 0; i < len(o.ImpData); i++ {
fmt.Printf(" Test: %+v", o.ImpData[i].Title)
}
到目前为止一切正常,但我不知道如何准确地使用正确的参数和数据来执行模板。
tmpl, _ := template.ParseFiles("index.html")
tmpl.Execute(w, o)
HTML:
<p style="color: black;"> {{ range .ImpData }} {{ . }}</p>
更多关于Golang中JSON与结构体的相互转换及结构体渲染到HTML的实现的实战教程也可以访问 https://www.itying.com/category-94-b0.html
感谢您的回答和帮助。
为什么您要声明两个结构体?这让我非常困惑,因为我有一个结构体嵌套在另一个结构体里。
在我的例子中,解组后的 JSON 数据在变量 o 中。
还有,为什么是 dat.ImpData?我的输出是 o.Impdata[i].Title、o.Impdata[i].TextS 等等,这些需要在 HTML 模板中渲染。
理解这个让我的大脑要栈溢出了 😄
更多关于Golang中JSON与结构体的相互转换及结构体渲染到HTML的实现的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
天啊,它真的可以运行了!非常感谢您付出的时间和提供的帮助!:slight_smile:
最后一个问题,我如何才能在 HTML 中同时渲染结构体中的 Data1、Data2 以及 ImpData?
另外,假设我有另一个独立的结构体,也想在同一个 HTML 中解析它,这该如何实现?
例如:
type OtherData struct {
OData1 int
OData2 int
BookData []struct {
Title string
ID string
TextS string
}
}
我该如何将这个结构体也渲染到同一个 HTML 中呢?
再次感谢 🙂 好的,但如果它没有相同的子记录呢?
像这样
type Data struct {
Data1 int
Data2 int
ImpData []struct {
Title string
ID string
TextS string
}
}
type OtherData struct {
OData1 int
OData2 int
BookData []struct {
Name string
ID string
Location string
}
}
我如何在同一份渲染的HTML中获取这两份数据?
还有另一件事:
我是不是需要对Data做类似这样的操作?
dat.ImpData = append(dat.ImpData etc
但这只是ImpData的数据,而不是Data的全部数据,对吗? 所以我的理解是,我也需要追加它?
Babtus2:
最后一个问题,我如何才能在HTML中同时渲染结构体中的Data1、Data2以及ImpData?
试试这个模板:
var htmlTmpl = `<h1>Data: {{ .Data1 }}</h1>
{{ range .ImpData }}
<p style="color: black;">{{ .Title }}</p>
{{ end }}`
Babtus2:
假设我有另一个独立的结构体,也想在同一个HTML中解析它,这该如何实现?
如果你有类似的数据,我建议创建一个能涵盖这两个概念的类型/结构体。这两个子记录在那个结构体上都有Title、ID和TextS,对吧?所以你可以把它提取到它自己的结构体中:
type LineItem struct {
Title string
ID string
TextS string
}
type Data struct {
Data1 int
Data2 int
ImpData []LineItem
}
type OtherData struct {
OData1 int
OData2 int
BookData []LineItem
}
这样,Data 和 OtherData 都有一个 LineItem 类型的切片。大致就是这样的思路。
为什么你要声明两个结构体?这让我非常困惑,因为我有一个结构体嵌套在另一个结构体里。
Data 包含一个 ImpData 类型的切片,而不是一个匿名结构体。我之所以这样做,是因为当你像下面这样将子结构体声明为匿名结构体时:
type Data struct {
Data1 int
Data2 int
ImpData []struct { // 这是什么类型?
Title string
ID string
TextS string
}
}
…这会使得我构造的数据初始化过程变得更加冗长:
for i := 0; i < 10; i++ {
dat.ImpData = append(dat.ImpData, struct {
Title string
ID string
TextS string
}{"test", strconv.Itoa(i), "test"})
}
但实际上效果是一样的。你可以在这里运行它,使用与你示例中完全相同的 Data 结构体:
尝试将你的模板切换成类似这样的:
{{ range .ImpData }}
<p style="color: black;">{{ .Title }}</p>
{{ end }}
这里有一个完整的示例,可以帮助你开始:
package main
import (
"html/template"
"os"
"strconv"
)
type ImpData struct {
Title string
ID string
TextS string
}
type Data struct {
Data1 int
Data2 int
ImpData []ImpData
}
var htmlTmpl = `{{ range .ImpData }}
<p style="color: black;">{{ .Title }}</p>
{{ end }}`
func main() {
// 为了简洁忽略错误。实际中不要这样做。
t := template.Must(template.New("test").Parse(htmlTmpl))
dat := Data{}
for i := 0; i < 10; i++ {
dat.ImpData = append(dat.ImpData, ImpData{Title: "test", ID: strconv.Itoa(i), TextS: "test"})
}
t.Execute(os.Stdout, dat)
}
你可以在 Go Playground 上运行它:
在Golang中实现JSON与结构体的相互转换及模板渲染,以下是完整的实现方案:
1. JSON与结构体转换
结构体定义优化(添加JSON标签)
type Data struct {
Data1 int `json:"data1"`
Data2 int `json:"data2"`
ImpData []ImpItem `json:"impData"`
}
type ImpItem struct {
Title string `json:"title"`
ID string `json:"id"`
TextS string `json:"textS"`
}
JSON反序列化
var o Data
err := json.Unmarshal(output, &o)
if err != nil {
log.Fatal("JSON解析错误:", err)
}
JSON序列化
// 结构体转JSON
jsonData, err := json.Marshal(o)
if err != nil {
log.Fatal("JSON编码错误:", err)
}
// 格式化输出
jsonIndent, _ := json.MarshalIndent(o, "", " ")
fmt.Println(string(jsonIndent))
2. 模板渲染实现
Go模板处理
func handler(w http.ResponseWriter, r *http.Request) {
// 解析模板
tmpl, err := template.ParseFiles("index.html")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// 准备数据
data := Data{
Data1: 100,
Data2: 200,
ImpData: []ImpItem{
{Title: "标题1", ID: "001", TextS: "内容1"},
{Title: "标题2", ID: "002", TextS: "内容2"},
},
}
// 执行模板渲染
err = tmpl.Execute(w, data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
HTML模板示例 (index.html)
<!DOCTYPE html>
<html>
<head>
<title>数据展示</title>
</head>
<body>
<h1>基础数据</h1>
<p>Data1: {{.Data1}}</p>
<p>Data2: {{.Data2}}</p>
<h1>重要数据列表</h1>
{{range .ImpData}}
<div style="border: 1px solid #ccc; padding: 10px; margin: 10px;">
<h3 style="color: black;">{{.Title}}</h3>
<p><strong>ID:</strong> {{.ID}}</p>
<p><strong>内容:</strong> {{.TextS}}</p>
</div>
{{else}}
<p>暂无数据</p>
{{end}}
</body>
</html>
3. 完整HTTP服务器示例
package main
import (
"encoding/json"
"html/template"
"log"
"net/http"
)
type Data struct {
Data1 int `json:"data1"`
Data2 int `json:"data2"`
ImpData []ImpItem `json:"impData"`
}
type ImpItem struct {
Title string `json:"title"`
ID string `json:"id"`
TextS string `json:"textS"`
}
func main() {
http.HandleFunc("/", renderTemplate)
log.Println("服务器启动在 :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func renderTemplate(w http.ResponseWriter, r *http.Request) {
// 模拟JSON数据
jsonStr := `{
"data1": 100,
"data2": 200,
"impData": [
{"title": "项目A", "id": "001", "textS": "这是项目A的描述"},
{"title": "项目B", "id": "002", "textS": "这是项目B的描述"}
]
}`
var o Data
err := json.Unmarshal([]byte(jsonStr), &o)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// 解析并执行模板
tmpl, err := template.ParseFiles("index.html")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
err = tmpl.Execute(w, o)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
4. 模板函数扩展
// 自定义模板函数
funcMap := template.FuncMap{
"upper": strings.ToUpper,
"add": func(a, b int) int { return a + b },
}
tmpl := template.New("index.html").Funcs(funcMap)
tmpl, _ = tmpl.ParseFiles("index.html")
// 在HTML中使用自定义函数
{{range .ImpData}}
<p>{{.Title | upper}}</p>
<p>计算值: {{add .Data1 .Data2}}</p>
{{end}}
这个实现方案提供了完整的JSON与结构体转换、模板渲染的示例,可以直接运行并查看结果。


