在golang中将字符串转换为json,反之亦然?

在golang中将字符串转换为json,反之亦然?

问题描述:

In my app, I receive a json from the client. This json can be anything since the user defines the keys and the values. In the backend I store it as string in the datastore.

Now i'm trying to override the MarshalJson / UnmarshalJson functions so that what I send / receive from the client is not a string but a json.

I can't figure out how to convert a string to json in go.

my structure

type ContextData string
type Iot struct {
Id              IotId       `json:"id,string" datastore:"-" goon:"id"`
Name            string   `json:"name"`
Context         ContextData  `json:"context" datastore:",noindex"` }

example of received data

{ 'id' : '',
  'name' '',
  'context': {
           'key1': value1,
           'key2': value2 }}

how i want to store this Context field in the datastore as a noindex string '{'key1':value1, 'key2':value2}' example of data i want to send

{ 'id' : '',
  'name' '',
  'context': {
           'key1': value1,
           'key2': value2 }}

在我的应用中,我从客户端接收到json。 该json可以是任何东西,因为用户定义了键和值。 在后端,我将其作为字符串存储在数据存储中。 p>

现在,我正尝试覆盖MarshalJson / UnmarshalJson函数,以便从客户端发送/接收的不是字符串,而是 一个json。 p>

我不知道如何在go中将字符串转换为json。 p>

我的结构 p>

  type ContextData string 
type Iot struct {
Id IotId`json:“ id,string”数据存储区:“-” goon:“ id”`
Name字符串`json:“ name”`
Context ContextData`json:  “上下文”数据存储区:“,noindex”`} 
  code>  pre> 
 
 

接收到的数据示例 p>

  {'id'  :'',
'名称''',
'上下文':{
'key1':value1,
'key2':value2}} 
  code>  pre> 
 
  

我如何将此Context字段作为noindex字符串存储在数据存储中'{'key1':value1,'key2':value2}' code> 我要发送的数据示例 p>

  {'id':'',
'name''',
'context':{
'key1':value1,
'key2':value2  }} 
  code>  pre> 
  div>

If I understand your problem correctly, you want to use json.RawMessage as Context.

RawMessage is a raw encoded JSON object. It implements Marshaler and Unmarshaler and can be used to delay JSON decoding or precompute a JSON encoding.

RawMessage is just []byte, so you can keep it in data store and then attach it for an outgoing messages as "precomputed JSON".

type Iot struct {
    Id      int             `json:"id"`
    Name    string          `json:"name"`
    Context json.RawMessage `json:"context"` // RawMessage here! (not a string)
}

func main() {
    in := []byte(`{"id":1,"name":"test","context":{"key1":"value1","key2":2}}`)

    var iot Iot
    err := json.Unmarshal(in, &iot)
    if err != nil {
        panic(err)
    }

    // Context is []byte, so you can keep it as string in DB
    fmt.Println("ctx:", string(iot.Context))

    // Marshal back to json (as original)
    out, _ := json.Marshal(&iot)
    fmt.Println(string(out))
}

https://play.golang.org/p/69n0B2PNRv

I little also don't know what You want to do exacly, but in go I know two ways to convert some received data to json. This data should be as []byte type

first is allow to compiler choice interface and try parsed to JSON in this way:

[]byte(`{"monster":[{"basic":0,"fun":11,"count":262}],"m":"18"}`) 
bufferSingleMap   map[string]interface{}
json.Unmarshal(buffer , &bufferSingleMap)

socond if You know how exacly looks received data You can first define structure

type Datas struct{

    Monster []struct {
        Basic int     `json:"basic"`
        Fun int       `json:"fun"`
        Count int     `json:"count"`
    }                 `json:"Monster"`
    M int             `json:"m"`
}

Datas datas;
json.Unmarshal(buffer , &datas)

Imporant is name value. Should be writed with a capital letter (Fun, Count) This is a sign for Unmarshal that should be json. If You still don't can parsed to JSON show us Your received data, may be they have a bad syntax

If you have no structured data and you really need to send a full JSON, then you can read it like this:

// an arbitrary json string
jsonString := "{\"foo\":{\"baz\": [1,2,3]}}"

var jsonMap map[string]interface{}
json.Unmarshal([]byte(jsonString ), &jsonMap)

fmt.Println(jsonMap)    
// prints: map[foo:map[baz:[1 2 3]]]

Of course, this has a big disadvantage, in that you don't know what is the content of each item, so you need to cast each of the children of the object to its proper type before using it.

// inner items are of type interface{}
foo := jsonMap["foo"]

// convert foo to the proper type
fooMap := foo.(map[string]interface{})

// now we can use it, but its children are still interface{}
fmt.Println(fooMap["baz"])

You could simplify this if the JSON you send can be more structured, but if you want to accept any kind of JSON string then you have to check everything and cast to the correct type before using the data.

You can find the code working in this playground.