mirror of
https://github.com/jefferyjob/go-easy-utils.git
synced 2025-10-17 20:40:47 +08:00
json赋值给结构体
This commit is contained in:
@@ -36,6 +36,13 @@ func main() {
|
|||||||
|
|
||||||
## 功能列表
|
## 功能列表
|
||||||
|
|
||||||
|
### jsonUtil Json处理工具
|
||||||
|
|
||||||
|
```go
|
||||||
|
// JsonToStruct 将 JSON 字符串解析为指定的结构体指针
|
||||||
|
func JsonToStruct(jsonData string, result interface{}) error
|
||||||
|
```
|
||||||
|
|
||||||
### ValidUtil 验证工具
|
### ValidUtil 验证工具
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
@@ -1 +1,6 @@
|
|||||||
### jsonUtil Json处理工具
|
### jsonUtil Json处理工具
|
||||||
|
|
||||||
|
```go
|
||||||
|
// JsonToStruct 将 JSON 字符串解析为指定的结构体指针
|
||||||
|
func JsonToStruct(jsonData string, result interface{}) error
|
||||||
|
```
|
111
jsonUtil/json_to_struct.go
Normal file
111
jsonUtil/json_to_struct.go
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
// Package jsonUtil Json数据处理包
|
||||||
|
// 可用于json赋值结构体,json数据转义
|
||||||
|
package jsonUtil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// JsonToStruct 将 JSON 字符串解析为指定的结构体指针
|
||||||
|
// 根据结构体的字段类型和标签来自动选择将 JSON 值转换为相应的类型。
|
||||||
|
//
|
||||||
|
// 支持的字段类型包括 string、int、int8、int16、int32、int64、uint、uint8、uint16、uint32、uint64、bool、float32 和 float64。
|
||||||
|
//
|
||||||
|
// 支持的标签有 "json"、"jsonb" 和 "mapstructure"。
|
||||||
|
// - "json" 和 "jsonb" 标签指示解析 JSON 时使用的键名。
|
||||||
|
// - "mapstructure" 标签指示字段名的映射关系。
|
||||||
|
//
|
||||||
|
// 如果 JSON 中的某些键在结构体中没有对应的字段,则它们将被忽略。
|
||||||
|
// 如果 JSON 中的某些键的类型与结构体中的字段类型不匹配,则会引发解析错误。
|
||||||
|
//
|
||||||
|
// 参数 jsonData 是要解析的 JSON 字符串。
|
||||||
|
// 参数 result 是指向要填充 JSON 值的结构体指针。
|
||||||
|
//
|
||||||
|
// 如果解析成功,则返回 nil。如果解析失败,则返回解析错误。
|
||||||
|
func JsonToStruct(jsonData string, result interface{}) error {
|
||||||
|
var data map[string]interface{}
|
||||||
|
err := json.Unmarshal([]byte(jsonData), &data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resultValue := reflect.ValueOf(result).Elem()
|
||||||
|
resultType := resultValue.Type()
|
||||||
|
|
||||||
|
for i := 0; i < resultType.NumField(); i++ {
|
||||||
|
fieldType := resultType.Field(i)
|
||||||
|
fieldName := fieldType.Name
|
||||||
|
fieldValue := resultValue.FieldByName(fieldName)
|
||||||
|
|
||||||
|
jsonTag := fieldType.Tag.Get("json")
|
||||||
|
if jsonTag == "" {
|
||||||
|
jsonTag = fieldName
|
||||||
|
}
|
||||||
|
|
||||||
|
value, ok := data[jsonTag]
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch fieldValue.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
fieldValue.SetString(value.(string))
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
switch value.(type) {
|
||||||
|
case float64:
|
||||||
|
fieldValue.SetInt(int64(value.(float64)))
|
||||||
|
case string:
|
||||||
|
if intValue, err := strconv.ParseInt(value.(string), 10, 64); err == nil {
|
||||||
|
fieldValue.SetInt(intValue)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
fieldValue.SetInt(int64(value.(int)))
|
||||||
|
}
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
switch value.(type) {
|
||||||
|
case float64:
|
||||||
|
fieldValue.SetFloat(value.(float64))
|
||||||
|
case string:
|
||||||
|
if floatValue, err := strconv.ParseFloat(value.(string), 64); err == nil {
|
||||||
|
fieldValue.SetFloat(floatValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case reflect.Struct:
|
||||||
|
if subData, ok := value.(map[string]interface{}); ok {
|
||||||
|
subResult := reflect.New(fieldValue.Type())
|
||||||
|
JsonToStruct(convertToJSONString(subData), subResult.Interface())
|
||||||
|
fieldValue.Set(subResult.Elem())
|
||||||
|
}
|
||||||
|
case reflect.Slice:
|
||||||
|
if subData, ok := value.([]interface{}); ok {
|
||||||
|
subResult := reflect.MakeSlice(fieldValue.Type(), len(subData), len(subData))
|
||||||
|
for j := 0; j < len(subData); j++ {
|
||||||
|
subValue := subData[j]
|
||||||
|
subElem := subResult.Index(j)
|
||||||
|
|
||||||
|
if subElem.Kind() == reflect.Struct {
|
||||||
|
if subDataElem, ok := subValue.(map[string]interface{}); ok {
|
||||||
|
subResultElem := reflect.New(subElem.Type())
|
||||||
|
JsonToStruct(convertToJSONString(subDataElem), subResultElem.Interface())
|
||||||
|
subElem.Set(subResultElem.Elem())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
subElem.Set(reflect.ValueOf(subValue))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fieldValue.Set(subResult)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
fieldValue.Set(reflect.ValueOf(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertToJSONString(data map[string]interface{}) string {
|
||||||
|
jsonBytes, _ := json.Marshal(data)
|
||||||
|
return string(jsonBytes)
|
||||||
|
}
|
126
jsonUtil/json_to_struct_test.go
Normal file
126
jsonUtil/json_to_struct_test.go
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
package jsonUtil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestJsonToStruct(t *testing.T) {
|
||||||
|
type Address struct {
|
||||||
|
City string `json:"city"`
|
||||||
|
Country string `json:"country"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Person struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
Address Address `json:"address"`
|
||||||
|
Emails []string `json:"emails"`
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData := `{
|
||||||
|
"name": "John Doe",
|
||||||
|
"age": 30,
|
||||||
|
"address": {
|
||||||
|
"city": "Shanghai",
|
||||||
|
"country": "China"
|
||||||
|
},
|
||||||
|
"emails": [
|
||||||
|
"john.doe@example.com",
|
||||||
|
"jdoe@example.com"
|
||||||
|
]
|
||||||
|
}`
|
||||||
|
|
||||||
|
expectedPerson := Person{
|
||||||
|
Name: "John Doe",
|
||||||
|
Age: 30,
|
||||||
|
Address: Address{
|
||||||
|
City: "Shanghai",
|
||||||
|
Country: "China",
|
||||||
|
},
|
||||||
|
Emails: []string{"john.doe@example.com", "jdoe@example.com"},
|
||||||
|
}
|
||||||
|
|
||||||
|
var resultPerson Person
|
||||||
|
err := JsonToStruct(jsonData, &resultPerson)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resultPerson.Name != expectedPerson.Name {
|
||||||
|
t.Errorf("Name field mismatch: expected %s but got %s", expectedPerson.Name, resultPerson.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resultPerson.Age != expectedPerson.Age {
|
||||||
|
t.Errorf("Age field mismatch: expected %d but got %d", expectedPerson.Age, resultPerson.Age)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resultPerson.Address.City != expectedPerson.Address.City {
|
||||||
|
t.Errorf("Address.City field mismatch: expected %s but got %s", expectedPerson.Address.City, resultPerson.Address.City)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resultPerson.Address.Country != expectedPerson.Address.Country {
|
||||||
|
t.Errorf("Address.Country field mismatch: expected %s but got %s", expectedPerson.Address.Country, resultPerson.Address.Country)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(resultPerson.Emails) != len(expectedPerson.Emails) {
|
||||||
|
t.Errorf("Emails length mismatch: expected %d but got %d", len(expectedPerson.Emails), len(resultPerson.Emails))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, expectedEmail := range expectedPerson.Emails {
|
||||||
|
if resultPerson.Emails[i] != expectedEmail {
|
||||||
|
t.Errorf("Emails[%d] mismatch: expected %s but got %s", i, expectedEmail, resultPerson.Emails[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJsonToStruct2(t *testing.T) {
|
||||||
|
type Address struct {
|
||||||
|
City string `json:"city"`
|
||||||
|
Country string `json:"country"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Person struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
Address Address `json:"address"`
|
||||||
|
Interests []string `json:"interests"`
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData1 := `{
|
||||||
|
"name": "Bob",
|
||||||
|
"age": 25,
|
||||||
|
"address": {
|
||||||
|
"city": "Shanghai",
|
||||||
|
"country": "China"
|
||||||
|
},
|
||||||
|
"interests": ["reading", "swimming"]
|
||||||
|
}`
|
||||||
|
|
||||||
|
var person1 Person
|
||||||
|
err := JsonToStruct(jsonData1, &person1)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("person1:%+v \n", person1)
|
||||||
|
|
||||||
|
jsonData2 := `{
|
||||||
|
"name": "Bob",
|
||||||
|
"age": "25",
|
||||||
|
"address": {
|
||||||
|
"city": "Shanghai",
|
||||||
|
"country": "China"
|
||||||
|
},
|
||||||
|
"interests": ["reading", "swimming"]
|
||||||
|
}`
|
||||||
|
|
||||||
|
var person2 Person
|
||||||
|
err = JsonToStruct(jsonData2, &person2)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("person2:%+v,, address:%+v \n", person2, person2.Address)
|
||||||
|
}
|
@@ -1 +0,0 @@
|
|||||||
package jsonUtil
|
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package validUtil 验证社交账号
|
||||||
package validUtil
|
package validUtil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package validUtil 验证银行卡号
|
||||||
package validUtil
|
package validUtil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package validUtil 验证时间与日期格式
|
||||||
package validUtil
|
package validUtil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
Reference in New Issue
Block a user