JSON रिस्पॉन्स में फ़ील्ड्स को स्ट्रक्चर से हटाना या उन्हें छिपाना


181

मैंने गो में एक एपीआई बनाया है, जिसे कॉल करने पर, एक क्वेरी करता है, एक संरचना का एक उदाहरण बनाता है, और फिर कॉल करने वाले को वापस भेजने से पहले उस संरचना को JSON के रूप में एन्कोड करता है। मैं अब कॉल करने वाले को उन विशिष्ट क्षेत्रों का चयन करने में सक्षम होना चाहता हूं, जिन्हें वे "फ़ील्ड" जीईटी पैरामीटर में पास करके लौटना चाहते हैं।

इसका मतलब है कि खेतों के मूल्य के आधार पर, मेरी संरचना बदल जाएगी। क्या किसी संरचना से खेतों को हटाने का कोई तरीका है? या कम से कम उन्हें JSON प्रतिक्रिया में गतिशील रूप से छिपाएं? (ध्यान दें: कभी-कभी मेरे पास खाली मान होते हैं इसलिए JSON omitEmpty टैग यहां काम नहीं करेगा) यदि इनमें से कोई भी संभव नहीं है, तो क्या इसे संभालने के लिए बेहतर तरीके पर कोई सुझाव है? अग्रिम में धन्यवाद।

मेरे द्वारा उपयोग किए जा रहे स्ट्रक्चर्स का एक छोटा संस्करण नीचे दिया गया है:

type SearchResult struct {
    Date        string      `json:"date"`
    IdCompany   int         `json:"idCompany"`
    Company     string      `json:"company"`
    IdIndustry  interface{} `json:"idIndustry"`
    Industry    string      `json:"industry"`
    IdContinent interface{} `json:"idContinent"`
    Continent   string      `json:"continent"`
    IdCountry   interface{} `json:"idCountry"`
    Country     string      `json:"country"`
    IdState     interface{} `json:"idState"`
    State       string      `json:"state"`
    IdCity      interface{} `json:"idCity"`
    City        string      `json:"city"`
} //SearchResult

type SearchResults struct {
    NumberResults int            `json:"numberResults"`
    Results       []SearchResult `json:"results"`
} //type SearchResults

मैं तो सांकेतिक शब्दों में बदलना और उत्पादन की तरह प्रतिक्रिया:

err := json.NewEncoder(c.ResponseWriter).Encode(&msg)

7
@ जेकॉब, पुकारिटोबीओ के अद्यतन उत्तर के अनुसार, मुझे लगता है कि आप प्रश्न को गलत पढ़ते हैं। (वर्तमान में) स्वीकृत आपके प्रश्न का "सही उत्तर" नहीं हो सकता है , लेकिन यहाँ पूछे जाने वाले के लिए है! (वर्तमान में) उच्चतम मतदान का जवाब आपके प्रश्न का उत्तर दे सकता है, लेकिन यह पूरी तरह से अनुपयुक्त है!
डेव सी

जवाबों:


275

संपादित करें: मैंने कुछ डाउनवोट्स पर ध्यान दिया और इस प्रश्नोत्तर पर एक और नज़र डाली। अधिकांश लोगों को यह याद आ रहा है कि ओपी ने फोन करने वालों को खेतों की सूची के आधार पर गतिशील रूप से चुने जाने के लिए कहा है । आप इसे सांख्यिकीय रूप से परिभाषित जसन स्ट्रक्चर टैग के साथ नहीं कर सकते।

यदि आप जो चाहते हैं, वह हमेशा एक क्षेत्र को json-encode पर छोड़ना है, तो निश्चित रूप json:"-"से फ़ील्ड को अनदेखा करने के लिए उपयोग करें (यह भी ध्यान दें कि यह नहीं है यदि आपका फ़ील्ड unexported है तो आवश्यक है - उन फ़ील्ड्स को हमेशा json एनकोडर द्वारा अनदेखा किया जाता है)। लेकिन यह ओपी का सवाल नहीं है।

json:"-"उत्तर पर टिप्पणी उद्धृत करने के लिए :

यह [ json:"-"उत्तर] वह उत्तर है जो अधिकांश लोग खोज से यहां समाप्त करना चाहते हैं, लेकिन यह प्रश्न का उत्तर नहीं है।


मैं इस मामले में एक संरचना के बजाय एक नक्शे [स्ट्रिंग] इंटरफ़ेस {} का उपयोग करता हूं। आप आसानी से कॉल करके फ़ील्ड निकाल सकते हैंdelete बिल्ट-इन मैप पर ।

यही है, यदि आप केवल पहली जगह में अनुरोधित फ़ील्ड के लिए क्वेरी नहीं कर सकते हैं।


4
आप सबसे अधिक संभावना है कि अपने प्रकार की परिभाषा को पूरी तरह से फेंकना नहीं चाहते हैं। वह लाइन से परेशान होने वाला है, जैसे कि जब आप इस प्रकार के अन्य तरीकों को लिखना चाहते हैं जो उन क्षेत्रों तक पहुंचते हैं। इंटरमीडिएट का उपयोग करने का कोई map[string]interface{}मतलब नहीं है, लेकिन इसकी आवश्यकता नहीं है कि आप अपनी प्रकार की परिभाषा को फेंक दें।
jorelli

1
अन्य उत्तर इस प्रश्न का वास्तविक उत्तर है।
याकूब

1
हटाए जाने का एक संभावित दोष यह है कि आप कभी-कभी अपनी संरचना (मानचित्र) के कई json विचारों का समर्थन करना चाह सकते हैं। उदाहरण के लिए एक संवेदनशील क्षेत्र के बिना क्लाइंट के लिए json दृश्य, और संवेदनशील क्षेत्र के साथ डेटाबेस के लिए json दृश्य। सौभाग्य से संरचना का उपयोग करना अभी भी संभव है - बस मेरे जवाब पर एक नज़र है।
एडम कुर्कविक्ज़

यह मेरे लिए काम करता है क्योंकि मुझे केवल एक विशिष्ट की आवश्यकता थी Idलेकिन, पूरे जसन संरचना को वापस नहीं करना चाहता। इसके लिए धन्यवाद!
लूई मिरांडा

155

`json:" - "` का उपयोग करें

// Field is ignored by this package.
Field int `json:"-"`

// Field appears in JSON as key "myName".
Field int `json:"myName"`

// Field appears in JSON as key "myName" and
// the field is omitted from the object if its value is empty,
// as defined above.
Field int `json:"myName,omitempty"`

// Field appears in JSON as key "Field" (the default), but
// the field is skipped if empty.
// Note the leading comma.
Field int `json:",omitempty"`

doc: http://golang.org/pkg/encoding/json/#Marshal


14
मैं @ जेकॉब से असहमत था क्योंकि ओपी ने कहा कि वे एपीआई को क्वेरी स्ट्रिंग प्रविष्टियों के आधार पर उत्पादन क्षेत्रों को गतिशील रूप से नियंत्रित करना चाहते थे। उदाहरण के लिए, यदि एपीआई को कॉल करने वाला केवल उद्योग और देश के लिए पूछता है, तो आपको बाकी को हटाने की आवश्यकता होगी। यही कारण है कि "टिक" जवाब इस प्रश्न के उत्तर के रूप में चिह्नित है। यह अत्यधिक मतदान वाला उत्तर स्पष्ट रूप से उपलब्ध-से-किसी भी बिल्ड-जॉन्सन-मार्शेलर - कभी भी फ़ील्ड को चिह्नित करने के लिए नहीं है। यदि आप इसे गतिशील रूप से चाहते हैं, तो टिक किया हुआ उत्तर ही उत्तर है।
eduncan911

11
यह जवाब है कि ज्यादातर लोग खोज करना चाहते हैं, लेकिन यह सवाल का जवाब नहीं है।
फिलिप हगलुंड

5
जैसा कि पहले ही कहा जा चुका है कि ओपी गतिशील रूप से डीटीओ बनाने की विधि पूछ रहा था।
कोडप्रुश

53

ऐसा करने का एक और तरीका है टैग के साथ पॉइंटर्स की एक संरचना होना ,omitempty। यदि बिंदु शून्य हैं , तो फ़ील्ड मार्शल नहीं होंगे।

इस पद्धति में नक्शे के अतिरिक्त प्रतिबिंब या अक्षम उपयोग की आवश्यकता नहीं होगी।

इस विधि का उपयोग कर जेली के रूप में एक ही उदाहरण: http://play.golang.org/p/JJNa0m2_nw


3
+1 पूरी तरह से सहमत हैं। मैं इस नियम / चाल का उपयोग हर समय अंतर्निहित मार्शलों के साथ करता हूं (और इस नियम के आधार पर CSV रीडर / लेखक भी बनाया है! - मैं ओपन-सोर्स कर सकता हूं कि जितनी जल्दी एक और सीएसवी गो पैकेज हो)। ओपी तब केवल * देश मूल्य को शून्य पर सेट नहीं कर सकता था, और इसे छोड़ दिया जाएगा। और कमाल है कि आप एक अच्छा आपूर्ति की; वाई टाइप play.golang के रूप में अच्छी तरह से।
eduncan911

2
बेशक उस विधि को प्रतिबिंब की आवश्यकता होती है, स्टैडलिब का जसन-टू-स्ट्रक्चर मार्शलिंग हमेशा प्रतिबिंब का उपयोग करता है (वास्तव में यह हमेशा प्रतिबिंब अवधि, मानचित्र या संरचना या जो भी उपयोग करता है)।
mna

हां, लेकिन इसे इंटरफेस का उपयोग करके अतिरिक्त प्रतिबिंब की आवश्यकता नहीं है , जो कुछ अन्य उत्तर सुझाते हैं।
ड्रूस्का

14

आप reflectफ़ील्ड का चयन करने के लिए पैकेज का उपयोग कर सकते हैं जिसे आप फ़ील्ड टैग पर प्रतिबिंबित करके और jsonटैग मानों का चयन करके चाहते हैं। टाइप कि चयन एक जैसे क्षेत्रों आप चाहते हैं और उन्हें रिटर्न अपने खोज परिणाम पर एक विधि को परिभाषित करें map[string]interface{}, और उसके बाद मार्शल कि बजाय खोज परिणाम ही struct। आप इस पद्धति को कैसे परिभाषित कर सकते हैं, इसका एक उदाहरण इस प्रकार है:

func fieldSet(fields ...string) map[string]bool {
    set := make(map[string]bool, len(fields))
    for _, s := range fields {
        set[s] = true
    }
    return set
}

func (s *SearchResult) SelectFields(fields ...string) map[string]interface{} {
    fs := fieldSet(fields...)
    rt, rv := reflect.TypeOf(*s), reflect.ValueOf(*s)
    out := make(map[string]interface{}, rt.NumField())
    for i := 0; i < rt.NumField(); i++ {
        field := rt.Field(i)
        jsonKey := field.Tag.Get("json")
        if fs[jsonKey] {
            out[jsonKey] = rv.Field(i).Interface()
        }
    }
    return out
}

और यहाँ एक रन करने योग्य समाधान है जो दिखाता है कि आप इस विधि को कैसे कॉल करेंगे और आपके चयन को मार्शल करेंगे: http://play.golang.org/p/1K9xjQRnO8


इसके बारे में सोचने के लिए, आप चुनिंदा फ़ील्ड्स को किसी भी प्रकार और किसी भी टैग कुंजी के लिए सामान्य रूप से सामान्य कर सकते हैं; इस बारे में कुछ भी नहीं है जो SearchResult परिभाषा या json कुंजी के लिए विशिष्ट है।
जोराली

मैं प्रतिबिंब से दूर रहने की कोशिश कर रहा हूं, लेकिन यह प्रकार की जानकारी को बहुत अच्छी तरह से बचाता है ... यह कोड के लिए अच्छा है कि दस्तावेज़ क्या आपकी संरचनाओं को एक मान्य () विधि में (यदि आप भी टैग करते हैं तो) एक है)
अक्ताउ

7

मैंने सिर्फ शेरिफ प्रकाशित किया है , जो संरचनात्मक क्षेत्रों पर एनोटेट किए गए टैग के आधार पर संरचनाओं को एक नक्शे में बदल देता है। फिर आप जनरेटेड मैप को मार्शल (JSON या अन्य) कर सकते हैं। यह संभवतः आपको कॉल करने वाले फ़ील्ड के सेट को केवल सीरियल करने की अनुमति नहीं देता है, लेकिन मुझे लगता है कि समूहों के सेट का उपयोग करने से आपको कई मामलों को कवर करने की अनुमति मिलेगी। खेतों के बजाय सीधे समूहों का उपयोग करने से सबसे अधिक संभावना कैश-क्षमता में भी वृद्धि होगी।

उदाहरण:

package main

import (
    "encoding/json"
    "fmt"
    "log"

    "github.com/hashicorp/go-version"
    "github.com/liip/sheriff"
)

type User struct {
    Username string   `json:"username" groups:"api"`
    Email    string   `json:"email" groups:"personal"`
    Name     string   `json:"name" groups:"api"`
    Roles    []string `json:"roles" groups:"api" since:"2"`
}

func main() {
    user := User{
        Username: "alice",
        Email:    "alice@example.org",
        Name:     "Alice",
        Roles:    []string{"user", "admin"},
    }

    v2, err := version.NewVersion("2.0.0")
    if err != nil {
        log.Panic(err)
    }

    o := &sheriff.Options{
        Groups:     []string{"api"},
        ApiVersion: v2,
    }

    data, err := sheriff.Marshal(o, user)
    if err != nil {
        log.Panic(err)
    }

    output, err := json.MarshalIndent(data, "", "  ")
    if err != nil {
        log.Panic(err)
    }
    fmt.Printf("%s", output)
}

7

तीन सामग्री लें:

  1. reflectएक संरचना के सभी क्षेत्रों पर लूप का पैकेज।

  2. ifउन फ़ील्ड्स को चुनने के लिए एक बयान जो आप चाहते हैं Marshal, और

  3. encoding/jsonकरने के लिए पैकेज Marshalको अपनी पसंद के क्षेत्र।

तैयारी:

  1. उन्हें एक अच्छे अनुपात में ब्लेंड करें। reflect.TypeOf(your_struct).Field(i).Name()के iवें क्षेत्र का नाम पाने के लिए उपयोग करें your_struct

  2. के एक वें क्षेत्र का reflect.ValueOf(your_struct).Field(i)एक प्रकार का Valueप्रतिनिधित्व प्राप्त करने के लिए उपयोग करें ।iyour_struct

  3. fieldValue.Interface()वास्तविक मान प्राप्त करने के लिए उपयोग करें (टाइप किए गए इंटरफ़ेस {} fieldValueका प्रकार) Value(ब्रैकेट के उपयोग पर ध्यान दें - इंटरफ़ेस) विधि का उत्पादन करता हैinterface{}

यदि आप इस प्रक्रिया में किसी भी ट्रांजिस्टर या सर्किट-ब्रेकर को जलाने का सौभाग्य नहीं लेते हैं, तो आपको कुछ इस तरह से मिलना चाहिए:

func MarshalOnlyFields(structa interface{},
    includeFields map[string]bool) (jsona []byte, status error) {
    value := reflect.ValueOf(structa)
    typa := reflect.TypeOf(structa)
    size := value.NumField()
    jsona = append(jsona, '{')
    for i := 0; i < size; i++ {
        structValue := value.Field(i)
        var fieldName string = typa.Field(i).Name
        if marshalledField, marshalStatus := json.Marshal((structValue).Interface()); marshalStatus != nil {
            return []byte{}, marshalStatus
        } else {
            if includeFields[fieldName] {
                jsona = append(jsona, '"')
                jsona = append(jsona, []byte(fieldName)...)
                jsona = append(jsona, '"')
                jsona = append(jsona, ':')
                jsona = append(jsona, (marshalledField)...)
                if i+1 != len(includeFields) {
                    jsona = append(jsona, ',')
                }
            }
        }
    }
    jsona = append(jsona, '}')
    return
}

सेवित:

map[string]boolउदाहरण के लिए, एक मनमाना संरचना और उन क्षेत्रों की सेवा करें जिन्हें आप शामिल करना चाहते हैं

type magic struct {
    Magic1 int
    Magic2 string
    Magic3 [2]int
}

func main() {
    var magic = magic{0, "tusia", [2]int{0, 1}}
    if json, status := MarshalOnlyFields(magic, map[string]bool{"Magic1": true}); status != nil {
        println("error")
    } else {
        fmt.Println(string(json))
    }

}

बॉन एपेतीत!


चेतावनी! यदि आपके शामिल फ़ील्ड में फ़ील्ड नाम शामिल हैं, जो वास्तविक फ़ील्ड से मेल नहीं खाते हैं, तो आपको एक अमान्य json मिलने वाला है। आपको चेतावनी दी गई है।
एडम कुर्कविक्ज़

5

आप टैगिंग विशेषता "omitifempty" का उपयोग कर सकते हैं या वैकल्पिक फ़ील्ड पॉइंटर्स बना सकते हैं और उन लोगों को छोड़ सकते हैं जिन्हें आप अनइंस्टॉल करना चाहते हैं।


यह ओपी प्रश्न और उपयोग के मामले का सबसे सही उत्तर है।
user1943442

2
@ user1943442, ऐसा नहीं है; ओपी स्पष्ट रूप से उल्लेख करता है कि "ओमिटेमेट्टी" अनुचित क्यों है।
डेव सी

2

मुझे इस समस्या का भी सामना करना पड़ा, सबसे पहले मैं सिर्फ अपने http हैंडलर में प्रतिक्रियाओं को माहिर करना चाहता था। मेरा पहला दृष्टिकोण एक पैकेज बना रहा था जो एक संरचना की जानकारी को किसी अन्य संरचना की नकल करता है और फिर दूसरी संरचना को मार्शल करता है। मैंने उस पैकेज का उपयोग प्रतिबिंब के रूप में किया, इसलिए, उस दृष्टिकोण को कभी पसंद नहीं किया और यह भी कि मैं गतिशील रूप से नहीं था।

इसलिए मैंने ऐसा करने के लिए एन्कोडिंग / जसन पैकेज को संशोधित करने का निर्णय लिया। कार्यों Marshal, MarshalIndentऔर (Encoder) Encodeइसके अतिरिक्त एक प्राप्त करता है

type F map[string]F

मैं उन खेतों के JSON का अनुकरण करना चाहता था जो मार्शल की जरूरत है, इसलिए यह केवल उन क्षेत्रों को मार्शल करता है जो नक्शे में हैं।

https://github.com/JuanTorr/jsont

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/JuanTorr/jsont"
)

type SearchResult struct {
    Date        string      `json:"date"`
    IdCompany   int         `json:"idCompany"`
    Company     string      `json:"company"`
    IdIndustry  interface{} `json:"idIndustry"`
    Industry    string      `json:"industry"`
    IdContinent interface{} `json:"idContinent"`
    Continent   string      `json:"continent"`
    IdCountry   interface{} `json:"idCountry"`
    Country     string      `json:"country"`
    IdState     interface{} `json:"idState"`
    State       string      `json:"state"`
    IdCity      interface{} `json:"idCity"`
    City        string      `json:"city"`
} //SearchResult

type SearchResults struct {
    NumberResults int            `json:"numberResults"`
    Results       []SearchResult `json:"results"`
} //type SearchResults
func main() {
    msg := SearchResults{
        NumberResults: 2,
        Results: []SearchResult{
            {
                Date:        "12-12-12",
                IdCompany:   1,
                Company:     "alfa",
                IdIndustry:  1,
                Industry:    "IT",
                IdContinent: 1,
                Continent:   "america",
                IdCountry:   1,
                Country:     "México",
                IdState:     1,
                State:       "CDMX",
                IdCity:      1,
                City:        "Atz",
            },
            {
                Date:        "12-12-12",
                IdCompany:   2,
                Company:     "beta",
                IdIndustry:  1,
                Industry:    "IT",
                IdContinent: 1,
                Continent:   "america",
                IdCountry:   2,
                Country:     "USA",
                IdState:     2,
                State:       "TX",
                IdCity:      2,
                City:        "XYZ",
            },
        },
    }
    fmt.Println(msg)
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

        //{"numberResults":2,"results":[{"date":"12-12-12","idCompany":1,"idIndustry":1,"country":"México"},{"date":"12-12-12","idCompany":2,"idIndustry":1,"country":"USA"}]}
        err := jsont.NewEncoder(w).Encode(msg, jsont.F{
            "numberResults": nil,
            "results": jsont.F{
                "date":       nil,
                "idCompany":  nil,
                "idIndustry": nil,
                "country":    nil,
            },
        })
        if err != nil {
            log.Fatal(err)
        }
    })

    http.ListenAndServe(":3009", nil)
}

मैंने अभी तक इसकी कोशिश नहीं की है, लेकिन यह बहुत अच्छा लग रहा है। यह और भी बेहतर होगा अगर मार्शल इंटरफ़ेस को भी समर्थन दिया जाए।
होगी

1

सवाल अब थोड़ा पुराना है, लेकिन मैं थोड़ी देर पहले उसी मुद्दे पर आया था, और जैसा कि मुझे ऐसा करने का कोई आसान तरीका नहीं मिला, मैंने इस उद्देश्य को पूरा करने वाला एक पुस्तकालय बनाया। यह map[string]interface{}एक स्थिर संरचना से आसानी से उत्पन्न करने की अनुमति देता है ।

https://github.com/tuvistavie/structomap


अब आप आसानी से मेरे नुस्खा से एक कोड स्निपेट का उपयोग कर सकते हैं।
एडम कुर्कविक्ज़ जूल

स्निपेट पुस्तकालय का एक सबसेट है, लेकिन यहां लौटने के बारे में एक प्रमुख मुद्दा []byteयह है कि यह बहुत पुन: प्रयोज्य नहीं है: उदाहरण के लिए बाद में एक क्षेत्र जोड़ने का कोई आसान तरीका नहीं है। इसलिए मैं एक map[string]interface{}मानक पुस्तकालय में JSON क्रमांकन भाग बनाने के लिए सुझाव दूंगा।
डैनियल पेरेज़

1

मैं एक ही समस्या है, लेकिन समान नहीं था। नीचे कोड आपकी समस्या को हल करता है, निश्चित रूप से अगर आपको प्रदर्शन की समस्या नहीं है। अपने सिस्टम के उस तरह के समाधान को लागू करने से पहले मैं आपको अपनी संरचना को फिर से डिज़ाइन करने की सलाह देता हूं यदि आप कर सकते हैं। चर संरचना प्रतिक्रिया भेजना अति-अभियांत्रिकी है। मेरा मानना ​​है कि एक प्रतिक्रिया संरचना एक अनुरोध और संसाधन के बीच एक अनुबंध का प्रतिनिधित्व करती है और इसे अनुरोधों पर निर्भर नहीं होना चाहिए। (आप संयुक्त राष्ट्र के वांछित क्षेत्र को अशक्त बना सकते हैं, मैं करता हूं)। कुछ मामलों में हमें इस डिज़ाइन को लागू करना होगा, अगर आपको लगता है कि आप उन मामलों में हैं, तो यहां प्ले लिंक और कोड I का उपयोग किया गया है।

type User2 struct {
    ID       int    `groups:"id" json:"id,omitempty"`
    Username string `groups:"username" json:"username,omitempty"`
    Nickname string `groups:"nickname" json:"nickname,omitempty"`
}

type User struct {
    ID       int    `groups:"private,public" json:"id,omitempty"`
    Username string `groups:"private" json:"username,omitempty"`
    Nickname string `groups:"public" json:"nickname,omitempty"`
}

var (
    tagName = "groups"
)

//OmitFields sets fields nil by checking their tag group value and access control tags(acTags)
func OmitFields(obj interface{}, acTags []string) {
    //nilV := reflect.Value{}
    sv := reflect.ValueOf(obj).Elem()
    st := sv.Type()
    if sv.Kind() == reflect.Struct {
        for i := 0; i < st.NumField(); i++ {
            fieldVal := sv.Field(i)
            if fieldVal.CanSet() {
                tagStr := st.Field(i).Tag.Get(tagName)
                if len(tagStr) == 0 {
                    continue
                }
                tagList := strings.Split(strings.Replace(tagStr, " ", "", -1), ",")
                //fmt.Println(tagList)
                // ContainsCommonItem checks whether there is at least one common item in arrays
                if !ContainsCommonItem(tagList, acTags) {
                    fieldVal.Set(reflect.Zero(fieldVal.Type()))
                }
            }
        }
    }
}

//ContainsCommonItem checks if arrays have at least one equal item
func ContainsCommonItem(arr1 []string, arr2 []string) bool {
    for i := 0; i < len(arr1); i++ {
        for j := 0; j < len(arr2); j++ {
            if arr1[i] == arr2[j] {
                return true
            }
        }
    }
    return false
}
func main() {
    u := User{ID: 1, Username: "very secret", Nickname: "hinzir"}
    //assume authenticated user doesn't has permission to access private fields
    OmitFields(&u, []string{"public"}) 
    bytes, _ := json.Marshal(&u)
    fmt.Println(string(bytes))


    u2 := User2{ID: 1, Username: "very secret", Nickname: "hinzir"}
    //you want to filter fields by field names
    OmitFields(&u2, []string{"id", "nickname"}) 
    bytes, _ = json.Marshal(&u2)
    fmt.Println(string(bytes))

}

1

मैंने कुछ क्षेत्रों को अनदेखा करके JSON स्ट्रिंग में संरचना बदलने के लिए यह फ़ंक्शन बनाया। आशा है कि यह मदद करेगा।

func GetJSONString(obj interface{}, ignoreFields ...string) (string, error) {
    toJson, err := json.Marshal(obj)
    if err != nil {
        return "", err
    }

    if len(ignoreFields) == 0 {
        return string(toJson), nil
    }

    toMap := map[string]interface{}{}
    json.Unmarshal([]byte(string(toJson)), &toMap)

    for _, field := range ignoreFields {
        delete(toMap, field)
    }

    toJson, err = json.Marshal(toMap)
    if err != nil {
        return "", err
    }
    return string(toJson), nil
}

उदाहरण: https://play.golang.org/p/nmq7MFF47Gp

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.