MotanV2Codec extends AbstractCodec { @Override public byte[] encode(Channel channel, Object message) throws IOException { try { if (DefaultRpcHeartbeatFactory.isHeartbeatRequest(message)) { return encodeHeartbeat(((Request) message).getRequestId(), true); } if (DefaultRpcHeartbeatFactory.isHeartbeatResponse(message)) { return encodeHeartbeat(((Response) message).getRequestId(), false); } MotanV2Header header = new MotanV2Header(); byte[] body = null; Serialization serialization; GrowableByteBuffer buf = new GrowableByteBuffer(4096); int index = HEADER_SIZE; buf.position(index); buf.putInt(0); if (message instanceof Request) { String serialName = channel.getUrl().getParameter(URLParamType.serialize.getName(), URLParamType.serialize.getValue()); serialization = ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(serialName); if (serialization == null) { throw new MotanServiceException("can not found serialization " + serialName); } header.setSerialize(serialization.getSerializationNumber()); Request request = (Request) message; putString(buf, M2_PATH); putString(buf, request.getInterfaceName()); putString(buf, M2_METHOD); putString(buf, request.getMethodName()); if (request.getParamtersDesc() != null) { putString(buf, M2_METHOD_DESC); putString(buf, request.getParamtersDesc()); } if (request.getAttachments() != null && request.getAttachments().get(URLParamType.group.getName()) != null) { request.setAttachment(M2_GROUP, request.getAttachments().get(URLParamType.group.getName())); } putMap(buf, request.getAttachments()); header.setRequestId(request.getRequestId()); if (request.getArguments() != null) { body = serialization.serializeMulti(request.getArguments()); } } else if (message instanceof Response) { Response response = (Response) message; serialization = getSerializationByNum(response.getSerializeNumber()); header.setSerialize(serialization.getSerializationNumber()); putString(buf, M2_PROCESS_TIME); putString(buf, String.valueOf(response.getProcessTime())); if (response.getException() != null) { putString(buf, M2_ERROR); putString(buf, ExceptionUtil.toMessage(response.getException())); header.setStatus(MotanV2Header.MessageStatus.EXCEPTION.getStatus()); } putMap(buf, response.getAttachments()); header.setRequestId(response.getRequestId()); header.setRequest(false); if (response.getException() == null) { body = serialization.serialize(response.getValue()); } } buf.position(buf.position() - 1); int metalength = buf.position() - index - 4; buf.putInt(index, metalength); if (body != null && body.length > 0) { if (channel.getUrl().getBooleanParameter(URLParamType.usegz.getName(), URLParamType.usegz.getBooleanValue()) && body.length > channel.getUrl().getIntParameter(URLParamType.mingzSize.getName(), URLParamType.mingzSize.getIntValue())) { try { body = ByteUtil.gzip(body); header.setGzip(true); } catch (IOException e) { LoggerUtil.warn("MotanV2Codec encode gzip fail. so not gzip body.", e); } } buf.putInt(body.length); buf.put(body); } else { buf.putInt(0); } int position = buf.position(); buf.position(0); buf.put(header.toBytes()); buf.position(position); buf.flip(); byte[] result = new byte[buf.remaining()]; buf.get(result); return result; } catch (Exception e) { String errmsg = ""; if (message != null) { if (message instanceof Request) { errmsg = "type:request, " + message.toString(); } else { errmsg = "type:response, " + message.toString(); } } LoggerUtil.warn("motan2 encode error." + errmsg, e); if (ExceptionUtil.isMotanException(e)) { throw (RuntimeException) e; } else { throw new MotanFrameworkException("encode error!" + errmsg + ", origin errmsg:" + e.getMessage(), e, MotanErrorMsgConstant.FRAMEWORK_ENCODE_ERROR); } } }  @Override byte[] encode(Channel channel, Object message); @Override Object decode(Channel channel, String remoteIp, byte[] data);  }
@Test public void testEncode() throws Exception { Map<String, String> params = new HashMap<String, String>(); URL url = new URL("motan2", "localhost", 0, "testService", params); url.getParameters().put(URLParamType.serialize.getName(), URLParamType.serialize.getValue()); Channel channel = new MockChannel(url); DefaultRequest request = new DefaultRequest(); request.setInterfaceName("com.weibo.test.TestService"); request.setRequestId(new Random().nextLong()); request.setMethodName("testHello"); request.setArguments(new Object[]{"hi!"}); Map<String, String> attachs = new HashMap<String, String>(); attachs.put("group", "testgroup"); request.setAttachments(attachs); byte[] bytes = codec.encode(channel, request); Request newReq = (Request) codec.decode(channel, "localhost", bytes); checkRequest(request, newReq); request.setAttachments(null); bytes = codec.encode(channel, request); newReq = (Request) codec.decode(channel, "localhost", bytes); checkRequest(request, newReq); request.setArguments(new Object[]{"123", 456, true }); bytes = codec.encode(channel, request); newReq = (Request) codec.decode(channel, "localhost", bytes); checkRequest(request, newReq); DefaultResponse response = new DefaultResponse(); response.setRequestId(8908790); response.setProcessTime(5); response.setValue("xxede"); Map<String, String> resAttachs = new HashMap<String, String>(); resAttachs.put("res", "testres"); resAttachs.put("xxx","eee"); response.setAttachments(resAttachs); bytes = codec.encode(channel, response); Response newRes = (Response) codec.decode(channel, "localhost", bytes); checkResponse(response, newRes); }