{"id":14988336,"url":"https://github.com/apache/dubbo-go-hessian2","last_synced_at":"2025-05-14T06:11:34.795Z","repository":{"id":34313779,"uuid":"161442380","full_name":"apache/dubbo-go-hessian2","owner":"apache","description":"caucho hessian2 implementation in Go for [apache/dubbo-go](https://github.com/apache/dubbo-go) which is compatible with [dubbo-hessian-lite](https://github.com/apache/dubbo-hessian-lite)","archived":false,"fork":false,"pushed_at":"2025-04-16T22:28:15.000Z","size":782,"stargazers_count":215,"open_issues_count":17,"forks_count":116,"subscribers_count":53,"default_branch":"master","last_synced_at":"2025-05-10T17:16:25.411Z","etag":null,"topics":["apache-dubbo-go","caucho","dubbo","dubbo-go","dubbo-hessian","dubbo-hessian-lite","dubbogo","dubbox","hessian","hessian2"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apache.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGE.md","contributing":"contributing.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-12-12T06:22:58.000Z","updated_at":"2025-05-07T11:29:25.000Z","dependencies_parsed_at":"2023-11-29T01:33:28.146Z","dependency_job_id":"ea2823cb-79ef-48ef-845b-ed1296947467","html_url":"https://github.com/apache/dubbo-go-hessian2","commit_stats":{"total_commits":612,"total_committers":64,"mean_commits":9.5625,"dds":0.8905228758169934,"last_synced_commit":"7231dc56dfe9384a1e41f0b76bf48aae125f338e"},"previous_names":[],"tags_count":55,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fdubbo-go-hessian2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fdubbo-go-hessian2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fdubbo-go-hessian2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fdubbo-go-hessian2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apache","download_url":"https://codeload.github.com/apache/dubbo-go-hessian2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253851552,"owners_count":21973758,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apache-dubbo-go","caucho","dubbo","dubbo-go","dubbo-hessian","dubbo-hessian-lite","dubbogo","dubbox","hessian","hessian2"],"created_at":"2024-09-24T14:16:33.542Z","updated_at":"2025-05-14T06:11:34.762Z","avatar_url":"https://github.com/apache.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dubbo-go-hessian2\n\n[![Build Status](https://travis-ci.org/apache/dubbo-go-hessian2.png?branch=master)](https://travis-ci.org/apache/dubbo-go-hessian2)\n[![codecov](https://codecov.io/gh/apache/dubbo-go-hessian2/branch/master/graph/badge.svg)](https://codecov.io/gh/apache/dubbo-go-hessian2)\n[![GoDoc](https://godoc.org/github.com/apache/dubbo-go-hessian2?status.svg)](https://godoc.org/github.com/apache/dubbo-go-hessian2)\n[![Go Report Card](https://goreportcard.com/badge/github.com/apache/dubbo-go-hessian2)](https://goreportcard.com/report/github.com/apache/dubbo-go-hessian2)\n![license](https://img.shields.io/badge/license-Apache--2.0-green.svg)\n\n---\n\n\u003e **Notice: When decoding, the java version of hessian will default skip and ignore non-exist fields.**\n\u003e **From the version of v1.6.0 , dubbo-go-hessian2 will skip non-exist fields too, while that before v1.6.0 will return errors.**\n\nIt's a golang hessian library used by [Apache/dubbo-go](https://github.com/apache/dubbo-go).\n\nThere is a big performance improvement, and some bugs fix for v1.6.0,\nthanks to [micln](https://github.com/micln), [pantianying](https://github.com/pantianying), [zonghaishang](https://github.com/zonghaishang),\n [willson-chen](https://github.com/willson-chen), [champly](https://github.com/champly).\n\n## Feature List\n\n* [All JDK Exceptions](https://github.com/apache/dubbo-go-hessian2/issues/59)\n* [Field Alias By Alias](https://github.com/apache/dubbo-go-hessian2/issues/19)\n* [Java wrapper type](https://github.com/apache/dubbo-go-hessian2/issues/349)\n* [Java Bigdecimal](https://github.com/apache/dubbo-go-hessian2/issues/89)\n* [Java Date \u0026 Time](https://github.com/apache/dubbo-go-hessian2/issues/90)\n* [java8 time.Date](https://github.com/apache/dubbo-go-hessian2/pull/212)\n* [java8 java.sql.Time \u0026 java.sql.Date](https://github.com/apache/dubbo-go-hessian2/pull/219)\n* [java UUID](https://github.com/apache/dubbo-go-hessian2/pull/256)\n* [Java Generic Invokation](https://github.com/apache/dubbo-go-hessian2/issues/84)\n* [Java Extends](https://github.com/apache/dubbo-go-hessian2/issues/157)\n* [Dubbo Attachements](https://github.com/apache/dubbo-go-hessian2/issues/49)\n* [Skipping unregistered POJO](https://github.com/apache/dubbo-go-hessian2/pull/128)\n* [Emoji](https://github.com/apache/dubbo-go-hessian2/issues/129)\n\n## hessian type mapping between Java and Go\n\nCross languages message definition should be careful, the following situations should be avoided:\n\n- define object that only exists in a special language\n- using various java exceptions (using error code/message instead)\n\nSo we can maintain a cross language type mapping:\n\n| hessian type                | java type            | golang type                                            |\n|-----------------------------|----------------------|--------------------------------------------------------|\n| **null**                    | null                 | nil                                                    |\n| **binary**                  | byte[]               | []byte                                                 |\n| **boolean**                 | boolean              | bool                                                   |\n| **date**                    | java.util.Date       | time.Time                                              |\n| **double**                  | double               | float64                                                |\n| **int**                     | int                  | int32                                                  |\n| **long**                    | long                 | int64                                                  |\n| **string**                  | java.lang.String     | string                                                 |\n| **list**                    | java.util.List       | slice                                                  |\n| **map**                     | java.util.Map        | map                                                    |\n| **object**                  | custom define object | custom define struct                                   |\n| **big decimal**             | java.math.BigDecimal | github.com/dubbogo/gost/math/big/Decimal               |\n| **big integer**             | java.math.BigInteger | github.com/dubbogo/gost/math/big/Integer               |\n| **date**                    | java.sql.Date        | github.com/apache/dubbo-go-hessian2/java_sql_time/Date |\n| **date**                    | java.sql.Time        | github.com/apache/dubbo-go-hessian2/java_sql_time/Time |\n| **date**                    | all java8 sdk time   | github.com/apache/dubbo-go-hessian2/java8_time         |\n| **Integer**                 | java.lang.Integer    | *int32                                                 |\n| **Byte**                    | java.lang.Byte       | *byte                                                  |\n| **Short**                   | java.lang.Short      | *int16                                                 |\n| **Boolean**                 | java.lang.Boolean    | *bool                                                  |\n| **Long**                    | java.lang.Long       | *int64                                                 |\n| **Float**                   | java.lang.Float      | *float32                                               |\n| **Double**                  | java.lang.Double     | *float64                                               |\n| **Character**               | java.lang.Character  | *hessian.Rune                                          |\n| **OTHER COMMON USING TYPE** |                      |                                                        |\n\n\n## reference\n\n- [hessian serialization](http://hessian.caucho.com/doc/hessian-serialization.html)\n\n## Basic Usage Examples\n\n### Encode To Bytes\n\n```go\ntype Circular struct {\n\tValue\n\tPrevious *Circular\n\tNext     *Circular\n}\n\ntype Value struct {\n\tNum int\n}\n\nfunc (Circular) JavaClassName() string {\n\treturn \"com.company.Circular\"\n}\n\nc := \u0026Circular{}\nc.Num = 12345\nc.Previous = c\nc.Next = c\n\ne := NewEncoder()\nerr := e.Encode(c)\nif err != nil {\n    panic(err)\n}\n\nbytes := e.Buffer()\n```\n\n### Decode From Bytes\n\n```go\ndecodedObject, err := NewDecoder(bytes).Decode()\nif err != nil {\n    panic(err)\n}\ncircular, ok := obj.(*Circular)\n// ...\n```\n\n## Customize Usage Examples\n\n#### Encoding filed name\n\nHessian encoder default converts filed names of struct to lower camelcase, but you can customize it using `hessian` tag.\n\nExample:\n```go\ntype MyUser struct {\n\tUserFullName      string   `hessian:\"user_full_name\"`\n\tFamilyPhoneNumber string   // default convert to =\u003e familyPhoneNumber\n}\n\nfunc (MyUser) JavaClassName() string {\n\treturn \"com.company.myuser\"\n}\n\nuser := \u0026MyUser{\n    UserFullName:      \"username\",\n    FamilyPhoneNumber: \"010-12345678\",\n}\n\ne := hessian.NewEncoder()\nerr := e.Encode(user)\nif err != nil {\n    panic(err)\n}\n```\n\nThe encoded bytes of the struct `MyUser` is as following:\n```text\n 00000000  43 12 63 6f 6d 2e 63 6f  6d 70 61 6e 79 2e 6d 79  |C.com.company.my|\n 00000010  75 73 65 72 92 0e 75 73  65 72 5f 66 75 6c 6c 5f  |user..user_full_|\n 00000020  6e 61 6d 65 11 66 61 6d  69 6c 79 50 68 6f 6e 65  |name.familyPhone|\n 00000030  4e 75 6d 62 65 72 60 08  75 73 65 72 6e 61 6d 65  |Number`.username|\n 00000040  0c 30 31 30 2d 31 32 33  34 35 36 37 38           |.010-12345678|\n```\n\n#### Decoding filed name\n\nHessian decoder finds the correct target field though comparing all filed names of struct one by one until matching.\n\nThe following example shows the order of the matching rules:\n```go\ntype MyUser struct {\n\tMobilePhone      string   `hessian:\"mobile-phone\"`\n}\n\n// You must define the tag of struct for lookup filed form encoded binary bytes, in this case：\n// 00000000  43 12 63 6f 6d 2e 63 6f  6d 70 61 6e 79 2e 6d 79  |C.com.company.my|\n// 00000010  75 73 65 72 91 0c 6d 6f  62 69 6c 65 2d 70 68 6f  |user..mobile-pho|\n// 00000020  6e 65 60 0b 31 37 36 31  32 33 34 31 32 33 34     |ne`.17612341234|\n//\n// mobile-phone(tag lookup) =\u003e mobilePhone(lowerCameCase) =\u003e MobilePhone(SameCase) =\u003e mobilephone(lowercase)\n// ^ will matched\n\n\ntype MyUser struct {\n\tMobilePhone      string\n}\n\n// The following encoded binary bytes will be hit automatically:\n//\n// 00000000  43 12 63 6f 6d 2e 63 6f  6d 70 61 6e 79 2e 6d 79  |C.com.company.my|\n// 00000010  75 73 65 72 91 0b 6d 6f  62 69 6c 65 50 68 6f 6e  |user..mobilePhon|\n// 00000020  65 60 0b 31 37 36 31 32  33 34 31 32 33 34        |e`.17612341234|\n//\n// mobile-phone(tag lookup) =\u003e mobilePhone(lowerCameCase) =\u003e MobilePhone(SameCase) =\u003e mobilephone(lowercase)\n//                             ^ will matched\n//\n// 00000000  43 12 63 6f 6d 2e 63 6f  6d 70 61 6e 79 2e 6d 79  |C.com.company.my|\n// 00000010  75 73 65 72 91 0b 4d 6f  62 69 6c 65 50 68 6f 6e  |user..MobilePhon|\n// 00000020  65 60 0b 31 37 36 31 32  33 34 31 32 33 34        |e`.17612341234|\n//\n// mobile-phone(tag lookup) =\u003e mobilePhone(lowerCameCase) =\u003e MobilePhone(SameCase) =\u003e mobilephone(lowercase)\n//                                                           ^ will matched\n//\n// 00000000  43 12 63 6f 6d 2e 63 6f  6d 70 61 6e 79 2e 6d 79  |C.com.company.my|\n// 00000010  75 73 65 72 91 0b 6d 6f  62 69 6c 65 70 68 6f 6e  |user..mobilephon|\n// 00000020  65 60 0b 31 37 36 31 32  33 34 31 32 33 34        |e`.17612341234|\n//\n// mobile-phone(tag lookup) =\u003e mobilePhone(lowerCameCase) =\u003e MobilePhone(SameCase) =\u003e mobilephone(lowercase)\n//                                                                                    ^ will matched\n\n```\n\n#### Encoding param name\n\nWhen a Java method declares an argument as a parent class, it actually hope receives a subclass，\nYou can specify the encoding type of the parameter separately.\n\n##### java-server\n\n```java\npublic abstract class User {\n}\n\npublic class MyUser extends User implements Serializable {\n\n    private String userFullName;\n\n    private String familyPhoneNumber;\n}\n\npublic interface UserProvider {\n    String GetUser(User user);\n}\n\npublic class UserProviderImpl implements UserProvider {\n    public UserProviderImpl() {\n    }\n    \n    public String GetUser(User user) {\n        MyUser myUser=(MyUser)user;\n        return myUser.getUserFullName();\n    }\n}\n\n```\n\n##### go-client\n\n```go\ntype MyUser struct {\n    UserFullName      string   `hessian:\"userFullName\"`\n    FamilyPhoneNumber string   // default convert to =\u003e familyPhoneNumber\n}\n\nfunc (m *MyUser) JavaClassName() string {\n    return \"com.company.MyUser\"\n}\n\nfunc (m *MyUser) JavaParamName() string {\n    return \"com.company.User\"\n}\n\ntype UserProvider struct {\n    GetUser func(ctx context.Context, user *MyUser) (string, error) `dubbo:\"GetUser\"`\n}\n```\n\n\n\n#### Set method Alias\n\nWhen the Go client calls the Java server, the first letter of the method is converted to lowercase by default,you can use the dubbo tag to set method alias.\n\n```go\ntype UserProvider struct {\n    GetUser func(ctx context.Context) (*User, error) `dubbo:\"GetUser\"`\n}\n```\n\n#### hessian.SetTagIdentifier\n\nYou can use `hessian.SetTagIdentifier` to customize tag-identifier of hessian, which takes effect to both encoder and decoder.\n\nExample:\n\n```go\nhessian.SetTagIdentifier(\"json\")\n\ntype MyUser struct {\n\tUserFullName      string   `json:\"user_full_name\"`\n\tFamilyPhoneNumber string   // default convert to =\u003e familyPhoneNumber\n}\n\nfunc (MyUser) JavaClassName() string {\n\treturn \"com.company.myuser\"\n}\n\nuser := \u0026MyUser{\n    UserFullName:      \"username\",\n    FamilyPhoneNumber: \"010-12345678\",\n}\n\ne := hessian.NewEncoder()\nerr := e.Encode(user)\nif err != nil {\n    panic(err)\n}\n```\n\nThe encoded bytes of the struct `MyUser` is as following:\n\n```text\n 00000000  43 12 63 6f 6d 2e 63 6f  6d 70 61 6e 79 2e 6d 79  |C.com.company.my|\n 00000010  75 73 65 72 92 0e 75 73  65 72 5f 66 75 6c 6c 5f  |user..user_full_|\n 00000020  6e 61 6d 65 11 66 61 6d  69 6c 79 50 68 6f 6e 65  |name.familyPhone|\n 00000030  4e 75 6d 62 65 72 60 08  75 73 65 72 6e 61 6d 65  |Number`.username|\n 00000040  0c 30 31 30 2d 31 32 33  34 35 36 37 38           |.010-12345678|\n```\n\n#### Using Java collections\n\nBy default, the output of Hessian Java impl of a Java collection like java.util.HashSet will be decoded as `[]interface{}` in `go-hessian2`.\nTo apply the one-to-one mapping relationship between certain Java collection class and your Go struct, examples are as follows:\n\n```go\n//use HashSet as example\n//define your struct, which should implements hessian.JavaCollectionObject\ntype JavaHashSet struct {\n\tvalue []interface{}\n}\n\n//get the inside slice value\nfunc (j *JavaHashSet) Get() []interface{} {\n\treturn j.value\n}\n\n//set the inside slice value\nfunc (j *JavaHashSet) Set(v []interface{}) {\n\tj.value = v\n}\n\n//should be the same as the class name of the Java collection\nfunc (j *JavaHashSet) JavaClassName() string {\n\treturn \"java.util.HashSet\"\n}\n\nfunc init() {\n        //register your struct so that hessian can recognized it when encoding and decoding\n\tSetCollectionSerialize(\u0026JavaHashSet{})\n}\n```\n\n\n\n## Notice for inheritance\n\n`go-hessian2` supports inheritance struct, but the following situations should be avoided.\n\n+ **Avoid fields with the same name in multiple parent struct**\n\nThe following struct `C` have inherited field `Name`(default from the first parent),\nbut it's confused in logic.\n\n```go\ntype A struct { Name string }\ntype B struct { Name string }\ntype C struct {\n\tA\n\tB\n}\n```\n\n+ **Avoid inheritance for a pointer of struct**\n\nThe following definition is valid for golang syntax,\nbut the parent will be nil when create a new Dog, like `dog := Dog{}`,\nwhich will not happen in java inheritance,\nand is also not supported by `go-hessian2`.\n\n```go\ntype Dog struct {\n\t*Animal\n}\n```\n\n## Strict Mode\n\nDefault, hessian2 will decode an object to map if it's not being registered.\nIf you don't want that, change the decoder to strict mode as following, \nand it will return error when meeting unregistered object.\n\n```go\ne := hessian.NewDecoder(bytes)\ne.Strict = true // set to strict mode, default is false\n\n// or \ne := hessian.NewStrictDecoder(bytes)\n```\n\n## Tools\n\n###  tools/gen-go-enum\n\nA tool for generate hessian2 java enum define golang code. Read more [details](tools/gen-go-enum/README.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapache%2Fdubbo-go-hessian2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapache%2Fdubbo-go-hessian2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapache%2Fdubbo-go-hessian2/lists"}