Lost Java Map Class Name
zhengzepeng opened this issue · 1 comments
zhengzepeng commented
Java Code:
public class JavaDict extends HashMap<Object, Object> {
....
}
And i define:
type JavaDict map[string]interface{}
func (dict JavaDict) JavaClassName() string {
return "xxxx.JavaDict"
}
So, when if first use java to encode the JavaDict Object , i get the []byte, and i use the dubbo-go-hessian2 to decode the []byte, everything is ok, i can the the JavaDict in go, but if i want to encode the JavaDict in go, it lost the classname, so i can not use the java to decode it.
dubbo-go-hessian2 use the map type to encode the JavaDict, so the map is BC_MAP_UNTYPED
:
func (e *Encoder) encMap(m interface{}) error {
var (
err error
k interface{}
typ reflect.Type
value reflect.Value
keys []reflect.Value
)
value = reflect.ValueOf(m)
// check ref
if n, ok := e.checkRefMap(value); ok {
e.buffer = encRef(e.buffer, n)
return nil
}
// check whether it should encode the map as class.
if mm, ok := m.(map[string]interface{}); ok {
if _, ok = mm[ClassKey]; ok {
return e.EncodeMapClass(mm)
}
}
value = UnpackPtrValue(value)
// check nil map
if value.Kind() == reflect.Ptr && !value.Elem().IsValid() {
e.buffer = EncNull(e.buffer)
return nil
}
keys = value.MapKeys()
e.buffer = encByte(e.buffer, BC_MAP_UNTYPED)
if len(keys) > 0 {
typ = value.Type().Key()
for i := 0; i < len(keys); i++ {
k, err = getMapKey(keys[i], typ)
if err != nil {
return perrors.Wrapf(err, "getMapKey(idx:%d, key:%+v)", i, keys[i])
}
if err = e.Encode(k); err != nil {
return perrors.Wrapf(err, "failed to encode map key(idx:%d, key:%+v)", i, keys[i])
}
entryValueObj := value.MapIndex(keys[i]).Interface()
if err = e.Encode(entryValueObj); err != nil {
return perrors.Wrapf(err, "failed to encode map value(idx:%d, key:%+v, value:%+v)", i, k, entryValueObj)
}
}
}
e.buffer = encByte(e.buffer, BC_END)
return nil
}
may be like that:
func (e *Encoder) encMap(m interface{}) error {
var (
err error
k interface{}
typ reflect.Type
value reflect.Value
keys []reflect.Value
)
value = reflect.ValueOf(m)
// check ref
if n, ok := e.checkRefMap(value); ok {
e.buffer = encRef(e.buffer, n)
return nil
}
// check whether it should encode the map as class.
if mm, ok := m.(map[string]interface{}); ok {
if _, ok = mm[ClassKey]; ok {
return e.EncodeMapClass(mm)
}
}
value = UnpackPtrValue(value)
// check nil map
if value.Kind() == reflect.Ptr && !value.Elem().IsValid() {
e.buffer = EncNull(e.buffer)
return nil
}
// if pojo, write class name first
if p, ok := m.(POJO); ok {
e.buffer = encByte(e.buffer, BC_MAP)
e.buffer = encString(e.buffer, p.JavaClassName())
} else {
e.buffer = encByte(e.buffer, BC_MAP_UNTYPED)
}
keys = value.MapKeys()
if len(keys) > 0 {
typ = value.Type().Key()
for i := 0; i < len(keys); i++ {
k, err = getMapKey(keys[i], typ)
if err != nil {
return perrors.Wrapf(err, "getMapKey(idx:%d, key:%+v)", i, keys[i])
}
if err = e.Encode(k); err != nil {
return perrors.Wrapf(err, "failed to encode map key(idx:%d, key:%+v)", i, keys[i])
}
entryValueObj := value.MapIndex(keys[i]).Interface()
if err = e.Encode(entryValueObj); err != nil {
return perrors.Wrapf(err, "failed to encode map value(idx:%d, key:%+v, value:%+v)", i, k, entryValueObj)
}
}
}
e.buffer = encByte(e.buffer, BC_END)
return nil
}
So if m
is POJO, write the classname first?
zhangymPerson commented
ok,I'll deal with it