JSON unmarshal не выводит в моем коде, работает в goplayground - PullRequest
0 голосов
/ 11 ноября 2019

Просмотрев несколько вопросов, я решил задать свой вопрос. Несколько вещей, которые я могу сказать ...

  • Структура, в которую я вставляю данные json, экспортируется, как и ее поля.
  • Структура, в которую я вставляю данные json, былаавтоматически генерируется protoc.
  • Используемая мной структура и код работает в goplayground https://goplay.space/#WZWs3dsVcR5

У меня есть код, разбитый на несколько частей.

protofile сообщение, определяющее структуру QueryParm.

message QueryParm {
  string column_name = 1;
  string column_type = 2;
}

Моя структура в protobuf.pb.go

type QueryParm struct {
    ColumnName           string   `protobuf:"bytes,1,opt,name=column_name,json=columnName,proto3" json:"column_name,omitempty"`
    ColumnType           string   `protobuf:"bytes,2,opt,name=column_type,json=columnType,proto3" json:"column_type,omitempty"`
    WhereValue           string   `protobuf:"bytes,3,opt,name=where_value,json=whereValue,proto3" json:"where_value,omitempty"`
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}

Мои данные в pg_client.go

type PgData struct {
    ...
    QueryParms   string    `orm:"null"`
    ...
}

И моя функцияin grpc_client.go

func createJobResponse(d *pg.PgData) (*pb.JobResponse, error) {
    var qp []*pb.QueryParm

    if d.QueryParms == *new(string) {
        d.QueryParms = "[{}]"
    }
    fmt.Printf("Parms: %v\nType: %T\n", d.QueryParms, d.QueryParms)
    if err := json.Unmarshal([]byte(d.QueryParms), &qp); err != nil {
        return nil, err
    }
    fmt.Printf("Parms: %v\nType: %T\n", qp, qp)
    return &pb.JobResponse{
        ...
        QueryParms:   qp,
        ...
    }, nil
}

Вывод, который я получаю после сообщения Unmarshal, пуст в моем коде и содержит пустые указатели на структуру QueryParm на игровой площадке. Строка JSON явно существует заранее.

Parms: [{"ColumnName":"message_property_assetId","ColumnType":"string"},{"ColumnName":"id","ColumnType":"string"},{"ColumnName":"message_id","ColumnType":"string"},{"ColumnName":"message_security_tenantId","ColumnType":"string"}]
Type: string
Parms: [   ]
Type: []*proto_export.QueryParm

Есть ли какая-то причина, по которой вывод моего кода и игровой площадки должен отличаться?

РЕДАКТИРОВАНИЕ ВЫВОДА:

Я хотел сказать, что по какой-то странной причине я использовал другую структуру для кодирования моего JSON, чем для его декодирования. Это привело к тому, что имена полей JSON отличались, и не позволил правильно декодировать JSON.

Убедитесь, что вы используете ту же структуру для кодирования, что и для декодирования!

1 Ответ

1 голос
/ 11 ноября 2019

Два рабочих решения:

  1. Вы можете использовать:
var qp []interface{}

Попробуйте this :

package main

import (
    "encoding/json"
    "fmt"
)

type QueryParm struct {
    ColumnName           string   `protobuf:"bytes,1,opt,name=column_name,json=columnName,proto3" json:"column_name,omitempty"`
    ColumnType           string   `protobuf:"bytes,2,opt,name=column_type,json=columnType,proto3" json:"column_type,omitempty"`
    WhereValue           string   `protobuf:"bytes,3,opt,name=where_value,json=whereValue,proto3" json:"where_value,omitempty"`
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}

func main() {
    jsonstr := `[
        {"ColumnName":"message_property_assetId","ColumnType":"string"},
        {"ColumnName":"id","ColumnType":"string"},
        {"ColumnName":"message_id","ColumnType":"string"},
        {"ColumnName":"message_security_tenantId","ColumnType":"string"}]`
    // var qp []QueryParm
    var qp []interface{}
    if err := json.Unmarshal([]byte(jsonstr), &qp); err != nil {
        return
    }
    fmt.Println(qp)
}

Выход:

[map[ColumnName:message_property_assetId ColumnType:string] map[ColumnName:id ColumnType:string] map[ColumnName:message_id ColumnType:string] map[ColumnName:message_security_tenantId ColumnType:string]]

У вас есть column_name и column_type, а не ColumnName и ColumnType в вашем теге JSON: json:"column_name,omitempty", поэтому вы можете изменить введенную строку, например:
    jsonstr := `[
    {"column_name":"message_property_assetId","column_type":"string"},
    {"column_name":"id","column_type":"string"},
    {"column_name":"message_id","column_type":"string"},
    {"column_name":"message_security_tenantId","column_type":"string"}]`

Попробуйте this :

package main

import (
    "encoding/json"
    "fmt"
)

type QueryParm struct {
    ColumnName           string   `protobuf:"bytes,1,opt,name=column_name,json=columnName,proto3" json:"column_name,omitempty"`
    ColumnType           string   `protobuf:"bytes,2,opt,name=column_type,json=columnType,proto3" json:"column_type,omitempty"`
    WhereValue           string   `protobuf:"bytes,3,opt,name=where_value,json=whereValue,proto3" json:"where_value,omitempty"`
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}

func main() {
    jsonstr := `[
        {"column_name":"message_property_assetId","column_type":"string"},
        {"column_name":"id","column_type":"string"},
        {"column_name":"message_id","column_type":"string"},
        {"column_name":"message_security_tenantId","column_type":"string"}]`
    var qp []QueryParm
    if err := json.Unmarshal([]byte(jsonstr), &qp); err != nil {
        return
    }
    fmt.Printf("%+v\n", qp)
}

Вывод:

[{ColumnName:message_property_assetId ColumnType:string WhereValue: XXX_NoUnkeyedLiteral:{} XXX_unrecognized:[] XXX_sizecache:0} {ColumnName:id ColumnType:string WhereValue: XXX_NoUnkeyedLiteral:{} XXX_unrecognized:[] XXX_sizecache:0} {ColumnName:message_id ColumnType: WhereValue: XXX_NoUnkeyedLiteral:{} XXX_unrecognized:[] XXX_sizecache:0} {ColumnName:message_security_tenantId ColumnType:string WhereValue: XXX_NoUnkeyedLiteral:{} XXX_unrecognized:[] XXX_sizecache:0}]

Вы можете написать свой собственный JSON Marshalling and Unmarshalling.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...