hessian

package module
v0.0.0-...-6bc30ac Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 14, 2024 License: Apache-2.0 Imports: 22 Imported by: 0

README

dubbo-go-hessian2

Build Status codecov GoDoc Go Report Card license


Notice: When decoding, the java version of hessian will default skip and ignore non-exist fields. 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.

It's a golang hessian library used by Apache/dubbo-go.

There is a big performance improvement, and some bugs fix for v1.6.0, thanks to micln, pantianying, zonghaishang, willson-chen, champly.

Feature List

hessian type mapping between Java and Go

Cross languages message definition should be careful, the following situations should be avoided:

  • define object that only exists in a special language
  • using various java exceptions (using error code/message instead)

So we can maintain a cross language type mapping:

hessian type java type golang type
null null nil
binary byte[] []byte
boolean boolean bool
date java.util.Date time.Time
double double float64
int int int32
long long int64
string java.lang.String string
list java.util.List slice
map java.util.Map map
object custom define object custom define struct
big decimal java.math.BigDecimal github.com/dubbogo/gost/math/big/Decimal
big integer java.math.BigInteger github.com/dubbogo/gost/math/big/Integer
date java.sql.Date gitee.com/wenj91/dubbo-go-hessian2/java_sql_time/Date
date java.sql.Time gitee.com/wenj91/dubbo-go-hessian2/java_sql_time/Time
date all java8 sdk time gitee.com/wenj91/dubbo-go-hessian2/java8_time
Integer java.lang.Integer *int32
Byte java.lang.Byte *byte
Short java.lang.Short *int16
Boolean java.lang.Boolean *bool
Long java.lang.Long *int64
Float java.lang.Float *float32
Double java.lang.Double *float64
Character java.lang.Character *hessian.Rune
OTHER COMMON USING TYPE

reference

Basic Usage Examples

Encode To Bytes
type Circular struct {
	Value
	Previous *Circular
	Next     *Circular
}

type Value struct {
	Num int
}

func (Circular) JavaClassName() string {
	return "com.company.Circular"
}

c := &Circular{}
c.Num = 12345
c.Previous = c
c.Next = c

e := NewEncoder()
err := e.Encode(c)
if err != nil {
    panic(err)
}

bytes := e.Buffer()
Decode From Bytes
decodedObject, err := NewDecoder(bytes).Decode()
if err != nil {
    panic(err)
}
circular, ok := obj.(*Circular)
// ...

Customize Usage Examples

Encoding filed name

Hessian encoder default converts filed names of struct to lower camelcase, but you can customize it using hessian tag.

Example:

type MyUser struct {
	UserFullName      string   `hessian:"user_full_name"`
	FamilyPhoneNumber string   // default convert to => familyPhoneNumber
}

func (MyUser) JavaClassName() string {
	return "com.company.myuser"
}

user := &MyUser{
    UserFullName:      "username",
    FamilyPhoneNumber: "010-12345678",
}

e := hessian.NewEncoder()
err := e.Encode(user)
if err != nil {
    panic(err)
}

The encoded bytes of the struct MyUser is as following:

 00000000  43 12 63 6f 6d 2e 63 6f  6d 70 61 6e 79 2e 6d 79  |C.com.company.my|
 00000010  75 73 65 72 92 0e 75 73  65 72 5f 66 75 6c 6c 5f  |user..user_full_|
 00000020  6e 61 6d 65 11 66 61 6d  69 6c 79 50 68 6f 6e 65  |name.familyPhone|
 00000030  4e 75 6d 62 65 72 60 08  75 73 65 72 6e 61 6d 65  |Number`.username|
 00000040  0c 30 31 30 2d 31 32 33  34 35 36 37 38           |.010-12345678|
Decoding filed name

Hessian decoder finds the correct target field though comparing all filed names of struct one by one until matching.

The following example shows the order of the matching rules:

type MyUser struct {
	MobilePhone      string   `hessian:"mobile-phone"`
}

// You must define the tag of struct for lookup filed form encoded binary bytes, in this case:
// 00000000  43 12 63 6f 6d 2e 63 6f  6d 70 61 6e 79 2e 6d 79  |C.com.company.my|
// 00000010  75 73 65 72 91 0c 6d 6f  62 69 6c 65 2d 70 68 6f  |user..mobile-pho|
// 00000020  6e 65 60 0b 31 37 36 31  32 33 34 31 32 33 34     |ne`.17612341234|
//
// mobile-phone(tag lookup) => mobilePhone(lowerCameCase) => MobilePhone(SameCase) => mobilephone(lowercase)
// ^ will matched


type MyUser struct {
	MobilePhone      string
}

// The following encoded binary bytes will be hit automatically:
//
// 00000000  43 12 63 6f 6d 2e 63 6f  6d 70 61 6e 79 2e 6d 79  |C.com.company.my|
// 00000010  75 73 65 72 91 0b 6d 6f  62 69 6c 65 50 68 6f 6e  |user..mobilePhon|
// 00000020  65 60 0b 31 37 36 31 32  33 34 31 32 33 34        |e`.17612341234|
//
// mobile-phone(tag lookup) => mobilePhone(lowerCameCase) => MobilePhone(SameCase) => mobilephone(lowercase)
//                             ^ will matched
//
// 00000000  43 12 63 6f 6d 2e 63 6f  6d 70 61 6e 79 2e 6d 79  |C.com.company.my|
// 00000010  75 73 65 72 91 0b 4d 6f  62 69 6c 65 50 68 6f 6e  |user..MobilePhon|
// 00000020  65 60 0b 31 37 36 31 32  33 34 31 32 33 34        |e`.17612341234|
//
// mobile-phone(tag lookup) => mobilePhone(lowerCameCase) => MobilePhone(SameCase) => mobilephone(lowercase)
//                                                           ^ will matched
//
// 00000000  43 12 63 6f 6d 2e 63 6f  6d 70 61 6e 79 2e 6d 79  |C.com.company.my|
// 00000010  75 73 65 72 91 0b 6d 6f  62 69 6c 65 70 68 6f 6e  |user..mobilephon|
// 00000020  65 60 0b 31 37 36 31 32  33 34 31 32 33 34        |e`.17612341234|
//
// mobile-phone(tag lookup) => mobilePhone(lowerCameCase) => MobilePhone(SameCase) => mobilephone(lowercase)
//                                                                                    ^ will matched

Encoding param name

When a Java method declares an argument as a parent class, it actually hope receives a subclass, You can specify the encoding type of the parameter separately.

java-server
public abstract class User {
}

public class MyUser extends User implements Serializable {

    private String userFullName;

    private String familyPhoneNumber;
}

public interface UserProvider {
    String GetUser(User user);
}

public class UserProviderImpl implements UserProvider {
    public UserProviderImpl() {
    }
    
    public String GetUser(User user) {
        MyUser myUser=(MyUser)user;
        return myUser.getUserFullName();
    }
}

go-client
type MyUser struct {
    UserFullName      string   `hessian:"userFullName"`
    FamilyPhoneNumber string   // default convert to => familyPhoneNumber
}

func (m *MyUser) JavaClassName() string {
    return "com.company.MyUser"
}

func (m *MyUser) JavaParamName() string {
    return "com.company.User"
}

type UserProvider struct {
    GetUser func(ctx context.Context, user *MyUser) (string, error) `dubbo:"GetUser"`
}
Set method Alias

When 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.

type UserProvider struct {
    GetUser func(ctx context.Context) (*User, error) `dubbo:"GetUser"`
}
hessian.SetTagIdentifier

You can use hessian.SetTagIdentifier to customize tag-identifier of hessian, which takes effect to both encoder and decoder.

Example:

hessian.SetTagIdentifier("json")

type MyUser struct {
	UserFullName      string   `json:"user_full_name"`
	FamilyPhoneNumber string   // default convert to => familyPhoneNumber
}

func (MyUser) JavaClassName() string {
	return "com.company.myuser"
}

user := &MyUser{
    UserFullName:      "username",
    FamilyPhoneNumber: "010-12345678",
}

e := hessian.NewEncoder()
err := e.Encode(user)
if err != nil {
    panic(err)
}

The encoded bytes of the struct MyUser is as following:

 00000000  43 12 63 6f 6d 2e 63 6f  6d 70 61 6e 79 2e 6d 79  |C.com.company.my|
 00000010  75 73 65 72 92 0e 75 73  65 72 5f 66 75 6c 6c 5f  |user..user_full_|
 00000020  6e 61 6d 65 11 66 61 6d  69 6c 79 50 68 6f 6e 65  |name.familyPhone|
 00000030  4e 75 6d 62 65 72 60 08  75 73 65 72 6e 61 6d 65  |Number`.username|
 00000040  0c 30 31 30 2d 31 32 33  34 35 36 37 38           |.010-12345678|
Using Java collections

By default, the output of Hessian Java impl of a Java collection like java.util.HashSet will be decoded as []interface{} in go-hessian2. To apply the one-to-one mapping relationship between certain Java collection class and your Go struct, examples are as follows:

//use HashSet as example
//define your struct, which should implements hessian.JavaCollectionObject
type JavaHashSet struct {
	value []interface{}
}

//get the inside slice value
func (j *JavaHashSet) Get() []interface{} {
	return j.value
}

//set the inside slice value
func (j *JavaHashSet) Set(v []interface{}) {
	j.value = v
}

//should be the same as the class name of the Java collection
func (j *JavaHashSet) JavaClassName() string {
	return "java.util.HashSet"
}

func init() {
        //register your struct so that hessian can recognized it when encoding and decoding
	SetCollectionSerialize(&JavaHashSet{})
}

Notice for inheritance

go-hessian2 supports inheritance struct, but the following situations should be avoided.

  • Avoid fields with the same name in multiple parent struct

The following struct C have inherited field Name(default from the first parent), but it's confused in logic.

type A struct { Name string }
type B struct { Name string }
type C struct {
	A
	B
}
  • Avoid inheritance for a pointer of struct

The following definition is valid for golang syntax, but the parent will be nil when create a new Dog, like dog := Dog{}, which will not happen in java inheritance, and is also not supported by go-hessian2.

type Dog struct {
	*Animal
}

Strict Mode

Default, hessian2 will decode an object to map if it's not being registered. If you don't want that, change the decoder to strict mode as following, and it will return error when meeting unregistered object.

e := hessian.NewDecoder(bytes)
e.Strict = true // set to strict mode, default is false

// or 
e := hessian.NewStrictDecoder(bytes)

Tools

tools/gen-go-enum

A tool for generate hessian2 java enum define golang code. Read more details.

Documentation

Overview

pack/unpack fixed length variable

Index

Constants

View Source
const (
	TAG_READ        = int32(-1)
	ASCII_GAP       = 32
	CHUNK_SIZE      = 4096
	BC_BINARY       = byte('B') // final chunk
	BC_BINARY_CHUNK = byte('A') // non-final chunk

	BC_BINARY_DIRECT  = byte(0x20) // 1-byte length binary
	BINARY_DIRECT_MAX = byte(0x0f)
	BC_BINARY_SHORT   = byte(0x34) // 2-byte length binary
	BINARY_SHORT_MAX  = 0x3ff      // 0-1023 binary

	BC_DATE        = byte(0x4a) // 64-bit millisecond UTC date
	BC_DATE_MINUTE = byte(0x4b) // 32-bit minute UTC date

	BC_DOUBLE = byte('D') // IEEE 64-bit double

	BC_DOUBLE_ZERO  = byte(0x5b)
	BC_DOUBLE_ONE   = byte(0x5c)
	BC_DOUBLE_BYTE  = byte(0x5d)
	BC_DOUBLE_SHORT = byte(0x5e)
	BC_DOUBLE_MILL  = byte(0x5f)

	BC_FALSE = byte('F') // boolean false

	BC_INT = byte('I') // 32-bit int

	INT_DIRECT_MIN = -0x10
	INT_DIRECT_MAX = byte(0x2f)
	BC_INT_ZERO    = byte(0x90)

	INT_BYTE_MIN     = -0x800
	INT_BYTE_MAX     = 0x7ff
	BC_INT_BYTE_ZERO = byte(0xc8)

	BC_END = byte('Z')

	INT_SHORT_MIN     = -0x40000
	INT_SHORT_MAX     = 0x3ffff
	BC_INT_SHORT_ZERO = byte(0xd4)

	BC_LIST_VARIABLE         = byte(0x55)
	BC_LIST_FIXED            = byte('V')
	BC_LIST_VARIABLE_UNTYPED = byte(0x57)
	BC_LIST_FIXED_UNTYPED    = byte(0x58)

	BC_LIST_DIRECT         = byte(0x70)
	BC_LIST_DIRECT_UNTYPED = byte(0x78)
	LIST_DIRECT_MAX        = byte(0x7)

	BC_LONG         = byte('L') // 64-bit signed integer
	LONG_DIRECT_MIN = -0x08
	LONG_DIRECT_MAX = byte(0x0f)
	BC_LONG_ZERO    = byte(0xe0)

	LONG_BYTE_MIN     = -0x800
	LONG_BYTE_MAX     = 0x7ff
	BC_LONG_BYTE_ZERO = byte(0xf8)

	LONG_SHORT_MIN     = -0x40000
	LONG_SHORT_MAX     = 0x3ffff
	BC_LONG_SHORT_ZERO = byte(0x3c)

	BC_LONG_INT = byte(0x59)

	BC_MAP         = byte('M')
	BC_MAP_UNTYPED = byte('H')

	BC_NULL = byte('N') // x4e

	BC_OBJECT     = byte('O')
	BC_OBJECT_DEF = byte('C')

	BC_OBJECT_DIRECT  = byte(0x60)
	OBJECT_DIRECT_MAX = byte(0x0f)

	BC_REF = byte(0x51)

	BC_STRING       = byte('S') // final string
	BC_STRING_CHUNK = byte('R') // non-final string

	BC_STRING_DIRECT  = byte(0x00)
	STRING_DIRECT_MAX = byte(0x1f)
	BC_STRING_SHORT   = byte(0x30)
	STRING_SHORT_MAX  = 0x3ff

	BC_TRUE = byte('T')

	P_PACKET_CHUNK = byte(0x4f)
	P_PACKET       = byte('P')

	P_PACKET_DIRECT   = byte(0x80)
	PACKET_DIRECT_MAX = byte(0x7f)

	P_PACKET_SHORT   = byte(0x70)
	PACKET_SHORT_MAX = 0xfff
	ARRAY_STRING     = "[string"
	ARRAY_INT        = "[int"
	ARRAY_DOUBLE     = "[double"
	ARRAY_FLOAT      = "[float"
	ARRAY_BOOL       = "[boolean"
	ARRAY_LONG       = "[long"

	PATH_KEY      = "path"
	GROUP_KEY     = "group"
	INTERFACE_KEY = "interface"
	VERSION_KEY   = "version"
	TIMEOUT_KEY   = "timeout"

	STRING_NIL   = ""
	STRING_TRUE  = "true"
	STRING_FALSE = "false"
	STRING_ZERO  = "0.0"
	STRING_ONE   = "1.0"
)

constants

View Source
const (
	Response_OK                byte = 20
	Response_CLIENT_TIMEOUT    byte = 30
	Response_SERVER_TIMEOUT    byte = 31
	Response_BAD_REQUEST       byte = 40
	Response_BAD_RESPONSE      byte = 50
	Response_SERVICE_NOT_FOUND byte = 60
	Response_SERVICE_ERROR     byte = 70
	Response_SERVER_ERROR      byte = 80
	Response_CLIENT_ERROR      byte = 90

	// According to "java dubbo" There are two cases of response:
	// 		1. with attachments
	// 		2. no attachments
	RESPONSE_WITH_EXCEPTION                  int32 = 0
	RESPONSE_VALUE                           int32 = 1
	RESPONSE_NULL_VALUE                      int32 = 2
	RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS int32 = 3
	RESPONSE_VALUE_WITH_ATTACHMENTS          int32 = 4
	RESPONSE_NULL_VALUE_WITH_ATTACHMENTS     int32 = 5
)

Response related consts

View Source
const (
	// header length.
	HEADER_LENGTH = 16

	// magic header
	MAGIC      = uint16(0xdabb)
	MAGIC_HIGH = byte(0xda)
	MAGIC_LOW  = byte(0xbb)

	// message flag.
	FLAG_REQUEST = byte(0x80)
	FLAG_TWOWAY  = byte(0x40)
	FLAG_EVENT   = byte(0x20) // for heartbeat
	SERIAL_MASK  = 0x1f

	DUBBO_VERSION                          = "2.5.4"
	DUBBO_VERSION_KEY                      = "dubbo"
	DEFAULT_DUBBO_PROTOCOL_VERSION         = "2.0.2" // Dubbo RPC protocol version, for compatibility, it must not be between 2.0.10 ~ 2.6.2
	LOWEST_VERSION_FOR_RESPONSE_ATTACHMENT = 2000200
	DEFAULT_LEN                            = 8388608 // 8 * 1024 * 1024 default body max length
)

*

  • the dubbo protocol header length is 16 Bytes.
  • the first 2 Bytes is magic code '0xdabb'
  • the next 1 Byte is message flags, in which its 16-20 bit is serial id, 21 for event, 22 for two way, 23 for request/response flag
  • the next 1 Bytes is response state.
  • the next 8 Bytes is package DI.
  • the next 4 Bytes is package length. *
View Source
const (
	JAVA_IDENT_REGEX = "(?:[_$a-zA-Z][_$a-zA-Z0-9]*)"
	CLASS_DESC       = "(?:L" + JAVA_IDENT_REGEX + "(?:\\/" + JAVA_IDENT_REGEX + ")*;)"
	ARRAY_DESC       = "(?:\\[+(?:(?:[VZBCDFIJS])|" + CLASS_DESC + "))"
	DESC_REGEX       = "(?:(?:[VZBCDFIJS])|" + CLASS_DESC + "|" + ARRAY_DESC + ")"
)

regular

View Source
const (
	PackageError              = PackageType(0x01)
	PackageRequest            = PackageType(0x02)
	PackageResponse           = PackageType(0x04)
	PackageHeartbeat          = PackageType(0x08)
	PackageRequest_TwoWay     = PackageType(0x10)
	PackageResponse_Exception = PackageType(0x20)
	PackageType_BitSize       = 0x2f
)

enum part

View Source
const (
	// Zero : byte zero
	Zero = byte(0x00)
)

Variables

View Source
var (
	DubboRequestHeaderBytesTwoWay = [HEADER_LENGTH]byte{MAGIC_HIGH, MAGIC_LOW, FLAG_REQUEST | FLAG_TWOWAY}
	DubboRequestHeaderBytes       = [HEADER_LENGTH]byte{MAGIC_HIGH, MAGIC_LOW, FLAG_REQUEST}
	DubboResponseHeaderBytes      = [HEADER_LENGTH]byte{MAGIC_HIGH, MAGIC_LOW, Zero, Response_OK}
	DubboRequestHeartbeatHeader   = [HEADER_LENGTH]byte{MAGIC_HIGH, MAGIC_LOW, FLAG_REQUEST | FLAG_TWOWAY | FLAG_EVENT}
	DubboResponseHeartbeatHeader  = [HEADER_LENGTH]byte{MAGIC_HIGH, MAGIC_LOW, FLAG_EVENT}
)

Dubbo request response related consts

View Source
var (
	ErrHeaderNotEnough = perrors.New("header buffer too short")
	ErrBodyNotEnough   = perrors.New("body buffer too short")
	ErrJavaException   = perrors.New("got java exception")
	ErrIllegalPackage  = perrors.New("illegal package!")
)

Error part

View Source
var (
	ErrNotEnoughBuf    = perrors.Errorf("not enough buf")
	ErrIllegalRefIndex = perrors.Errorf("illegal ref index")
)

Error part

View Source
var DescRegex, _ = regexp.Compile(DESC_REGEX)

DescRegex ...

View Source
var NilValue = reflect.Zero(reflect.TypeOf((*interface{})(nil)).Elem())
View Source
var ZeroDate = time.Time{}

Functions

func AddrEqual

func AddrEqual(x, y interface{}) bool

AddrEqual compares addrs

func ConvertSliceValueType

func ConvertSliceValueType(destTyp reflect.Type, v reflect.Value) (reflect.Value, error)

ConvertSliceValueType convert to slice of destination type

func CopyMap

func CopyMap(inMapValue, outMapValue reflect.Value) error

CopyMap copy from in map to out map

func CopySlice

func CopySlice(inSlice, outSlice reflect.Value) error

CopySlice copy from inSlice to outSlice

func EncNull

func EncNull(b []byte) []byte

/////////////////////////////////////// Null ///////////////////////////////////////

func EnsureInterface

func EnsureInterface(in interface{}, err error) (interface{}, error)

EnsureInterface get value of reflect.Value return original value if not reflect.Value

func EnsurePackValue

func EnsurePackValue(in interface{}) reflect.Value

EnsurePackValue pack the interface with value

func EnsureRawAny

func EnsureRawAny(in interface{}) interface{}

EnsureRawAny unpack if in is a reflect.Value or a ref holder.

func EnsureRawValue

func EnsureRawValue(in interface{}) reflect.Value

EnsureRawValue pack the interface with value, and make sure it's not a ref holder

func GetGoType

func GetGoType(o interface{}) string

GetGoType get the raw go type name with package.

func PackFloat64

func PackFloat64(v float64) []byte

PackFloat64 packs float64 to byte array [10].pack('G').bytes => [64, 36, 0, 0, 0, 0, 0, 0] PackFloat64 invokes go's official math library function Float64bits.

func PackInt16

func PackInt16(v int16) []byte

PackInt16 packs int16 to byte array [10].pack('N').bytes => [0, 0, 0, 10]

func PackInt32

func PackInt32(v int32) []byte

PackInt32 packs int32 to byte array [10].pack('N').bytes => [0, 0, 0, 10]

func PackInt64

func PackInt64(v int64) []byte

PackInt64 packs int64 to byte array [10].pack('q>').bytes => [0, 0, 0, 0, 0, 0, 0, 10]

func PackInt8

func PackInt8(v int8, b []byte) []byte

PackInt8 packs int to byte array

func PackPtr

func PackPtr(v reflect.Value) reflect.Value

PackPtr pack a Ptr value

func PackPtrInterface

func PackPtrInterface(s interface{}, value reflect.Value) interface{}

PackPtrInterface pack struct interface to pointer interface

func PackUint16

func PackUint16(v uint16) []byte

PackUint16 packs uint16 to byte array [10].pack('N').bytes => [0, 0, 0, 10]

func ReflectResponse

func ReflectResponse(in interface{}, out interface{}) error

ReflectResponse reflect return value TODO response object should not be copied again to another object, it should be the exact type of the object

func RegisterJavaEnum

func RegisterJavaEnum(o POJOEnum) int

RegisterJavaEnum Register a value type JavaEnum variable.

func RegisterPOJO

func RegisterPOJO(o POJO) int

RegisterPOJO Register a POJO instance. The return value is -1 if @o has been registered.

func RegisterPOJOMapping

func RegisterPOJOMapping(javaClassName string, o interface{}) int

RegisterPOJOMapping Register a POJO instance. The return value is -1 if @o has been registered.

func RegisterPOJOs

func RegisterPOJOs(os ...POJO) []int

RegisterPOJOs register a POJO instance arr @os. The return value is @os's mathching index array, in which "-1" means its matching POJO has been registered.

func SetCollectionSerialize

func SetCollectionSerialize(collection JavaCollectionObject)

func SetJavaSqlTimeSerialize

func SetJavaSqlTimeSerialize(time java_sql_time.JavaSqlTime)

SetJavaSqlTimeSerialize register serializer for java.sql.Time & java.sql.Date

func SetSerializer

func SetSerializer(javaClassName string, codec Serializer)

func SetSlice

func SetSlice(dest reflect.Value, objects interface{}) error

SetSlice set value into slice object

func SetTagIdentifier

func SetTagIdentifier(s string)

SetTagIdentifier for customize struct filed tag of hessian, your can use it like:

hessian.SetTagIdentifier("json")
type MyUser struct {
	UserFullName      string   `json:"user_full_name"`
	FamilyPhoneNumber string   // default convert to => familyPhoneNumber
}
var user MyUser
hessian.NewEncoder().Encode(user)

func SetValue

func SetValue(dest, v reflect.Value)

SetValue set the value to dest. It will auto check the Ptr pack level and unpack/pack to the right level. It makes sure success to set value

func SetValueToPtrDest

func SetValueToPtrDest(dest reflect.Value, v reflect.Value)

SetValueToPtrDest set the raw value to a pointer dest.

func Slice

func Slice(s string) (b []byte)

Slice convert string to byte slice

func SprintHex

func SprintHex(b []byte) (rs string)

SprintHex converts the []byte to a Hex string.

func ToMapStringString

func ToMapStringString(origin map[interface{}]interface{}) map[string]string

func UnRegisterPOJOs

func UnRegisterPOJOs(os ...POJO) []int

UnRegisterPOJOs unregister POJO instances. It is easy for test.

func UnpackFloat64

func UnpackFloat64(b []byte) float64

UnpackFloat64 unpacks float64 from byte array Double (0,8).unpack('G)

func UnpackInt16

func UnpackInt16(b []byte) int16

UnpackInt16 unpacks int16 from byte array (0,2).unpack('n')

func UnpackInt32

func UnpackInt32(b []byte) int32

UnpackInt32 unpacks int32 from byte array (0,4).unpack('N')

func UnpackInt64

func UnpackInt64(b []byte) int64

UnpackInt64 unpacks int64 from byte array long (0,8).unpack('q>')

func UnpackPtr

func UnpackPtr(v reflect.Value) reflect.Value

UnpackPtr unpack pointer value to original value

func UnpackPtrType

func UnpackPtrType(typ reflect.Type) reflect.Type

UnpackPtrType unpack pointer type to original type

func UnpackPtrValue

func UnpackPtrValue(v reflect.Value) reflect.Value

UnpackPtrValue unpack pointer value to original value return the pointer if its elem is zero value, because lots of operations on zero value is invalid

func UnpackToRootAddressableValue

func UnpackToRootAddressableValue(v reflect.Value) reflect.Value

UnpackToRootAddressableValue unpack pointer value to the root addressable value.

func UnpackType

func UnpackType(typ reflect.Type) (reflect.Type, int)

UnpackType unpack pointer type to original type and return the pointer depth.

func UnpackUint16

func UnpackUint16(b []byte) uint16

UnpackUint16 unpacks int16 from byte array (0,2).unpack('n')

Types

type BooleanArray

type BooleanArray struct {
	Values []bool
}

BooleanArray Boolean[] Deprecated: it will not be supported in next major version, being replaced by a slice type instead.

func (*BooleanArray) Get

func (ba *BooleanArray) Get() []interface{}

nolint

func (*BooleanArray) JavaClassName

func (*BooleanArray) JavaClassName() string

nolint

func (*BooleanArray) Set

func (ba *BooleanArray) Set(vs []interface{})

nolint

type ByteArray

type ByteArray struct {
	Values []uint8
}

ByteArray Byte[] Deprecated: it will not be supported in next major version, being replaced by a slice type instead.

func (*ByteArray) Get

func (ba *ByteArray) Get() []interface{}

nolint

func (*ByteArray) JavaClassName

func (*ByteArray) JavaClassName() string

nolint

func (*ByteArray) Set

func (ba *ByteArray) Set(vs []interface{})

nolint

type CharacterArray

type CharacterArray struct {
	Values string
}

CharacterArray Character[] Deprecated: it will not be supported in next major version, being replaced by a slice type instead.

func (*CharacterArray) Get

func (ca *CharacterArray) Get() []interface{}

nolint

func (*CharacterArray) JavaClassName

func (*CharacterArray) JavaClassName() string

nolint

func (*CharacterArray) Set

func (ca *CharacterArray) Set(vs []interface{})

nolint

type ClassInfo

type ClassInfo struct {
	// contains filtered or unexported fields
}

type DecimalSerializer

type DecimalSerializer struct{}

func (DecimalSerializer) DecObject

func (DecimalSerializer) DecObject(d *Decoder, typ reflect.Type, cls *ClassInfo) (interface{}, error)

func (DecimalSerializer) EncObject

func (DecimalSerializer) EncObject(e *Encoder, v POJO) error

type Decoder

type Decoder struct {

	// In strict mode, a class data can be decoded only when the class is registered, otherwise error returned.
	// In non-strict mode, a class data will be decoded to a map when the class is not registered.
	// The default is non-strict mode, user can change it as required.
	Strict bool
	// contains filtered or unexported fields
}

Decoder struct

func NewCheapDecoderWithSkip

func NewCheapDecoderWithSkip(b []byte) *Decoder

NewCheapDecoderWithSkip generate a decoder instance with skip, only for cache pool, before decode Reset should be called. For example, with pooling use, will effectively improve performance

	var hessianPool = &sync.Pool{
		New: func() interface{} {
			return hessian.NewCheapDecoderWithSkip([]byte{})
		},
	}

	decoder := hessianPool.Get().(*hessian.Decoder)
	fill decode data
	decoder.Reset(data[:])
 decode anything ...
	hessianPool.Put(decoder)

func NewDecoder

func NewDecoder(b []byte) *Decoder

NewDecoder generate a decoder instance

func NewDecoderSize

func NewDecoderSize(b []byte, size int) *Decoder

NewDecoderSize generate a decoder instance.

func NewDecoderWithSkip

func NewDecoderWithSkip(b []byte) *Decoder

NewDecoderWithSkip generate a decoder instance with skip.

func NewStrictDecoder

func NewStrictDecoder(b []byte) *Decoder

NewStrictDecoder generates a strict mode decoder instance. In strict mode, all target class must be registered.

func (*Decoder) Buffered

func (d *Decoder) Buffered() int

func (*Decoder) Clean

func (d *Decoder) Clean()

Clean clean the Decoder (room) for a new object decoding. Notice it won't reset reader buffer and will continue to read data from it.

func (*Decoder) Decode

func (d *Decoder) Decode() (interface{}, error)

Decode parse hessian data, and ensure the reflection value unpacked

func (*Decoder) DecodeValue

func (d *Decoder) DecodeValue() (interface{}, error)

DecodeValue parse hessian data, the return value maybe a reflection value when it's a map, list, object, or ref.

func (*Decoder) Discard

func (d *Decoder) Discard(n int) (int, error)

Discard skips the next n bytes

func (*Decoder) FindClassInfo

func (d *Decoder) FindClassInfo(javaName string) *ClassInfo

FindClassInfo find ClassInfo for the given name in decoder class info list.

func (*Decoder) ReadByte

func (d *Decoder) ReadByte() (byte, error)

ReadByte read a byte from Decoder, advance the ptr

func (*Decoder) Reset

func (d *Decoder) Reset(b []byte) *Decoder

type DoubleArray

type DoubleArray struct {
	Values []float64
}

DoubleArray Double[] Deprecated: it will not be supported in next major version, being replaced by a slice type instead.

func (*DoubleArray) Get

func (da *DoubleArray) Get() []interface{}

nolint

func (*DoubleArray) JavaClassName

func (*DoubleArray) JavaClassName() string

nolint

func (*DoubleArray) Set

func (da *DoubleArray) Set(vs []interface{})

nolint

type DubboHeader

type DubboHeader struct {
	SerialID       byte
	Type           PackageType
	ID             int64
	BodyLen        int
	ResponseStatus byte
}

DubboHeader dubbo header

type Encoder

type Encoder struct {
	// contains filtered or unexported fields
}

Encoder struct

func NewEncoder

func NewEncoder() *Encoder

NewEncoder generate an encoder instance

func (*Encoder) Append

func (e *Encoder) Append(buf []byte)

Append byte arr to encoder buffer

func (*Encoder) Buffer

func (e *Encoder) Buffer() []byte

Buffer returns byte buffer

func (*Encoder) Clean

func (e *Encoder) Clean()

Clean clean the Encoder (room) for a new object encoding.

func (*Encoder) Encode

func (e *Encoder) Encode(v interface{}) error

Encode If @v can not be encoded, the return value is nil. At present only struct may can not be encoded.

func (*Encoder) EncodeMapAsClass

func (e *Encoder) EncodeMapAsClass(className string, m map[string]interface{}) error

EncodeMapAsClass encode a map as object of given class name.

func (*Encoder) EncodeMapAsObject

func (e *Encoder) EncodeMapAsObject(clsDef *ClassInfo, m map[string]interface{}) error

EncodeMapAsObject encode a map as the given class defined object. Sometimes a class may not being registered in hessian, but it can be decoded from serialized data, and the ClassInfo can be found in Decoder by calling Decoder.FindClassInfo.

func (*Encoder) EncodeMapClass

func (e *Encoder) EncodeMapClass(m map[string]interface{}) error

EncodeMapClass encode a map as object, which MUST contains a key _class and its value is the target class name.

func (*Encoder) ReuseBufferClean

func (e *Encoder) ReuseBufferClean()

ReuseBufferClean reuse the Encoder for a new object encoding. it reuse allocated buffer and reduce memory-allocation.

type FloatArray

type FloatArray struct {
	Values []float32
}

FloatArray Float[] Deprecated: it will not be supported in next major version, being replaced by a slice type instead.

func (*FloatArray) Get

func (fa *FloatArray) Get() []interface{}

nolint

func (*FloatArray) JavaClassName

func (*FloatArray) JavaClassName() string

nolint

func (*FloatArray) Set

func (fa *FloatArray) Set(vs []interface{})

nolint

type HessianCodec

type HessianCodec struct {
	// contains filtered or unexported fields
}

HessianCodec defines hessian codec

func NewHessianCodec

func NewHessianCodec(reader *bufio.Reader) *HessianCodec

NewHessianCodec generate a new hessian codec instance

func NewHessianCodecCustom

func NewHessianCodecCustom(pkgType PackageType, reader *bufio.Reader, bodyLen int) *HessianCodec

NewHessianCodecCustom generate a new hessian codec instance.

func (*HessianCodec) ReadAttachments

func (h *HessianCodec) ReadAttachments() (map[string]string, error)

ReadAttachments ignore body, but only read attachments

func (*HessianCodec) ReadBody

func (h *HessianCodec) ReadBody(rspObj interface{}) error

ReadBody uses hessian codec to read response body

func (*HessianCodec) ReadHeader

func (h *HessianCodec) ReadHeader(header *DubboHeader) error

ReadHeader uses hessian codec to read dubbo header

func (*HessianCodec) Write

func (h *HessianCodec) Write(service Service, header DubboHeader, body interface{}) ([]byte, error)

type IntegerArray

type IntegerArray struct {
	Values []int32
}

IntegerArray Integer[]. Deprecated: it will not be supported in next major version, being replaced by a slice type instead.

func (*IntegerArray) Get

func (ia *IntegerArray) Get() []interface{}

nolint

func (*IntegerArray) JavaClassName

func (*IntegerArray) JavaClassName() string

nolint

func (*IntegerArray) Set

func (ia *IntegerArray) Set(vs []interface{})

nolint

type IntegerSerializer

type IntegerSerializer struct{}

func (IntegerSerializer) DecObject

func (IntegerSerializer) DecObject(d *Decoder, typ reflect.Type, cls *ClassInfo) (interface{}, error)

func (IntegerSerializer) EncObject

func (IntegerSerializer) EncObject(e *Encoder, v POJO) error

type JavaCollectionObject

type JavaCollectionObject interface {
	Get() []interface{}
	Set([]interface{})
	JavaClassName() string
}

type JavaCollectionSerializer

type JavaCollectionSerializer struct{}

func (JavaCollectionSerializer) DecObject

func (JavaCollectionSerializer) DecObject(d *Decoder, typ reflect.Type, cls *ClassInfo) (interface{}, error)

func (JavaCollectionSerializer) EncObject

func (JavaCollectionSerializer) EncObject(e *Encoder, vv POJO) error

type JavaEnum

type JavaEnum int32

JavaEnum type

const (
	InvalidJavaEnum JavaEnum = -1

	ClassKey = "_class"
)

invalid consts

type JavaEnumClass

type JavaEnumClass struct {
	// contains filtered or unexported fields
}

JavaEnumClass struct

type JavaSqlTimeSerializer

type JavaSqlTimeSerializer struct{}

JavaSqlTimeSerializer used to encode & decode java.sql.Time & java.sql.Date

func (JavaSqlTimeSerializer) DecObject

func (JavaSqlTimeSerializer) DecObject(d *Decoder, typ reflect.Type, cls *ClassInfo) (interface{}, error)

nolint

func (JavaSqlTimeSerializer) EncObject

func (JavaSqlTimeSerializer) EncObject(e *Encoder, vv POJO) error

nolint

type LongArray

type LongArray struct {
	Values []int64
}

LongArray Long[] Deprecated: it will not be supported in next major version, being replaced by a slice type instead.

func (*LongArray) Get

func (ba *LongArray) Get() []interface{}

nolint

func (*LongArray) JavaClassName

func (*LongArray) JavaClassName() string

nolint

func (*LongArray) Set

func (ba *LongArray) Set(vs []interface{})

nolint

type Map

type Map struct {
	sync.Mutex
	// contains filtered or unexported fields
}

func NewMap

func NewMap() *Map

func (*Map) Delete

func (m *Map) Delete(key string)

func (*Map) Load

func (m *Map) Load(key string) (any, bool)

func (*Map) Store

func (m *Map) Store(key string, value string)

type Object

type Object interface{}

Object is equal to Object of java When encoding

type POJO

type POJO interface {
	JavaClassName() string // got a go struct's Java Class package name which should be a POJO class.
}

POJO interface !!! Pls attention that Every field name should be upper case. Otherwise the app may panic.

type POJOEnum

type POJOEnum interface {
	POJO
	String() string
	EnumValue(string) JavaEnum
}

POJOEnum enum for POJO

type POJORegistry

type POJORegistry struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

POJORegistry pojo registry struct

type PackageType

type PackageType int

PackageType defines dubbo package type.

type Param

type Param interface {
	POJO
	JavaParamName() string
}

Param interface !!! Pls attention that Every field name should be upper case. specifies the Java method parameter type. if this interface is not implemented, the pojo javaClassName is used as the method parameter type by default

type Request

type Request struct {
	Params      interface{}
	Attachments map[string]string
}

func EnsureRequest

func EnsureRequest(body interface{}) *Request

func NewRequest

func NewRequest(params interface{}, atta map[string]string) *Request

NewRequest create a new Request

type Response

type Response struct {
	RspObj      interface{}
	Exception   error
	Attachments map[string]string
}

Response dubbo response

func EnsureResponse

func EnsureResponse(body interface{}) *Response

EnsureResponse check body type, make sure it's a Response or package it as a Response

func NewResponse

func NewResponse(rspObj interface{}, exception error, attachments map[string]string) *Response

NewResponse create a new Response

type Rune

type Rune rune

Rune is an alias for rune, so that to get the correct runtime type of rune. The runtime type of rune is int32, which is not expected.

type Serializer

type Serializer interface {
	EncObject(*Encoder, POJO) error
	DecObject(*Decoder, reflect.Type, *ClassInfo) (interface{}, error)
}

func GetSerializer

func GetSerializer(javaClassName string) (Serializer, bool)

type Service

type Service struct {
	Path      string
	Interface string
	Group     string
	Version   string
	Method    string
	Timeout   time.Duration // request timeout
}

Service defines service instance

type ShortArray

type ShortArray struct {
	Values []int16
}

ShortArray Short[] Deprecated: it will not be supported in next major version, being replaced by a slice type instead.

func (*ShortArray) Get

func (sa *ShortArray) Get() []interface{}

nolint

func (*ShortArray) JavaClassName

func (*ShortArray) JavaClassName() string

nolint

func (*ShortArray) Set

func (sa *ShortArray) Set(vs []interface{})

nolint

type TypeRefs

type TypeRefs struct {
	// contains filtered or unexported fields
}

/////////////////////////////////////// typeRefs ///////////////////////////////////////

func (*TypeRefs) Get

func (t *TypeRefs) Get(index int) reflect.Type

type UnknownException

type UnknownException struct {
	SerialVersionUID     int64
	DetailMessage        string
	SuppressedExceptions []java_exception.Throwabler
	StackTrace           []java_exception.StackTraceElement
	Cause                java_exception.Throwabler
	// contains filtered or unexported fields
}

func (UnknownException) Error

func (e UnknownException) Error() string

Error output error message

func (UnknownException) GetStackTrace

equals to getStackTrace in java

func (UnknownException) JavaClassName

func (e UnknownException) JavaClassName() string

JavaClassName java fully qualified path

Directories

Path Synopsis
* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.
* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.
big
testcases
tools

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL