英文:
Manipulating JSON in Go ReST service that uses Gorilla
问题
我有一个接收 JSON 的 Go ReST 服务,我需要编辑 JSON 以便创建两个不同的结构体。
我的结构体:
type Interaction struct {
DrugName string `json:"drugName"`
SeverityLevel string `json:"severityLevel"`
Summary string `json:"summary"`
}
type Drug struct {
Name string `json:"drugName"`
Dosages []string `json:"dosages"`
Interactions []Interaction `json:"interactions"`
}
示例发送的 JSON:
{
"drugName": "foo",
"dosages": ["dos1"],
"interactions": [["advil", "high", "summaryForAdvil"]]
}
ReST 服务:
func CreateDrug(w http.ResponseWriter, r *http.Request) {
// 通过打印字节验证接收到的 JSON:
bytes, _ := ioutil.ReadAll(r.Body)
}
我的目标是在 CreateDrug
函数中创建两个不同的 JSON,以便创建两个不同的结构体 Drug 和 Interaction:
{"drugName": "foo", "dosages": ["dos1"]}
{"drugName": "advil", "severityLevel": "high", "summary": "summaryForAdvil"}
在 Go 中,我该如何使用接收到的 JSON 来创建两个新的 JSON?
英文:
I have a Go ReST service that receives JSON, and I need to edit the JSON so I may make two different structs.
My structs:
type Interaction struct{
DrugName string `json:"drugName"`
SeverityLevel string `json:"severityLevel"`
Summary string `json:"summary"`
}
type Drug struct {
Name string `json:"drugName"`
Dosages []string `json:"dosages"`
Interactions []Interaction `json:"interactions"`
}
Example JSON being sent:
{"drugName":"foo","dosages":["dos1"],"interactions":[["advil","high","summaryForAdvil"]]}
The ReST service:
func CreateDrug(w http.ResponseWriter, r *http.Request) {
//I verified the received JSON by printing out the bytes:
bytes, _ := ioutil.ReadAll(r.Body)
}
My goal is the make two different JSONs in the CreateDrug function so I may make the two different structs, Drug and Interaction:
{"drugName":"foo","dosages":["dos1"]}
{"drugName":"advil", "severityLevel":"high", "summary":"summaryForAdvil"}
In Go, in this function, how do I use the received JSON to make two new JSONs?
答案1
得分: 0
将请求解组为与请求结构匹配的结构体,将值复制到您定义的结构体中,并进行编组以创建结果。
func CreateDrug(w http.ResponseWriter, r *http.Request) {
// 将请求解组为与传入JSON结构匹配的值
var v struct {
DrugName string
Dosages []string
Interactions [][3]string
}
if err := json.NewDecoder(r.Body).Decode(&v); err != nil {
// 处理错误
}
// 复制到新的结构体值。
var interactions []Interaction
for _, i := range v.Interactions {
interactions = append(interactions, Interaction{DrugName: i[0], SeverityLevel: i[1], Summary: i[2]})
}
drug := &Drug{Name: v.DrugName, Dosages: v.Dosages, Interactions: interactions}
// 编组回JSON。
data, err := json.Marshal(drug)
if err != nil {
// 处理错误
}
// 处理数据。
}
(我假设您希望Drug具有填充了Interactions字段的单个JSON值。如果这不是您想要的,请分别编组Drug和Interactions值。)
英文:
Unmarshal the request to a struct matching the structure of the request, copy values to the structs you have defined, and marshal to create the result.
func CreateDrug(w http.ResponseWriter, r *http.Request) {
// Unmarshal request to value matching the structure of the incoming JSON
var v struct {
DrugName string
Dosages []string
Interactions [][3]string
}
if err := json.NewDecoder(r.Body).Decode(&v); err != nil {
// handle error
}
// Copy to new struct values.
var interactions []Interaction
for _, i := range v.Interactions {
interactions = append(interactions, Interaction{DrugName: i[0], SeverityLevel: i[1], Summary: i[2]})
}
drug := &Drug{Name: v.DrugName, Dosages: v.Dosages, Interactions: interactions}
// Marshal back to JSON.
data, err := json.Marshal(drug)
if err != nil {
// handle error
}
// Do something with data.
}
<kbd>Playground link</kbd>
(I am assuming that you want a single JSON value for Drug with the Interactions field filled in. If that's not what you want, marshal the Drug and Interactions values separately.)
答案2
得分: 0
你可以使用json.Encoder
将多个json结构输出到流中,只需解码输入的json即可。这里是一个简单的示例:
type restValue struct {
Name string `json:"drugName"`
Dosages []string `json:"dosages"`
Interactions [][3]string `json:"interactions"`
}
func main() {
d := []byte(`{"drugName":"foo","dosages":["dos1"],"interactions":[["advil","high","summaryForAdvil"]]}`)
var v restValue
if err := json.Unmarshal(d, &v); err != nil {
panic(err)
}
interactions := make([]Interaction, 0, len(v.Interactions))
for _, in := range v.Interactions {
interactions = append(interactions, Interaction{in[0], in[1], in[2]})
}
drug := &Drug{Name: v.Name, Dosages: v.Dosages, Interactions: interactions}
enc := json.NewEncoder(os.Stdout)
// 如果你想要整个Drug结构
enc.Encode(drug)
// 或者如果你想要两个不同的结构:
drug = &Drug{Name: v.Name, Dosages: v.Dosages}
enc.Encode(drug)
for _, in := range interactions {
enc.Encode(in)
}
}
英文:
You can use json.Encoder
and output multiple json structs to a stream, you just have to decode the input json, here's a simple example:
type restValue struct {
Name string `json:"drugName"`
Dosages []string `json:"dosages"`
Interactions [][3]string `json:"interactions"`
}
func main() {
d := []byte(`{"drugName":"foo","dosages":["dos1"],"interactions":[["advil","high","summaryForAdvil"]]}`)
var v restValue
if err := json.Unmarshal(d, &v); err != nil {
panic(err)
}
interactions := make([]Interaction, 0, len(v.Interactions))
for _, in := range v.Interactions {
interactions = append(interactions, Interaction{in[0], in[1], in[2]})
}
drug := &Drug{Name: v.Name, Dosages: v.Dosages, Interactions: interactions}
enc := json.NewEncoder(os.Stdout)
// if you want the whole Drug struct
enc.Encode(drug)
// or if you want 2 different ones:
drug = &Drug{Name: v.Name, Dosages: v.Dosages}
enc.Encode(drug)
for _, in := range interactions {
enc.Encode(in)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论