Merge pull request #97 from aliiohs/feature/AddDecimalSupport
Feature/add decimal support
diff --git a/encode.go b/encode.go
index 599830d..f5f333b 100644
--- a/encode.go
+++ b/encode.go
@@ -124,6 +124,15 @@
switch t.Kind() {
case reflect.Struct:
if p, ok := v.(POJO); ok {
+ var clazz string
+ vv := reflect.ValueOf(v)
+ vv = UnpackPtr(vv)
+ if vv.IsValid() {
+ clazz = p.JavaClassName()
+ if c, ok := GetSerializer(clazz); ok {
+ return c.EncObject(e, p)
+ }
+ }
return e.encObject(p)
}
diff --git a/go.mod b/go.mod
index 971dd66..24e71dd 100644
--- a/go.mod
+++ b/go.mod
@@ -2,6 +2,7 @@
require (
github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/dubbogo/gost v1.1.1
github.com/pkg/errors v0.8.1
github.com/stretchr/testify v1.3.0
)
diff --git a/go.sum b/go.sum
index b0ebc7a..dd2e8c8 100644
--- a/go.sum
+++ b/go.sum
@@ -2,6 +2,10 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dubbogo/gost v1.0.1-0.20190709080436-ae4ac3e96ad1 h1:RrdI0SvwHR2DKNLJj+heaIbeb9qYig9QlniddKB6ViU=
+github.com/dubbogo/gost v1.0.1-0.20190709080436-ae4ac3e96ad1/go.mod h1:R7wZm1DrmrKGr50mBZVcg6C9ekG8aL5hP+sgWcIDwQg=
+github.com/dubbogo/gost v1.1.1 h1:JCM7vx5edPIjDA5ovJTuzEEXuw2t7xLyrlgi2mi5jHI=
+github.com/dubbogo/gost v1.1.1/go.mod h1:R7wZm1DrmrKGr50mBZVcg6C9ekG8aL5hP+sgWcIDwQg=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
diff --git a/object.go b/object.go
index 5757e56..d9f3cc0 100644
--- a/object.go
+++ b/object.go
@@ -522,7 +522,9 @@
cls, _ = clsDef.(classInfo)
//add to slice
d.appendClsDef(cls)
-
+ if c, ok := GetSerializer(cls.javaName); ok {
+ return c.DecObject(d)
+ }
return d.DecodeValue()
case tag == BC_OBJECT:
diff --git a/serialize.go b/serialize.go
new file mode 100644
index 0000000..510f967
--- /dev/null
+++ b/serialize.go
@@ -0,0 +1,67 @@
+// Copyright 2016-2019 aliiohs
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package hessian
+
+import (
+ big "github.com/dubbogo/gost/math/big"
+)
+
+func init() {
+ RegisterPOJO(&big.Decimal{})
+ SetSerializer("java.math.BigDecimal", DecimalSerializer{})
+}
+
+type Serializer interface {
+ EncObject(*Encoder, POJO) error
+ DecObject(*Decoder) (interface{}, error)
+}
+
+var serializerMap = make(map[string]Serializer, 16)
+
+func SetSerializer(key string, codec Serializer) {
+ serializerMap[key] = codec
+}
+
+func GetSerializer(key string) (Serializer, bool) {
+ codec, ok := serializerMap[key]
+ return codec, ok
+}
+
+type DecimalSerializer struct{}
+
+func (DecimalSerializer) EncObject(e *Encoder, v POJO) error {
+ decimal, ok := v.(big.Decimal)
+ if !ok {
+ return e.encObject(v)
+ }
+ decimal.Value = decimal.String()
+ return e.encObject(decimal)
+}
+
+func (DecimalSerializer) DecObject(d *Decoder) (interface{}, error) {
+ dec, err := d.DecodeValue()
+ if err != nil {
+ return nil, err
+ }
+ result, ok := dec.(*big.Decimal)
+ if !ok {
+ panic("result type is not decimal,please check the whether the conversion is ok")
+ }
+ err = result.FromString(result.Value)
+ if err != nil {
+ return nil, err
+ }
+ return result, nil
+}
diff --git a/serialize_test.go b/serialize_test.go
new file mode 100644
index 0000000..195a758
--- /dev/null
+++ b/serialize_test.go
@@ -0,0 +1,68 @@
+// Copyright 2016-2019 aliiohs
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package hessian
+
+import (
+ "reflect"
+ "testing"
+)
+
+import (
+ big "github.com/dubbogo/gost/math/big"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestEncodeDecodeDecimal(t *testing.T) {
+ var dec big.Decimal
+ _ = dec.FromString("100.256")
+ e := NewEncoder()
+ err := e.Encode(dec)
+ if err != nil {
+ t.Error(err)
+ t.FailNow()
+ }
+
+ d := NewDecoder(e.buffer)
+ decObj, err := d.Decode()
+ if err != nil {
+ t.Error(err)
+ t.FailNow()
+ }
+
+ if !reflect.DeepEqual(dec.String(), decObj.(*big.Decimal).String()) {
+ t.Errorf("expect: %v, but get: %v", dec, decObj)
+ }
+}
+
+func TestDecimalGoDecode(t *testing.T) {
+ var d big.Decimal
+ _ = d.FromString("100.256")
+ d.Value = d.String()
+ doTestDecimal(t, "customReplyTypedFixedDecimal", "100.256")
+}
+
+func TestDecimalJavaDecode(t *testing.T) {
+ var d big.Decimal
+ _ = d.FromString("100.256")
+ d.Value = d.String()
+ testJavaDecode(t, "customArgTypedFixedList_Decimal", d)
+}
+
+func doTestDecimal(t *testing.T, method, content string) {
+ testDecodeFrameworkFunc(t, method, func(r interface{}) {
+ t.Logf("%#v", r)
+ assert.Equal(t, content, r.(*big.Decimal).String())
+ })
+}
diff --git a/test_hessian/src/main/java/test/TestCustomDecode.java b/test_hessian/src/main/java/test/TestCustomDecode.java
index cb38a4e..27ac4ce 100644
--- a/test_hessian/src/main/java/test/TestCustomDecode.java
+++ b/test_hessian/src/main/java/test/TestCustomDecode.java
@@ -1,166 +1,171 @@
-// Copyright 2019 Xinge Gao
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package test;
-
-import com.caucho.hessian.io.Hessian2Input;
-import com.caucho.hessian.test.A0;
-import com.caucho.hessian.test.A1;
-
-import javax.xml.crypto.Data;
-import java.io.InputStream;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-
-
-public class TestCustomDecode {
-
- private Hessian2Input input;
-
- TestCustomDecode(InputStream is) {
- input = new Hessian2Input(is);
- }
-
- public Object customArgUntypedFixedListHasNull() throws Exception {
- List list = new ArrayList();
- list.add(new A0());
- list.add(new A1());
- list.add(null);
-
- Object o = input.readObject();
- return list.equals(o);
- }
-
- public Object customArgTypedFixedList() throws Exception {
- A0[] list = new A0[]{new A0()};
- Object o = input.readObject();
- return Arrays.equals(list,(A0[])o);
- }
-
- public Object customArgTypedFixedList_short_0() throws Exception {
- short[] list = new short[]{};
- Object o = input.readObject();
- return Arrays.equals(list,(short[])o);
- }
-
- public Object customArgTypedFixedList_short_7() throws Exception {
- short[] list = new short[]{1,2,3,4,5,6,7};
- Object o = input.readObject();
- return Arrays.equals(list,(short[])o);
- }
-
- public Object customArgTypedFixedList_int_0() throws Exception {
- int[] list = new int[]{};
- Object o = input.readObject();
- return Arrays.equals(list,(int[])o);
- }
-
- public Object customArgTypedFixedList_int_7() throws Exception {
- int[] list = new int[]{1,2,3,4,5,6,7};
- Object o = input.readObject();
- return Arrays.equals(list,(int[])o);
- }
-
- public Object customArgTypedFixedList_long_0() throws Exception {
- long[] list = new long[]{};
- Object o = input.readObject();
- return Arrays.equals(list,(long[])o);
- }
-
- public Object customArgTypedFixedList_long_7() throws Exception {
- long[] list = new long[]{1,2,3,4,5,6,7};
- Object o = input.readObject();
- return Arrays.equals(list,(long[])o);
- }
-
- public Object customArgTypedFixedList_float_0() throws Exception {
- float[] list = new float[]{};
- Object o = input.readObject();
- return Arrays.equals(list,(float[])o);
- }
-
- public Object customArgTypedFixedList_float_7() throws Exception {
- float[] list = new float[]{1,2,3,4,5,6,7};
- Object o = input.readObject();
- return Arrays.equals(list,(float[])o);
- }
-
- public Object customArgTypedFixedList_double_0() throws Exception {
- double[] list = new double[]{};
- Object o = input.readObject();
- return Arrays.equals(list,(double[])o);
- }
-
- public Object customArgTypedFixedList_double_7() throws Exception {
- double[] list = new double[]{1,2,3,4,5,6,7};
- Object o = input.readObject();
- return Arrays.equals(list,(double[])o);
- }
-
- public Object customArgTypedFixedList_boolean_0() throws Exception {
- boolean[] list = new boolean[]{};
- Object o = input.readObject();
- return Arrays.equals(list,(boolean[])o);
- }
-
- public Object customArgTypedFixedList_boolean_7() throws Exception {
- boolean[] list = new boolean[]{true,false,true,false,true,false,true};
- Object o = input.readObject();
- return Arrays.equals(list,(boolean[])o);
- }
-
- public Object customArgTypedFixedList_date_0() throws Exception {
- Date[] list = new Date[]{};
- Object o = input.readObject();
- return Arrays.equals(list,(Date[])o);
- }
-
- public Object customArgTypedFixedList_date_3() throws Exception {
- Date[] list = new Date[]{new Date(1560864000), new Date(1560864000), new Date(1560864000)};
- Object o = input.readObject();
- return Arrays.equals(list,(Date[])o);
- }
-
- public Object customArgTypedFixedList_arrays() throws Exception {
- int[][][] list = new int[][][]{{{1, 2, 3}, {4, 5, 6, 7}}, {{8, 9, 10}, {11, 12, 13, 14}}};
- try {
- Object o = input.readObject();
- return Arrays.deepEquals(list, (int[][][])o);
- } catch (Exception e){
- return e.toString();
- }
- }
-
- public Object customArgTypedFixedList_A0arrays() throws Exception {
- A0[][][] list = new A0[][][]{{{new A0(), new A0(), new A0()}, {new A0(), new A0(), new A0(), null}}, {{new A0()}, {new A0()}}};
- Object o = input.readObject();
- return Arrays.deepEquals(list, (A0[][][])o);
- }
-
- public Object customArgTypedFixedList_Test() throws Exception {
- TypedListTest t = new TypedListTest();
- Object o = input.readObject();
- TypedListTest t2 = (TypedListTest)o;
- return t.a.equals(t.a) && Arrays.deepEquals(t.list, t2.list) && Arrays.deepEquals(t.list1, t2.list1);
- }
-
- public Object customArgTypedFixedList_Object() throws Exception {
- Object[] list = new Object[]{new A0()};
- Object o = input.readObject();
- return Arrays.deepEquals(list, (Object[])o);
- }
+// Copyright 2019 Xinge Gao
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package test;
+
+import com.caucho.hessian.io.Hessian2Input;
+import com.caucho.hessian.test.A0;
+import com.caucho.hessian.test.A1;
+
+import javax.xml.crypto.Data;
+import java.io.InputStream;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.math.BigDecimal;
+
+public class TestCustomDecode {
+
+ private Hessian2Input input;
+
+ TestCustomDecode(InputStream is) {
+ input = new Hessian2Input(is);
+ }
+
+ public Object customArgUntypedFixedListHasNull() throws Exception {
+ List list = new ArrayList();
+ list.add(new A0());
+ list.add(new A1());
+ list.add(null);
+
+ Object o = input.readObject();
+ return list.equals(o);
+ }
+
+ public Object customArgTypedFixedList() throws Exception {
+ A0[] list = new A0[]{new A0()};
+ Object o = input.readObject();
+ return Arrays.equals(list,(A0[])o);
+ }
+
+ public Object customArgTypedFixedList_short_0() throws Exception {
+ short[] list = new short[]{};
+ Object o = input.readObject();
+ return Arrays.equals(list,(short[])o);
+ }
+
+ public Object customArgTypedFixedList_short_7() throws Exception {
+ short[] list = new short[]{1,2,3,4,5,6,7};
+ Object o = input.readObject();
+ return Arrays.equals(list,(short[])o);
+ }
+
+ public Object customArgTypedFixedList_int_0() throws Exception {
+ int[] list = new int[]{};
+ Object o = input.readObject();
+ return Arrays.equals(list,(int[])o);
+ }
+
+ public Object customArgTypedFixedList_int_7() throws Exception {
+ int[] list = new int[]{1,2,3,4,5,6,7};
+ Object o = input.readObject();
+ return Arrays.equals(list,(int[])o);
+ }
+
+ public Object customArgTypedFixedList_long_0() throws Exception {
+ long[] list = new long[]{};
+ Object o = input.readObject();
+ return Arrays.equals(list,(long[])o);
+ }
+
+ public Object customArgTypedFixedList_long_7() throws Exception {
+ long[] list = new long[]{1,2,3,4,5,6,7};
+ Object o = input.readObject();
+ return Arrays.equals(list,(long[])o);
+ }
+
+ public Object customArgTypedFixedList_float_0() throws Exception {
+ float[] list = new float[]{};
+ Object o = input.readObject();
+ return Arrays.equals(list,(float[])o);
+ }
+
+ public Object customArgTypedFixedList_float_7() throws Exception {
+ float[] list = new float[]{1,2,3,4,5,6,7};
+ Object o = input.readObject();
+ return Arrays.equals(list,(float[])o);
+ }
+
+ public Object customArgTypedFixedList_double_0() throws Exception {
+ double[] list = new double[]{};
+ Object o = input.readObject();
+ return Arrays.equals(list,(double[])o);
+ }
+
+ public Object customArgTypedFixedList_double_7() throws Exception {
+ double[] list = new double[]{1,2,3,4,5,6,7};
+ Object o = input.readObject();
+ return Arrays.equals(list,(double[])o);
+ }
+
+ public Object customArgTypedFixedList_boolean_0() throws Exception {
+ boolean[] list = new boolean[]{};
+ Object o = input.readObject();
+ return Arrays.equals(list,(boolean[])o);
+ }
+
+ public Object customArgTypedFixedList_boolean_7() throws Exception {
+ boolean[] list = new boolean[]{true,false,true,false,true,false,true};
+ Object o = input.readObject();
+ return Arrays.equals(list,(boolean[])o);
+ }
+
+ public Object customArgTypedFixedList_date_0() throws Exception {
+ Date[] list = new Date[]{};
+ Object o = input.readObject();
+ return Arrays.equals(list,(Date[])o);
+ }
+
+ public Object customArgTypedFixedList_date_3() throws Exception {
+ Date[] list = new Date[]{new Date(1560864000), new Date(1560864000), new Date(1560864000)};
+ Object o = input.readObject();
+ return Arrays.equals(list,(Date[])o);
+ }
+
+ public Object customArgTypedFixedList_arrays() throws Exception {
+ int[][][] list = new int[][][]{{{1, 2, 3}, {4, 5, 6, 7}}, {{8, 9, 10}, {11, 12, 13, 14}}};
+ try {
+ Object o = input.readObject();
+ return Arrays.deepEquals(list, (int[][][])o);
+ } catch (Exception e){
+ return e.toString();
+ }
+ }
+
+ public Object customArgTypedFixedList_A0arrays() throws Exception {
+ A0[][][] list = new A0[][][]{{{new A0(), new A0(), new A0()}, {new A0(), new A0(), new A0(), null}}, {{new A0()}, {new A0()}}};
+ Object o = input.readObject();
+ return Arrays.deepEquals(list, (A0[][][])o);
+ }
+
+ public Object customArgTypedFixedList_Test() throws Exception {
+ TypedListTest t = new TypedListTest();
+ Object o = input.readObject();
+ TypedListTest t2 = (TypedListTest)o;
+ return t.a.equals(t.a) && Arrays.deepEquals(t.list, t2.list) && Arrays.deepEquals(t.list1, t2.list1);
+ }
+
+ public Object customArgTypedFixedList_Object() throws Exception {
+ Object[] list = new Object[]{new A0()};
+ Object o = input.readObject();
+ return Arrays.deepEquals(list, (Object[])o);
+ }
+
+ public Object customArgTypedFixedList_Decimal() throws Exception {
+ BigDecimal o = (BigDecimal) input.readObject();
+ return o.toString().equals( "100.256");
+ }
}
\ No newline at end of file
diff --git a/test_hessian/src/main/java/test/TestCustomReply.java b/test_hessian/src/main/java/test/TestCustomReply.java
index e2d17b7..21ada2a 100644
--- a/test_hessian/src/main/java/test/TestCustomReply.java
+++ b/test_hessian/src/main/java/test/TestCustomReply.java
@@ -22,7 +22,7 @@
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
-
+import java.math.BigDecimal;
public class TestCustomReply {
@@ -340,6 +340,12 @@
output.flush();
}
+ public void customReplyTypedFixedDecimal() throws Exception {
+ BigDecimal decimal = new BigDecimal("100.256");
+ output.writeObject(decimal);
+ output.flush();
+ }
+
}
class TypedListTest implements Serializable {