Skip to content

Commit 461a715

Browse files
authored
feat: support encode & decode custom map type (#122)
1 parent b9aabc2 commit 461a715

3 files changed

Lines changed: 116 additions & 6 deletions

File tree

lib/v1/encoder.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict';
22

3+
var utility = require('utility');
34
var ByteBuffer = require('byte');
45
var debug = require('debug')('hessian:v1:encoder');
56
var utils = require('../utils');
@@ -15,10 +16,19 @@ function Encoder(options) {
1516
size: options.size
1617
});
1718
this.objects = [];
19+
this.mapTypes = utility.assign({
20+
'java.util.HashMap': true,
21+
'java.util.Map': true,
22+
'com.alibaba.fastjson.JSONObject': true,
23+
}, options.mapTypes);
1824
}
1925

2026
var proto = Encoder.prototype;
2127

28+
proto.isMap = function (type) {
29+
return utility.has(this.mapTypes, type) && this.mapTypes[type];
30+
};
31+
2232
proto._assertType = function (method, expectType, val, desc) {
2333
var valType = typeof val;
2434
if (!is[expectType](val)) {
@@ -245,15 +255,15 @@ proto._checkRef = function (obj) {
245255
* @param {Object} obj simple obj
246256
* @return {this}
247257
*/
248-
proto._writeHashMap = function (obj) {
258+
proto._writeHashMap = function (obj, type) {
249259
debug('_writeHashMap() %j, fields: %j', obj);
250260

251261
// Real code in java impl:
252262
// http://grepcode.com/file/repo1.maven.org/maven2/com.caucho/hessian/3.1.3/com/caucho/hessian/io/Hessian2Output.java#Hessian2Output.writeMapBegin%28java.lang.String%29
253263
// M(0x4d) type(writeType) (<key> <value>) z(0x7a)
254264
this.byteBuffer.put(0x4d);
255265
// hashmap's type is null
256-
this.writeType('');
266+
this.writeType(type);
257267

258268
if (supportES6Map && obj instanceof Map) {
259269
obj.forEach(function (value, key) {
@@ -322,8 +332,8 @@ proto.writeObject = function (obj) {
322332
realObj = obj.$;
323333
}
324334

325-
if (!className) {
326-
return this._writeHashMap(realObj);
335+
if (!className || this.isMap(className)) {
336+
return this._writeHashMap(realObj, className);
327337
}
328338

329339
debug('writeObject with complex object, className: %s', className);

lib/v2/encoder.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -578,10 +578,15 @@ proto._writeObject = function (obj) {
578578
* @param {Object} obj simple obj
579579
* @return {this}
580580
*/
581-
proto._writeHashMap = function (obj) {
581+
proto._writeHashMap = function (obj, type) {
582582
debug('_writeHashMap() %j, fields: %j', obj);
583583

584-
this.byteBuffer.put(0x48); // H
584+
if (type) {
585+
this.byteBuffer.put(0x4d);
586+
this.writeType(type);
587+
} else {
588+
this.byteBuffer.put(0x48); // H
589+
}
585590

586591
if (supportES6Map && obj instanceof Map) {
587592
obj.forEach(function (value, key) {

test/map.test.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,65 @@ describe('map.test.js', function() {
219219
assert(result.$map.get(123456) === 123);
220220
});
221221

222+
it('should encode & decode custom map type', function() {
223+
var buf = new Buffer('5674001E636F6D2E616C69626162612E666173746A736F6E2E4A534F4E41727261796C000000034D74001F636F6D2E616C69626162612E666173746A736F6E2E4A534F4E4F626A65637453000D44415445204F46204249525448530013323031362F31322F31322031323A31323A313253000946554C4C204E414D45530005446F652030530003414745490000000A7A4D74001F636F6D2E616C69626162612E666173746A736F6E2E4A534F4E4F626A65637453000D44415445204F46204249525448530013323031362F31322F31322031323A31323A313253000946554C4C204E414D45530005446F652031530003414745490000000A7A4D74001F636F6D2E616C69626162612E666173746A736F6E2E4A534F4E4F626A6563745300037878785300037979797A7A', 'hex');
224+
var obj = hessian.decode(buf, '1.0', true);
225+
assert.deepEqual(obj, {
226+
$class: 'com.alibaba.fastjson.JSONArray',
227+
$: [
228+
{
229+
$class: 'com.alibaba.fastjson.JSONObject',
230+
$: {
231+
'DATE OF BIRTH': {
232+
$class: 'java.lang.String',
233+
$: '2016/12/12 12:12:12',
234+
},
235+
'FULL NAME': {
236+
$class: 'java.lang.String',
237+
$: 'Doe 0',
238+
},
239+
AGE: {
240+
$: 10,
241+
$class: 'int',
242+
}
243+
}
244+
},
245+
{
246+
$class: 'com.alibaba.fastjson.JSONObject',
247+
$: {
248+
'DATE OF BIRTH': {
249+
$class: 'java.lang.String',
250+
$: '2016/12/12 12:12:12',
251+
},
252+
'FULL NAME': {
253+
$class: 'java.lang.String',
254+
$: 'Doe 1',
255+
},
256+
AGE: {
257+
$: 10,
258+
$class: 'int',
259+
}
260+
}
261+
},
262+
{
263+
$class: 'com.alibaba.fastjson.JSONObject',
264+
$: {
265+
xxx: {
266+
$class: 'java.lang.String',
267+
$: 'yyy',
268+
}
269+
}
270+
}
271+
]
272+
});
273+
274+
var buf2 = hessian.encode(obj, '1.0', {
275+
'com.alibaba.fastjson.JSONObject': true,
276+
});
277+
var obj2 = hessian.decode(buf2, '1.0', true);
278+
assert.deepEqual(obj, obj2);
279+
});
280+
222281
describe('v2.0', function() {
223282
// map = new HashMap();
224283
// map.put(new Integer(1), "fee");
@@ -469,6 +528,42 @@ describe('map.test.js', function() {
469528
var plainObject = JSON.parse(JSON.stringify(res.data));
470529
assert.deepEqual(plainObject, { '[object Object]': 166239 });
471530
});
531+
532+
it('should encode & decode custom map type', function() {
533+
var buf = new Buffer('731E636F6D2E616C69626162612E666173746A736F6E2E4A534F4E41727261794D1F636F6D2E616C69626162612E666173746A736F6E2E4A534F4E4F626A6563740D44415445204F4620424952544813323031362F31322F31322031323A31323A31320946554C4C204E414D4505446F652030034147459A5A4D910D44415445204F4620424952544813323031362F31322F31322031323A31323A31320946554C4C204E414D4505446F652031034147459A5A4D9103787878037979795A', 'hex');
534+
var obj = hessian.decode(buf, '2.0', true);
535+
assert.deepEqual(obj, {
536+
$class: 'com.alibaba.fastjson.JSONArray',
537+
$: [
538+
{
539+
$class: 'com.alibaba.fastjson.JSONObject',
540+
$: {
541+
'DATE OF BIRTH': '2016/12/12 12:12:12',
542+
'FULL NAME': 'Doe 0',
543+
AGE: 10
544+
}
545+
},
546+
{
547+
$class: 'com.alibaba.fastjson.JSONObject',
548+
$: {
549+
'DATE OF BIRTH': '2016/12/12 12:12:12',
550+
'FULL NAME': 'Doe 1',
551+
AGE: 10
552+
}
553+
},
554+
{
555+
$class: 'com.alibaba.fastjson.JSONObject',
556+
$: {
557+
xxx: 'yyy'
558+
}
559+
}
560+
]
561+
});
562+
563+
var buf2 = hessian.encode(obj, '2.0');
564+
var obj2 = hessian.decode(buf2, '2.0', true);
565+
assert.deepEqual(obj, obj2);
566+
});
472567
});
473568

474569
});

0 commit comments

Comments
 (0)