Rumah >pembangunan bahagian belakang >Golang >Membongkar mesej SOAP menggunakan Go

Membongkar mesej SOAP menggunakan Go

WBOY
WBOYke hadapan
2024-02-06 09:21:141227semak imbas

使用 Go 解组 SOAP 消息

Kandungan soalan

Saya agak baru dalam bahasa go.

Saya menghadapi masalah untuk membongkar mesej sabun. Percubaan saya adalah untuk mengabstrakkan kandungan elemen badan dan mengelakkan mentakrifkan struktur xml secara statik kerana ia berubah bergantung pada operasi yang diminta. Malangnya saya tidak dapat mencari jalan yang betul. Dalam contoh, fungsi getcontent harus menerima penunjuk kepada struktur yang mengandungi kandungan dan menambahkannya secara dinamik pada badan supaya ia boleh diisi. Tetapi hasilnya tidak seperti yang diharapkan.

package main

import (
    "encoding/xml"
    "fmt"
)

type Message interface{}

type EnvelopeResponse struct {
    XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"`
    Body    Message  `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"`
}

type Body struct {
    XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"`

    Fault               *Fault  `xml:",omitempty"`
    Content             Message `xml:",omitempty"`
    SOAPBodyContentType string  `xml:"-"`
}

type Fault struct {
    XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault"`

    Code   string `xml:"faultcode,omitempty"`
    String string `xml:"faultstring,omitempty"`
    Actor  string `xml:"faultactor,omitempty"`
    Detail string `xml:"detail,omitempty"`
}

type GetHostNumberOfEntriesResponse struct {
    XMLName                xml.Name `xml:"urn:dslforum-org:service:Hosts:1 GetHostNumberOfEntriesResponse"`
    NewHostNumberOfEntries int64    `xml:"NewHostNumberOfEntries"`
}

func GetContent(rawXml []byte, content interface{}) {
    envelope := EnvelopeResponse{Body: Body{Content: content}}
    xml.Unmarshal(rawXml, &envelope)
}

func main() {
    b := []byte(`
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:GetHostNumberOfEntriesResponse xmlns:u="urn:dslforum-org:service:Hosts:1">
<NewHostNumberOfEntries>47</NewHostNumberOfEntries>
</u:GetHostNumberOfEntriesResponse>
</s:Body>
</s:Envelope>
`)
    content := &GetHostNumberOfEntriesResponse{}
    GetContent(b, content)
    fmt.Println(*content)
}

Ini contoh dari taman permainan:

https://go.dev/play/p/bbr4vexipbc


Jawapan Betul


Penyelesaian yang saya temui ialah menggunakan generik untuk mewakili pembolehubah dan kandungan parameter badan.

Kod ini berfungsi seperti yang saya jangkakan:

package main

import (
    "encoding/xml"
    "fmt"
)

type EnvelopeResponse[T any] struct {
    XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"`
    Body    Body[T]  `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"`
}

type Body[T any] struct {
    XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"`

    Fault               *Fault `xml:",omitempty"`
    Content             T      `xml:",omitempty"`
    SOAPBodyContentType string `xml:"-"`
}

type Fault struct {
    XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault"`

    Code   string `xml:"faultcode,omitempty"`
    String string `xml:"faultstring,omitempty"`
    Actor  string `xml:"faultactor,omitempty"`
    Detail string `xml:"detail,omitempty"`
}

type GetHostNumberOfEntriesResponse struct {
    XMLName                xml.Name `xml:"urn:dslforum-org:service:Hosts:1 GetHostNumberOfEntriesResponse"`
    NewHostNumberOfEntries int64    `xml:"NewHostNumberOfEntries"`
}

func GetContent[T any](rawXml []byte, content T) {
    envelope := EnvelopeResponse[T]{Body: Body[T]{Content: content}}
    xml.Unmarshal(rawXml, &envelope)
}

func main() {
    b := []byte(`
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:GetHostNumberOfEntriesResponse xmlns:u="urn:dslforum-org:service:Hosts:1">
<NewHostNumberOfEntries>47</NewHostNumberOfEntries>
</u:GetHostNumberOfEntriesResponse>
</s:Body>
</s:Envelope>
`)
    content := &GetHostNumberOfEntriesResponse{}
    GetContent(b, content)
    fmt.Println(*content)
}

Atas ialah kandungan terperinci Membongkar mesej SOAP menggunakan Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam
Artikel sebelumnya:Buat fail menggunakan sudoArtikel seterusnya:Buat fail menggunakan sudo