unicode character in result execute template - go

I have this template
<data><datos name={{.Name}} phone={{.Phone}} email={{.Email}}></data>
And I'm running it like this:
buf := &bytes.Buffer{}
t := template.Must(template.New("dataPdf").Parse("<data><datos name={{.Name}} phone={{.Phone}} email={{.email}}></data>"))
err := t.Execute(buf, data)
if err != nil {
panic(err)
}
return buf.String()
All values ​​are overridden, but for some reason the < and > characters remain in unicode
\u003cdatos\u003e\
I update:
Verify and the error doesn't occur until this string value is assigned to a specific Struct object and then I try to convert it to json.

I cannot reproduce this. See a working example on the Go Playground https://play.golang.org/p/xKmjgzZxeES.
The output of the code below is
<data><datos name=Joe phone=123-456-7890 email=hunter2#a.com></data>
package main
import (
"bytes"
"fmt"
"text/template"
)
type Person struct {
Name string
Phone string
Email string
}
func main() {
buf := &bytes.Buffer{}
t := template.Must(template.New("dataPdf").Parse("<data><datos name={{.Name}} phone={{.Phone}} email={{.Email}}></data>"))
data := Person{Name: "Joe", Phone: "123-456-7890", Email: "hunter2#a.com"}
err := t.Execute(buf, data)
if err != nil {
panic(err)
}
fmt.Printf(buf.String())
}

Related

Decode JSON from URL query param

I am a newbie for golang proto. I need to decrypt the string that I was getting from the query param.
This is my string.
%7B%22predicates%22%3A%5B%7B%22key%22%3A%22name%22%2C%22op%22%3A%22IS_SUBSTRING%22%2C%22string_value%22%3A%22123%22%7D%2C%7B%22key%22%3A%22storage_state%22%2C%22op%22%3A%22NOT_EQUALS%22%2C%22string_value%22%3A%22STORAGESTATE_ARCHIVED%22%7D%5D%7D
I couldn't find how to decrypt this string.
Can anyone provide me an idea to decrypt this string using golang
Thanks in advance
Using urldecode and result like this:
{"predicates":[{"key":"name","op":"IS_SUBSTRING","string_value":"123"},{"key":"storage_state","op":"NOT_EQUALS","string_value":"STORAGESTATE_ARCHIVED"}]}
You can using 3rd lib or online website to decode it:https://www.urldecoder.org/
You may use url.PathUnescape(s) from std lib (try it online):
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
s := `%7B%22predicates%22%3A%5B%7B%22key%22%3A%22name%22%2C%22op%22%3A%22IS_SUBSTRING%22%2C%22string_value%22%3A%22123%22%7D%2C%7B%22key%22%3A%22storage_state%22%2C%22op%22%3A%22NOT_EQUALS%22%2C%22string_value%22%3A%22STORAGESTATE_ARCHIVED%22%7D%5D%7D`
st, err := url.PathUnescape(s)
if err != nil {
log.Fatal(err)
}
fmt.Println(st)
}
Output:
{"predicates":[{"key":"name","op":"IS_SUBSTRING","string_value":"123"},{"key":"storage_state","op":"NOT_EQUALS","string_value":"STORAGESTATE_ARCHIVED"}]}
You may Unmarshal:
var m map[string]interface{}
err = json.Unmarshal([]byte(st), &m)
if err != nil {
log.Fatal(err)
}
Or decode:
d := json.NewDecoder(strings.NewReader(st))
var m map[string]interface{}
err = d.Decode(&m)
if err != nil {
log.Fatal(err)
}
fmt.Println(m)

Golang Unmarshal an JSON response, then marshal with Struct field names

So I am hitting an API that returns a JSON response and I am unmarshalling it into a struct like so:
package main
type ProcessedRecords struct {
SLMIndividualID string `json:"individual_id"`
HouseholdPosition int `json:"Household Position"`
IndividualFirstName string `json:"individual_first_name"`
}
func main() {
req, _ := http.NewRequest(method, url, payload)
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(body)
var responseObject Response
json.Unmarshal(body, &responseObject)
fmt.Println(responseObject)
which works great. However I need to marshal this struct again but I want to use the Struct Fields as keys instead of the json: ... fields. I am using the following code:
recordsInput := []*firehose.Record{}
for i := 0; i < len(records); i++ {
if len(recordsInput) == 500 {
* code to submit records, this part works fine *
}
b, err := json.Marshal(records[i])
if err != nil {
log.Printf("Error: %v", err)
}
record := &firehose.Record{Data: b}
recordsInput = append(recordsInput, record)
}
This does submit records successfully but it's in the format:
{"individual_id":"33c05b49-149b-480f-b1c2-3a3b30e0cb6f","Household Position":1...}
and I'd like it in the format:
{"SLMIndividualId":"33c05b49-149b-480f-b1c2-3a3b30e0cb6f","HouseholdPosition":1...}
How can I achieve this?
Those tags say how the struct should be marshalled, so if they are present, that is how the output will be. You'll need to convert it to a matching struct that does not have the json: tags:
type ProcessedRecords struct {
SLMIndividualID string `json:"individual_id"`
HouseholdPosition int `json:"Household Position"`
IndividualFirstName string `json:"individual_first_name"`
}
type ProcessedRecordsOut struct {
SLMIndividualID string
HouseholdPosition int
IndividualFirstName string
}
func process() {
var in ProcessedRecords
json.Unmarshal(data, &in)
// Convert to same type w/o tags
out := ProcessedRecordsOut(in)
payload, _ := json.Marshal(out)
// ...
}
See a working example here: https://play.golang.org/p/p0Fc8DJotYE
You can omit fields one-way by defining a custom type and implementing the correct interface, e.g.
package main
import (
"encoding/json"
"fmt"
)
type Animal struct {
Name ReadOnlyString
Order string
}
type ReadOnlyString string
func (ReadOnlyString) UnmarshalJSON([]byte) error { return nil }
func main() {
x := Animal{"Bob", "First"}
js, err := json.Marshal(&x)
if err != nil {
fmt.Println("error:", err)
}
fmt.Printf("%s\n", js)
var jsonBlob = []byte(`{"Name": "Platypus", "Order": "Monotremata"}`)
if err := json.Unmarshal(jsonBlob, &x); err != nil {
fmt.Println("error:", err)
}
fmt.Printf("%#v\n\n", x)
}
https://go.dev/play/p/-mwBL0kIqM
Found this answer here: https://github.com/golang/go/issues/19423#issuecomment-284607677

How to serialize a nested struct with GOB encoding in GoLang?

I have a couple of example nested structs and need to serialize them. I am using the encoding/gob library, which should convert the struct data to bytes and the encoding/base64 library to convert the bytes to a readable base64 format. However, when I run my example code I get a serialization error error. I don't understand why this happens and how to fix the problem.
I followed this example: Golang serialize and deserialize back
Here is the code:
package main
import (
"bytes"
"encoding/base64"
"encoding/gob"
"errors"
"fmt"
)
type Hello struct {
greeting string
}
type Bye struct {
helloSaid Hello
byesaid Hello
}
func (b1 Bye) Serialize() (string, error) {
b := bytes.Buffer{}
e := gob.NewEncoder(&b)
err := e.Encode(b1)
if err != nil {
return string(b.Bytes()[:]), errors.New("serialization failed")
}
return base64.StdEncoding.EncodeToString(b.Bytes()), nil
}
func DeserializeBye(str string) (Bye, error) {
m := Bye{}
by, err := base64.StdEncoding.DecodeString(str)
if err != nil {
return m, errors.New("deserialization failed")
}
b := bytes.Buffer{}
b.Write(by)
d := gob.NewDecoder(&b)
err = d.Decode(&m)
if err != nil {
return m, errors.New("deserialization failed")
}
return m, nil
}
func main() {
h := Hello{greeting: "hello"}
b := Bye{helloSaid: h, byesaid: h}
serialized, err := b.Serialize()
if err != nil {
fmt.Println(err)
}
fmt.Println(serialized)
}
Please, make the fields of the Hello and Bye structures public. Please see the documentation for the gob package:
Structs encode and decode only exported fields.

What's the purpose of gob.Register method?

I have read the documentation of ( gob) and I have some problems :
Now I know how to encode structure and decode like that:
func main() {
s1 := &S{
Field1: "Hello Gob",
Field2: 999,
}
log.Println("Original value:", s1)
buf := new(bytes.Buffer)
err := gob.NewEncoder(buf).Encode(s1)
if err != nil {
log.Println("Encode:", err)
return
}
s2 := &S{}
err = gob.NewDecoder(buf).Decode(s2)
if err != nil {
log.Println("Decode:", err)
return
}
log.Println("Decoded value:", s2)
}
But I don't know the purpose of this method gob.Register() can someone explain to me when to use it and why?
If you're dealing with concrete types (structs) only, you don't really need it. Once you're dealing with interfaces you must register your concrete type first.
For example, let's assume we have these struct and interface (the struct implements the interface):
type Getter interface {
Get() string
}
type Foo struct {
Bar string
}
func (f Foo)Get() string {
return f.Bar
}
To send a Foo over gob as a Getter and decode it back, we must first call
gob.Register(Foo{})
So the flow would be:
// init and register
buf := bytes.NewBuffer(nil)
gob.Register(Foo{})
// create a getter of Foo
g := Getter(Foo{"wazzup"})
// encode
enc := gob.NewEncoder(buf)
enc.Encode(&g)
// decode
dec := gob.NewDecoder(buf)
var gg Getter
if err := dec.Decode(&gg); err != nil {
panic(err)
}
Now try removing the Register and this won't work because gob wouldn't know how to map things back to their appropriate type.
As http://golang.org/pkg/encoding/gob/#Register said:
Only types that will be transferred as implementations of interface
values need to be registered.
So it doesn't needed by your demo.
If you want to encode / decode a map[string]interface{}, since the field of the map is enclosed as interface type, then we need to register the specific type before.
package main
import (
"bytes"
"encoding/gob"
"fmt"
"log"
)
type SomeStruct struct {
Text string
}
func main() {
var bytes bytes.Buffer
// Remove one of these, then the decoding will produce error
gob.Register(SomeStruct{})
gob.Register([]interface{}{})
gob.Register([]SomeStruct{})
gob.Register(map[string]SomeStruct{})
writer := gob.NewEncoder(&bytes)
err := writer.Encode(map[string]interface{}{
"SomeStruct": SomeStruct{"Halo"},
"SomeSlice": []interface{}{},
"SomeSliceStruct": []SomeStruct{
{
Text: "SomeText",
},
},
"SomeMapStruct": map[string]SomeStruct{
"S": {"Test"},
},
})
if err != nil {
log.Fatalf("Error on encode process: %v\n", err)
return
}
reader := gob.NewDecoder(&bytes)
var aMap map[string]interface{}
err = reader.Decode(&aMap)
if err != nil {
log.Fatalf("Error on decode process: %v\n", err)
return
}
fmt.Printf("Decode is successful: %+v\n", aMap)
}

Go template to struct

I have a Go template that should resolve to a struct. How can I convert the bytes.Bufferresult from template execute function back to the struct. Playground
package main
import (
"bytes"
"encoding/gob"
"fmt"
"log"
"text/template"
)
type Data struct {
Age int
Username string
SubData SubData
}
type SubData struct {
Name string
}
func main() {
s := SubData{Name: "J. Jr"}
d := Data{Age: 26, Username: "HelloWorld", SubData: s}
tmpl := "{{ .SubData }}"
t := template.New("My template")
t, _ = t.Parse(string(tmpl))
buffer := new(bytes.Buffer)
t.Execute(buffer, d)
fmt.Println(buffer)
// writing
enc := gob.NewEncoder(buffer)
err := enc.Encode(s)
if err != nil {
log.Fatal("encode error:", err)
}
// reading
buffer = bytes.NewBuffer(buffer.Bytes())
e := new(SubData)
dec := gob.NewDecoder(buffer)
err = dec.Decode(e)
if err != nil {
log.Fatal("decode error:", err)
}
fmt.Println(e, err)
}
You cannot. This is plain simply impossible.
But why on earth would anybody want to do something like this? Why don't you just send your Data directly via gob and decode it directly? Why creating a textual representation which you gob?

Resources