Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lost Java Map Class Name #319

Closed
zhengzepeng opened this issue Jul 15, 2022 · 1 comment
Closed

Lost Java Map Class Name #319

zhengzepeng opened this issue Jul 15, 2022 · 1 comment

Comments

@zhengzepeng
Copy link

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
Copy link
Contributor

ok,I'll deal with it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants