This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git


The following commit(s) were added to refs/heads/master by this push:
     new 286fb12  Merge pull request #1827, support generic invoke and 
attachment for http/hessian protocol.
286fb12 is described below

commit 286fb12b011fd878b3d44ff6985e082e2141a164
Author: Jerrick Zhu <diecui1...@gmail.com>
AuthorDate: Fri Jun 1 15:02:53 2018 +0800

    Merge pull request #1827, support generic invoke and attachment for 
http/hessian protocol.
    
    fixes  #1768, #19
---
 .../dubbo/config/mock/MockProxyFactory.java        |   5 +
 .../java/com/alibaba/dubbo/rpc/ProxyFactory.java   |   9 +
 .../alibaba/dubbo/rpc/filter/GenericFilter.java    |   9 +-
 .../dubbo/rpc/filter/GenericImplFilter.java        |   8 +-
 .../dubbo/rpc/protocol/AbstractProxyProtocol.java  |   6 +-
 .../dubbo/rpc/proxy/AbstractProxyFactory.java      |  15 ++
 .../rpc/proxy/wrapper/StubProxyFactoryWrapper.java |   5 +
 dubbo-rpc/dubbo-rpc-hessian/pom.xml                |   6 +
 ....java => DubboHessianURLConnectionFactory.java} |  87 +++++----
 .../rpc/protocol/hessian/HessianProtocol.java      |  32 +++-
 .../hessian/HttpClientConnectionFactory.java       |   9 +-
 .../rpc/protocol/hessian/HessianProtocolTest.java  |  93 ++++++++++
 .../dubbo/rpc/protocol/hessian/HessianService.java |   2 +
 .../rpc/protocol/hessian/HessianServiceImpl.java   |   6 +
 dubbo-rpc/dubbo-rpc-http/pom.xml                   |   6 +
 .../dubbo/rpc/protocol/http/HttpProtocol.java      |  55 ++++--
 .../rpc/protocol/http/HttpRemoteInvocation.java    |  57 ++++++
 .../dubbo/rpc/protocol/http/HttpProtocolTest.java  | 198 +++++++++++++++++++++
 .../dubbo/rpc/protocol/http/HttpService.java}      |   8 +-
 .../dubbo/rpc/protocol/http/HttpServiceImpl.java}  |   8 +-
 dubbo-rpc/dubbo-rpc-rest/pom.xml                   |   6 +
 .../dubbo/rpc/protol/rest/RestProtocolTest.java    |  48 +++++
 .../dubbo/rpc/protol/rest/RestService.java}        |  21 ++-
 .../dubbo/rpc/protol/rest/RestServiceImpl.java}    |  19 +-
 24 files changed, 625 insertions(+), 93 deletions(-)

diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/mock/MockProxyFactory.java
 
b/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/mock/MockProxyFactory.java
index 3de2e3a..cd78366 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/mock/MockProxyFactory.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/mock/MockProxyFactory.java
@@ -28,6 +28,11 @@ public class MockProxyFactory implements ProxyFactory {
     }
 
     @Override
+    public <T> T getProxy(Invoker<T> invoker, boolean generic) throws 
RpcException {
+        return null;
+    }
+
+    @Override
     public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws 
RpcException {
         return null;
     }
diff --git 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/ProxyFactory.java 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/ProxyFactory.java
index 6ba7057..fb03d6b 100644
--- 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/ProxyFactory.java
+++ 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/ProxyFactory.java
@@ -37,6 +37,15 @@ public interface ProxyFactory {
     <T> T getProxy(Invoker<T> invoker) throws RpcException;
 
     /**
+     * create proxy.
+     *
+     * @param invoker
+     * @return proxy
+     */
+    @Adaptive({Constants.PROXY_KEY})
+    <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException;
+
+    /**
      * create invoker.
      *
      * @param <T>
diff --git 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericFilter.java
 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericFilter.java
index d393822..8404a99 100644
--- 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericFilter.java
+++ 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericFilter.java
@@ -32,10 +32,12 @@ import com.alibaba.dubbo.rpc.Filter;
 import com.alibaba.dubbo.rpc.Invocation;
 import com.alibaba.dubbo.rpc.Invoker;
 import com.alibaba.dubbo.rpc.Result;
+import com.alibaba.dubbo.rpc.RpcContext;
 import com.alibaba.dubbo.rpc.RpcException;
 import com.alibaba.dubbo.rpc.RpcInvocation;
 import com.alibaba.dubbo.rpc.RpcResult;
 import com.alibaba.dubbo.rpc.service.GenericException;
+import com.alibaba.dubbo.rpc.service.GenericService;
 import com.alibaba.dubbo.rpc.support.ProtocolUtils;
 
 import java.io.IOException;
@@ -52,7 +54,7 @@ public class GenericFilter implements Filter {
         if (inv.getMethodName().equals(Constants.$INVOKE)
                 && inv.getArguments() != null
                 && inv.getArguments().length == 3
-                && 
!ProtocolUtils.isGeneric(invoker.getUrl().getParameter(Constants.GENERIC_KEY))) 
{
+                && !invoker.getInterface().equals(GenericService.class)) {
             String name = ((String) inv.getArguments()[0]).trim();
             String[] types = (String[]) inv.getArguments()[1];
             Object[] args = (Object[]) inv.getArguments()[2];
@@ -63,6 +65,11 @@ public class GenericFilter implements Filter {
                     args = new Object[params.length];
                 }
                 String generic = inv.getAttachment(Constants.GENERIC_KEY);
+
+                if (StringUtils.isBlank(generic)) {
+                    generic = 
RpcContext.getContext().getAttachment(Constants.GENERIC_KEY);
+                }
+
                 if (StringUtils.isEmpty(generic)
                         || 
ProtocolUtils.isDefaultGenericSerialization(generic)) {
                     args = PojoUtils.realize(args, params, 
method.getGenericParameterTypes());
diff --git 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericImplFilter.java
 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericImplFilter.java
index 99bced5..6be08fe 100644
--- 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericImplFilter.java
+++ 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/GenericImplFilter.java
@@ -155,13 +155,13 @@ public class GenericImplFilter implements Filter {
 
                 for (Object arg : args) {
                     if (!(byte[].class == arg.getClass())) {
-                        error(byte[].class.getName(), 
arg.getClass().getName());
+                        error(generic, byte[].class.getName(), 
arg.getClass().getName());
                     }
                 }
             } else if (ProtocolUtils.isBeanGenericSerialization(generic)) {
                 for (Object arg : args) {
                     if (!(arg instanceof JavaBeanDescriptor)) {
-                        error(JavaBeanDescriptor.class.getName(), 
arg.getClass().getName());
+                        error(generic, JavaBeanDescriptor.class.getName(), 
arg.getClass().getName());
                     }
                 }
             }
@@ -172,10 +172,10 @@ public class GenericImplFilter implements Filter {
         return invoker.invoke(invocation);
     }
 
-    private void error(String expected, String actual) throws RpcException {
+    private void error(String generic, String expected, String actual) throws 
RpcException {
         throw new RpcException(
                 "Generic serialization [" +
-                        Constants.GENERIC_SERIALIZATION_NATIVE_JAVA +
+                        generic +
                         "] only support message type " +
                         expected +
                         " and your message type is " +
diff --git 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/protocol/AbstractProxyProtocol.java
 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/protocol/AbstractProxyProtocol.java
index 8136cc0..561520c 100644
--- 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/protocol/AbstractProxyProtocol.java
+++ 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/protocol/AbstractProxyProtocol.java
@@ -68,7 +68,7 @@ public abstract class AbstractProxyProtocol extends 
AbstractProtocol {
         if (exporter != null) {
             return exporter;
         }
-        final Runnable runnable = doExport(proxyFactory.getProxy(invoker), 
invoker.getInterface(), invoker.getUrl());
+        final Runnable runnable = doExport(proxyFactory.getProxy(invoker, 
true), invoker.getInterface(), invoker.getUrl());
         exporter = new AbstractExporter<T>(invoker) {
             @Override
             public void unexport() {
@@ -89,12 +89,12 @@ public abstract class AbstractProxyProtocol extends 
AbstractProtocol {
 
     @Override
     public <T> Invoker<T> refer(final Class<T> type, final URL url) throws 
RpcException {
-        final Invoker<T> tagert = proxyFactory.getInvoker(doRefer(type, url), 
type, url);
+        final Invoker<T> target = proxyFactory.getInvoker(doRefer(type, url), 
type, url);
         Invoker<T> invoker = new AbstractInvoker<T>(type, url) {
             @Override
             protected Result doInvoke(Invocation invocation) throws Throwable {
                 try {
-                    Result result = tagert.invoke(invocation);
+                    Result result = target.invoke(invocation);
                     Throwable e = result.getException();
                     if (e != null) {
                         for (Class<?> rpcException : rpcExceptions) {
diff --git 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/AbstractProxyFactory.java
 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/AbstractProxyFactory.java
index 21c350d..d27f608 100644
--- 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/AbstractProxyFactory.java
+++ 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/AbstractProxyFactory.java
@@ -22,6 +22,7 @@ import com.alibaba.dubbo.rpc.Invoker;
 import com.alibaba.dubbo.rpc.ProxyFactory;
 import com.alibaba.dubbo.rpc.RpcException;
 import com.alibaba.dubbo.rpc.service.EchoService;
+import com.alibaba.dubbo.rpc.service.GenericService;
 
 /**
  * AbstractProxyFactory
@@ -30,6 +31,11 @@ public abstract class AbstractProxyFactory implements 
ProxyFactory {
 
     @Override
     public <T> T getProxy(Invoker<T> invoker) throws RpcException {
+        return getProxy(invoker, false);
+    }
+
+    @Override
+    public <T> T getProxy(Invoker<T> invoker, boolean generic) throws 
RpcException {
         Class<?>[] interfaces = null;
         String config = invoker.getUrl().getParameter("interfaces");
         if (config != null && config.length() > 0) {
@@ -46,6 +52,15 @@ public abstract class AbstractProxyFactory implements 
ProxyFactory {
         if (interfaces == null) {
             interfaces = new Class<?>[]{invoker.getInterface(), 
EchoService.class};
         }
+
+        if (!invoker.getInterface().equals(GenericService.class) && generic) {
+            int len = interfaces.length;
+            Class<?>[] temp = interfaces;
+            interfaces = new Class<?>[len + 1];
+            System.arraycopy(temp, 0, interfaces, 0, len);
+            interfaces[len] = GenericService.class;
+        }
+
         return getProxy(invoker, interfaces);
     }
 
diff --git 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/wrapper/StubProxyFactoryWrapper.java
 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/wrapper/StubProxyFactoryWrapper.java
index ec3db16..3f3ed3f 100644
--- 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/wrapper/StubProxyFactoryWrapper.java
+++ 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/proxy/wrapper/StubProxyFactoryWrapper.java
@@ -55,6 +55,11 @@ public class StubProxyFactoryWrapper implements ProxyFactory 
{
     }
 
     @Override
+    public <T> T getProxy(Invoker<T> invoker, boolean generic) throws 
RpcException {
+        return proxyFactory.getProxy(invoker, generic);
+    }
+
+    @Override
     @SuppressWarnings({"unchecked", "rawtypes"})
     public <T> T getProxy(Invoker<T> invoker) throws RpcException {
         T proxy = proxyFactory.getProxy(invoker);
diff --git a/dubbo-rpc/dubbo-rpc-hessian/pom.xml 
b/dubbo-rpc/dubbo-rpc-hessian/pom.xml
index 00ca28c..98ad82d 100644
--- a/dubbo-rpc/dubbo-rpc-hessian/pom.xml
+++ b/dubbo-rpc/dubbo-rpc-hessian/pom.xml
@@ -48,5 +48,11 @@
             <groupId>org.apache.httpcomponents</groupId>
             <artifactId>httpclient</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo-serialization-jdk</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
\ No newline at end of file
diff --git 
a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnectionFactory.java
 
b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/DubboHessianURLConnectionFactory.java
similarity index 55%
copy from 
dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnectionFactory.java
copy to 
dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/DubboHessianURLConnectionFactory.java
index 033277d..8fe2f14 100644
--- 
a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnectionFactory.java
+++ 
b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/DubboHessianURLConnectionFactory.java
@@ -1,47 +1,40 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 com.alibaba.dubbo.rpc.protocol.hessian;
-
-import com.caucho.hessian.client.HessianConnection;
-import com.caucho.hessian.client.HessianConnectionFactory;
-import com.caucho.hessian.client.HessianProxyFactory;
-import org.apache.http.client.HttpClient;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.params.HttpConnectionParams;
-
-import java.io.IOException;
-import java.net.URL;
-
-/**
- * HttpClientConnectionFactory
- */
-public class HttpClientConnectionFactory implements HessianConnectionFactory {
-
-    private final HttpClient httpClient = new DefaultHttpClient();
-
-    @Override
-    public void setHessianProxyFactory(HessianProxyFactory factory) {
-        HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), 
(int) factory.getConnectTimeout());
-        HttpConnectionParams.setSoTimeout(httpClient.getParams(), (int) 
factory.getReadTimeout());
-    }
-
-    @Override
-    public HessianConnection open(URL url) throws IOException {
-        return new HttpClientConnection(httpClient, url);
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 com.alibaba.dubbo.rpc.protocol.hessian;
+
+import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.rpc.RpcContext;
+import com.caucho.hessian.client.HessianConnection;
+import com.caucho.hessian.client.HessianURLConnectionFactory;
+
+import java.io.IOException;
+import java.net.URL;
+
+public class DubboHessianURLConnectionFactory extends 
HessianURLConnectionFactory {
+
+    @Override
+    public HessianConnection open(URL url) throws IOException {
+        HessianConnection connection = super.open(url);
+        RpcContext context = RpcContext.getContext();
+        for (String key : context.getAttachments().keySet()) {
+            connection.addHeader(Constants.DEFAULT_EXCHANGER + key, 
context.getAttachment(key));
+        }
+
+        return connection;
+    }
+}
diff --git 
a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocol.java
 
b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocol.java
index f1eae5c..9733307 100644
--- 
a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocol.java
+++ 
b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocol.java
@@ -25,8 +25,11 @@ import com.alibaba.dubbo.rpc.RpcContext;
 import com.alibaba.dubbo.rpc.RpcException;
 import com.alibaba.dubbo.rpc.protocol.AbstractProxyProtocol;
 
+import com.alibaba.dubbo.rpc.service.GenericService;
+import com.alibaba.dubbo.rpc.support.ProtocolUtils;
 import com.caucho.hessian.HessianException;
 import com.caucho.hessian.client.HessianConnectionException;
+import com.caucho.hessian.client.HessianConnectionFactory;
 import com.caucho.hessian.client.HessianProxyFactory;
 import com.caucho.hessian.io.HessianMethodSerializationException;
 import com.caucho.hessian.server.HessianSkeleton;
@@ -37,6 +40,7 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.net.SocketTimeoutException;
 import java.util.ArrayList;
+import java.util.Enumeration;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -73,12 +77,17 @@ public class HessianProtocol extends AbstractProxyProtocol {
             serverMap.put(addr, server);
         }
         final String path = url.getAbsolutePath();
-        HessianSkeleton skeleton = new HessianSkeleton(impl, type);
+        final HessianSkeleton skeleton = new HessianSkeleton(impl, type);
         skeletonMap.put(path, skeleton);
+
+        final String genericPath = path + "/" + Constants.GENERIC_KEY;
+        skeletonMap.put(genericPath, new HessianSkeleton(impl, 
GenericService.class));
+
         return new Runnable() {
             @Override
             public void run() {
                 skeletonMap.remove(path);
+                skeletonMap.remove(genericPath);
             }
         };
     }
@@ -86,6 +95,13 @@ public class HessianProtocol extends AbstractProxyProtocol {
     @Override
     @SuppressWarnings("unchecked")
     protected <T> T doRefer(Class<T> serviceType, URL url) throws RpcException 
{
+        String generic = url.getParameter(Constants.GENERIC_KEY);
+        boolean isGeneric = ProtocolUtils.isGeneric(generic) || 
serviceType.equals(GenericService.class);
+        if (isGeneric) {
+            RpcContext.getContext().setAttachment(Constants.GENERIC_KEY, 
generic);
+            url = url.setPath(url.getPath() + "/" + Constants.GENERIC_KEY);
+        }
+
         HessianProxyFactory hessianProxyFactory = new HessianProxyFactory();
         boolean isHessian2Request = 
url.getParameter(Constants.HESSIAN2_REQUEST_KEY, 
Constants.DEFAULT_HESSIAN2_REQUEST);
         hessianProxyFactory.setHessian2Request(isHessian2Request);
@@ -96,6 +112,10 @@ public class HessianProtocol extends AbstractProxyProtocol {
             hessianProxyFactory.setConnectionFactory(new 
HttpClientConnectionFactory());
         } else if (client != null && client.length() > 0 && 
!Constants.DEFAULT_HTTP_CLIENT.equals(client)) {
             throw new IllegalStateException("Unsupported http protocol 
client=\"" + client + "\"!");
+        } else {
+            HessianConnectionFactory factory = new 
DubboHessianURLConnectionFactory();
+            factory.setHessianProxyFactory(hessianProxyFactory);
+            hessianProxyFactory.setConnectionFactory(factory);
         }
         int timeout = url.getParameter(Constants.TIMEOUT_KEY, 
Constants.DEFAULT_TIMEOUT);
         hessianProxyFactory.setConnectTimeout(timeout);
@@ -148,6 +168,16 @@ public class HessianProtocol extends AbstractProxyProtocol 
{
                 response.setStatus(500);
             } else {
                 
RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), 
request.getRemotePort());
+
+                Enumeration<String> enumeration = request.getHeaderNames();
+                while (enumeration.hasMoreElements()) {
+                    String key = enumeration.nextElement();
+                    if (key.startsWith(Constants.DEFAULT_EXCHANGER)) {
+                        
RpcContext.getContext().setAttachment(key.substring(Constants.DEFAULT_EXCHANGER.length()),
+                                request.getHeader(key));
+                    }
+                }
+
                 try {
                     skeleton.invoke(request.getInputStream(), 
response.getOutputStream());
                 } catch (Throwable e) {
diff --git 
a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnectionFactory.java
 
b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnectionFactory.java
index 033277d..b19cd27 100644
--- 
a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnectionFactory.java
+++ 
b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnectionFactory.java
@@ -16,6 +16,8 @@
  */
 package com.alibaba.dubbo.rpc.protocol.hessian;
 
+import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.rpc.RpcContext;
 import com.caucho.hessian.client.HessianConnection;
 import com.caucho.hessian.client.HessianConnectionFactory;
 import com.caucho.hessian.client.HessianProxyFactory;
@@ -41,7 +43,12 @@ public class HttpClientConnectionFactory implements 
HessianConnectionFactory {
 
     @Override
     public HessianConnection open(URL url) throws IOException {
-        return new HttpClientConnection(httpClient, url);
+        HttpClientConnection httpClientConnection = new 
HttpClientConnection(httpClient, url);
+        RpcContext context = RpcContext.getContext();
+        for (String key : context.getAttachments().keySet()) {
+            httpClientConnection.addHeader(Constants.DEFAULT_EXCHANGER + key, 
context.getAttachment(key));
+        }
+        return httpClientConnection;
     }
 
 }
diff --git 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocolTest.java
 
b/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocolTest.java
index 877ecd3..bae0333 100644
--- 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocolTest.java
+++ 
b/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocolTest.java
@@ -17,17 +17,29 @@
 package com.alibaba.dubbo.rpc.protocol.hessian;
 
 import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.common.beanutil.JavaBeanDescriptor;
+import com.alibaba.dubbo.common.beanutil.JavaBeanSerializeUtil;
 import com.alibaba.dubbo.common.extension.ExtensionLoader;
+import com.alibaba.dubbo.common.serialize.ObjectInput;
+import com.alibaba.dubbo.common.serialize.ObjectOutput;
+import com.alibaba.dubbo.common.serialize.Serialization;
+import com.alibaba.dubbo.common.serialize.nativejava.NativeJavaSerialization;
 import com.alibaba.dubbo.rpc.Exporter;
 import com.alibaba.dubbo.rpc.Invoker;
 import com.alibaba.dubbo.rpc.Protocol;
 import com.alibaba.dubbo.rpc.ProxyFactory;
+import com.alibaba.dubbo.rpc.RpcContext;
 import com.alibaba.dubbo.rpc.RpcException;
 import com.alibaba.dubbo.rpc.protocol.hessian.HessianServiceImpl.MyException;
 
+import com.alibaba.dubbo.rpc.service.GenericService;
 import org.junit.Assert;
 import org.junit.Test;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
 import static org.junit.Assert.fail;
 
 /**
@@ -53,6 +65,87 @@ public class HessianProtocolTest {
     }
 
     @Test
+    public void testGenericInvoke() {
+        HessianServiceImpl server = new HessianServiceImpl();
+        Assert.assertFalse(server.isCalled());
+        ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+        Protocol protocol = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+        URL url = URL.valueOf("hessian://127.0.0.1:5342/" + 
HessianService.class.getName() + "?version=1.0.0");
+        Exporter<HessianService> exporter = 
protocol.export(proxyFactory.getInvoker(server, HessianService.class, url));
+        Invoker<GenericService> invoker = protocol.refer(GenericService.class, 
url);
+        GenericService client = proxyFactory.getProxy(invoker, true);
+        String result = (String) client.$invoke("sayHello", new 
String[]{"java.lang.String"}, new Object[]{"haha"});
+        Assert.assertTrue(server.isCalled());
+        Assert.assertEquals("Hello, haha", result);
+        invoker.destroy();
+        exporter.unexport();
+    }
+
+    @Test
+    public void testGenericInvokeWithNativeJava() throws IOException, 
ClassNotFoundException {
+        HessianServiceImpl server = new HessianServiceImpl();
+        Assert.assertFalse(server.isCalled());
+        ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+        Protocol protocol = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+        URL url = URL.valueOf("hessian://127.0.0.1:5342/" + 
HessianService.class.getName() + "?version=1.0.0&generic=nativejava");
+        Exporter<HessianService> exporter = 
protocol.export(proxyFactory.getInvoker(server, HessianService.class, url));
+        Invoker<GenericService> invoker = protocol.refer(GenericService.class, 
url);
+        GenericService client = proxyFactory.getProxy(invoker);
+
+        Serialization serialization = new NativeJavaSerialization();
+        ByteArrayOutputStream byteArrayOutputStream = new 
ByteArrayOutputStream();
+
+        ObjectOutput objectOutput = serialization.serialize(url, 
byteArrayOutputStream);
+        objectOutput.writeObject("haha");
+        objectOutput.flushBuffer();
+
+        Object result = client.$invoke("sayHello", new 
String[]{"java.lang.String"}, new 
Object[]{byteArrayOutputStream.toByteArray()});
+        ByteArrayInputStream byteArrayInputStream = new 
ByteArrayInputStream((byte[]) result);
+        ObjectInput objectInput = serialization.deserialize(url, 
byteArrayInputStream);
+        Assert.assertTrue(server.isCalled());
+        Assert.assertEquals("Hello, haha", objectInput.readObject());
+        invoker.destroy();
+        exporter.unexport();
+    }
+
+    @Test
+    public void testGenericInvokeWithRpcContext() {
+        RpcContext.getContext().setAttachment("myContext", "123");
+
+        HessianServiceImpl server = new HessianServiceImpl();
+        ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+        Protocol protocol = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+        URL url = URL.valueOf("hessian://127.0.0.1:5342/" + 
HessianService.class.getName() + "?version=1.0.0");
+        Exporter<HessianService> exporter = 
protocol.export(proxyFactory.getInvoker(server, HessianService.class, url));
+        Invoker<GenericService> invoker = protocol.refer(GenericService.class, 
url);
+        GenericService client = proxyFactory.getProxy(invoker, true);
+        String result = (String) client.$invoke("context", new 
String[]{"java.lang.String"}, new Object[]{"haha"});
+        Assert.assertEquals("Hello, haha context, 123", result);
+        invoker.destroy();
+        exporter.unexport();
+    }
+
+    @Test
+    public void testGenericInvokeWithBean() {
+        HessianServiceImpl server = new HessianServiceImpl();
+        Assert.assertFalse(server.isCalled());
+        ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+        Protocol protocol = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+        URL url = URL.valueOf("hessian://127.0.0.1:5342/" + 
HessianService.class.getName() + "?version=1.0.0&generic=bean");
+        Exporter<HessianService> exporter = 
protocol.export(proxyFactory.getInvoker(server, HessianService.class, url));
+        Invoker<GenericService> invoker = protocol.refer(GenericService.class, 
url);
+        GenericService client = proxyFactory.getProxy(invoker);
+
+        JavaBeanDescriptor javaBeanDescriptor = 
JavaBeanSerializeUtil.serialize("haha");
+
+        Object result = client.$invoke("sayHello", new 
String[]{"java.lang.String"}, new Object[]{javaBeanDescriptor});
+        Assert.assertTrue(server.isCalled());
+        Assert.assertEquals("Hello, haha", 
JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) result));
+        invoker.destroy();
+        exporter.unexport();
+    }
+
+    @Test
     public void testOverload() {
         HessianServiceImpl server = new HessianServiceImpl();
         Assert.assertFalse(server.isCalled());
diff --git 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
 
b/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
index 8629425..9df4524 100644
--- 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
+++ 
b/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
@@ -30,4 +30,6 @@ public interface HessianService {
 
     String customException();
 
+    String context(String name);
+
 }
diff --git 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianServiceImpl.java
 
b/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianServiceImpl.java
index 855de0a..68d14b3 100644
--- 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianServiceImpl.java
+++ 
b/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianServiceImpl.java
@@ -16,6 +16,8 @@
  */
 package com.alibaba.dubbo.rpc.protocol.hessian;
 
+import com.alibaba.dubbo.rpc.RpcContext;
+
 /**
  * HessianServiceImpl
  */
@@ -53,6 +55,10 @@ public class HessianServiceImpl implements HessianService {
         throw new MyException("custom exception");
     }
 
+    public String context(String name) {
+        return "Hello, " + name + " context, " + 
RpcContext.getContext().getAttachment("myContext");
+    }
+
     static class MyException extends RuntimeException {
 
         private static final long serialVersionUID = -3051041116483629056L;
diff --git a/dubbo-rpc/dubbo-rpc-http/pom.xml b/dubbo-rpc/dubbo-rpc-http/pom.xml
index 427b70b..93d8a0f 100644
--- a/dubbo-rpc/dubbo-rpc-http/pom.xml
+++ b/dubbo-rpc/dubbo-rpc-http/pom.xml
@@ -48,5 +48,11 @@
             <groupId>org.springframework</groupId>
             <artifactId>spring-web</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo-serialization-jdk</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
\ No newline at end of file
diff --git 
a/dubbo-rpc/dubbo-rpc-http/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocol.java
 
b/dubbo-rpc/dubbo-rpc-http/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocol.java
index 27a5913..3fc9087 100644
--- 
a/dubbo-rpc/dubbo-rpc-http/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocol.java
+++ 
b/dubbo-rpc/dubbo-rpc-http/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocol.java
@@ -24,12 +24,16 @@ import com.alibaba.dubbo.remoting.http.HttpServer;
 import com.alibaba.dubbo.rpc.RpcContext;
 import com.alibaba.dubbo.rpc.RpcException;
 import com.alibaba.dubbo.rpc.protocol.AbstractProxyProtocol;
-
+import com.alibaba.dubbo.rpc.service.GenericService;
+import com.alibaba.dubbo.rpc.support.ProtocolUtils;
+import org.aopalliance.intercept.MethodInvocation;
 import org.springframework.remoting.RemoteAccessException;
 import 
org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor;
 import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
 import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
 import 
org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor;
+import org.springframework.remoting.support.RemoteInvocation;
+import org.springframework.remoting.support.RemoteInvocationFactory;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
@@ -74,6 +78,22 @@ public class HttpProtocol extends AbstractProxyProtocol {
             server = httpBinder.bind(url, new InternalHandler());
             serverMap.put(addr, server);
         }
+        final String path = url.getAbsolutePath();
+        skeletonMap.put(path, createExporter(impl, type));
+
+        final String genericPath = path + "/" + Constants.GENERIC_KEY;
+
+        skeletonMap.put(genericPath, createExporter(impl, 
GenericService.class));
+        return new Runnable() {
+            @Override
+            public void run() {
+                skeletonMap.remove(path);
+                skeletonMap.remove(genericPath);
+            }
+        };
+    }
+
+    private <T> HttpInvokerServiceExporter createExporter(T impl, Class<?> 
type) {
         final HttpInvokerServiceExporter httpServiceExporter = new 
HttpInvokerServiceExporter();
         httpServiceExporter.setServiceInterface(type);
         httpServiceExporter.setService(impl);
@@ -82,21 +102,33 @@ public class HttpProtocol extends AbstractProxyProtocol {
         } catch (Exception e) {
             throw new RpcException(e.getMessage(), e);
         }
-        final String path = url.getAbsolutePath();
-        skeletonMap.put(path, httpServiceExporter);
-        return new Runnable() {
-            @Override
-            public void run() {
-                skeletonMap.remove(path);
-            }
-        };
+        return httpServiceExporter;
     }
 
     @Override
     @SuppressWarnings("unchecked")
     protected <T> T doRefer(final Class<T> serviceType, final URL url) throws 
RpcException {
+        final String generic = url.getParameter(Constants.GENERIC_KEY);
+        final boolean isGeneric = ProtocolUtils.isGeneric(generic) || 
serviceType.equals(GenericService.class);
+
         final HttpInvokerProxyFactoryBean httpProxyFactoryBean = new 
HttpInvokerProxyFactoryBean();
-        httpProxyFactoryBean.setServiceUrl(url.toIdentityString());
+        httpProxyFactoryBean.setRemoteInvocationFactory(new 
RemoteInvocationFactory() {
+            @Override
+            public RemoteInvocation createRemoteInvocation(MethodInvocation 
methodInvocation) {
+                RemoteInvocation invocation = new 
HttpRemoteInvocation(methodInvocation);
+                if (isGeneric) {
+                    invocation.addAttribute(Constants.GENERIC_KEY, generic);
+                }
+                return invocation;
+            }
+        });
+
+        String key = url.toIdentityString();
+        if (isGeneric) {
+            key = key + "/" + Constants.GENERIC_KEY;
+        }
+
+        httpProxyFactoryBean.setServiceUrl(key);
         httpProxyFactoryBean.setServiceInterface(serviceType);
         String client = url.getParameter(Constants.CLIENT_KEY);
         if (client == null || client.length() == 0 || "simple".equals(client)) 
{
@@ -112,7 +144,8 @@ public class HttpProtocol extends AbstractProxyProtocol {
             
httpProxyFactoryBean.setHttpInvokerRequestExecutor(httpInvokerRequestExecutor);
         } else if ("commons".equals(client)) {
             HttpComponentsHttpInvokerRequestExecutor 
httpInvokerRequestExecutor = new HttpComponentsHttpInvokerRequestExecutor();
-            
httpInvokerRequestExecutor.setReadTimeout(url.getParameter(Constants.CONNECT_TIMEOUT_KEY,
 Constants.DEFAULT_CONNECT_TIMEOUT));
+            
httpInvokerRequestExecutor.setReadTimeout(url.getParameter(Constants.TIMEOUT_KEY,
 Constants.DEFAULT_TIMEOUT));
+            
httpInvokerRequestExecutor.setConnectTimeout(url.getParameter(Constants.CONNECT_TIMEOUT_KEY,
 Constants.DEFAULT_CONNECT_TIMEOUT));
             
httpProxyFactoryBean.setHttpInvokerRequestExecutor(httpInvokerRequestExecutor);
         } else {
             throw new IllegalStateException("Unsupported http protocol client 
" + client + ", only supported: simple, commons");
diff --git 
a/dubbo-rpc/dubbo-rpc-http/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpRemoteInvocation.java
 
b/dubbo-rpc/dubbo-rpc-http/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpRemoteInvocation.java
new file mode 100644
index 0000000..5054c4f
--- /dev/null
+++ 
b/dubbo-rpc/dubbo-rpc-http/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpRemoteInvocation.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 com.alibaba.dubbo.rpc.protocol.http;
+
+import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.common.utils.StringUtils;
+import com.alibaba.dubbo.rpc.RpcContext;
+import org.aopalliance.intercept.MethodInvocation;
+import org.springframework.remoting.support.RemoteInvocation;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class HttpRemoteInvocation extends RemoteInvocation {
+
+    private static final long serialVersionUID = 1L;
+    private static final String dubboAttachmentsAttrName = "dubbo.attachments";
+
+    public HttpRemoteInvocation(MethodInvocation methodInvocation) {
+        super(methodInvocation);
+        addAttribute(dubboAttachmentsAttrName, new HashMap<String, 
String>(RpcContext.getContext().getAttachments()));
+    }
+
+    @Override
+    public Object invoke(Object targetObject) throws NoSuchMethodException, 
IllegalAccessException,
+            InvocationTargetException {
+        RpcContext context = RpcContext.getContext();
+        context.setAttachments((Map<String, String>) 
getAttribute(dubboAttachmentsAttrName));
+
+        String generic = (String) getAttribute(Constants.GENERIC_KEY);
+        if (StringUtils.isNotEmpty(generic)) {
+            context.setAttachment(Constants.GENERIC_KEY, generic);
+        }
+        try {
+            return super.invoke(targetObject);
+        } finally {
+            context.setAttachments(null);
+
+        }
+    }
+}
diff --git 
a/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocolTest.java
 
b/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocolTest.java
new file mode 100644
index 0000000..014eed6
--- /dev/null
+++ 
b/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpProtocolTest.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 com.alibaba.dubbo.rpc.protocol.http;
+
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.common.beanutil.JavaBeanDescriptor;
+import com.alibaba.dubbo.common.beanutil.JavaBeanSerializeUtil;
+import com.alibaba.dubbo.common.extension.ExtensionLoader;
+import com.alibaba.dubbo.common.serialize.ObjectInput;
+import com.alibaba.dubbo.common.serialize.ObjectOutput;
+import com.alibaba.dubbo.common.serialize.Serialization;
+import com.alibaba.dubbo.common.serialize.nativejava.NativeJavaSerialization;
+import com.alibaba.dubbo.rpc.*;
+import com.alibaba.dubbo.rpc.service.GenericService;
+import junit.framework.Assert;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import static org.junit.Assert.fail;
+
+/**
+ * HttpProtocolTest
+ */
+public class HttpProtocolTest {
+
+    @Test
+    public void testHttpProtocol() {
+        HttpServiceImpl server = new HttpServiceImpl();
+        Assert.assertFalse(server.isCalled());
+        ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+        Protocol protocol = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+        URL url = URL.valueOf("http://127.0.0.1:5342/"; + 
HttpService.class.getName() + "?version=1.0.0");
+        Exporter<HttpService> exporter = 
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+        Invoker<HttpService> invoker = protocol.refer(HttpService.class, url);
+        HttpService client = proxyFactory.getProxy(invoker);
+        String result = client.sayHello("haha");
+        Assert.assertTrue(server.isCalled());
+        Assert.assertEquals("Hello, haha", result);
+        invoker.destroy();
+        exporter.unexport();
+    }
+
+    @Test
+    public void testGenericInvoke() {
+        HttpServiceImpl server = new HttpServiceImpl();
+        Assert.assertFalse(server.isCalled());
+        ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+        Protocol protocol = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+        URL url = URL.valueOf("http://127.0.0.1:5342/"; + 
HttpService.class.getName() + "?version=1.0.0");
+        Exporter<HttpService> exporter = 
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+        Invoker<GenericService> invoker = protocol.refer(GenericService.class, 
url);
+        GenericService client = proxyFactory.getProxy(invoker, true);
+        String result = (String) client.$invoke("sayHello", new 
String[]{"java.lang.String"}, new Object[]{"haha"});
+        Assert.assertTrue(server.isCalled());
+        Assert.assertEquals("Hello, haha", result);
+        invoker.destroy();
+        exporter.unexport();
+    }
+
+    @Test
+    public void testGenericInvokeWithNativeJava() throws IOException, 
ClassNotFoundException {
+        HttpServiceImpl server = new HttpServiceImpl();
+        Assert.assertFalse(server.isCalled());
+        ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+        Protocol protocol = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+        URL url = URL.valueOf("http://127.0.0.1:5342/"; + 
HttpService.class.getName() + "?version=1.0.0&generic=nativejava");
+        Exporter<HttpService> exporter = 
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+        Invoker<GenericService> invoker = protocol.refer(GenericService.class, 
url);
+        GenericService client = proxyFactory.getProxy(invoker);
+
+        Serialization serialization = new NativeJavaSerialization();
+        ByteArrayOutputStream byteArrayOutputStream = new 
ByteArrayOutputStream();
+
+        ObjectOutput objectOutput = serialization.serialize(url, 
byteArrayOutputStream);
+        objectOutput.writeObject("haha");
+        objectOutput.flushBuffer();
+
+        Object result = client.$invoke("sayHello", new 
String[]{"java.lang.String"}, new 
Object[]{byteArrayOutputStream.toByteArray()});
+        ByteArrayInputStream byteArrayInputStream = new 
ByteArrayInputStream((byte[]) result);
+        ObjectInput objectInput = serialization.deserialize(url, 
byteArrayInputStream);
+        Assert.assertTrue(server.isCalled());
+        Assert.assertEquals("Hello, haha", objectInput.readObject());
+        invoker.destroy();
+        exporter.unexport();
+    }
+
+    @Test
+    public void testGenericInvokeWithBean() {
+        HttpServiceImpl server = new HttpServiceImpl();
+        Assert.assertFalse(server.isCalled());
+        ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+        Protocol protocol = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+        URL url = URL.valueOf("http://127.0.0.1:5342/"; + 
HttpService.class.getName() + "?version=1.0.0&generic=bean");
+        Exporter<HttpService> exporter = 
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+        Invoker<GenericService> invoker = protocol.refer(GenericService.class, 
url);
+        GenericService client = proxyFactory.getProxy(invoker);
+
+        JavaBeanDescriptor javaBeanDescriptor = 
JavaBeanSerializeUtil.serialize("haha");
+
+        Object result = client.$invoke("sayHello", new 
String[]{"java.lang.String"}, new Object[]{javaBeanDescriptor});
+        Assert.assertTrue(server.isCalled());
+        Assert.assertEquals("Hello, haha", 
JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) result));
+        invoker.destroy();
+        exporter.unexport();
+    }
+
+    @Test
+    public void testOverload() {
+        HttpServiceImpl server = new HttpServiceImpl();
+        Assert.assertFalse(server.isCalled());
+        ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+        Protocol protocol = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+        URL url = URL.valueOf("http://127.0.0.1:5342/"; + 
HttpService.class.getName() + 
"?version=1.0.0&hessian.overload.method=true&hessian2.request=false");
+        Exporter<HttpService> exporter = 
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+        Invoker<HttpService> invoker = protocol.refer(HttpService.class, url);
+        HttpService client = proxyFactory.getProxy(invoker);
+        String result = client.sayHello("haha");
+        Assert.assertEquals("Hello, haha", result);
+        result = client.sayHello("haha", 1);
+        Assert.assertEquals("Hello, haha. ", result);
+        invoker.destroy();
+        exporter.unexport();
+    }
+
+    @Test
+    public void testSimpleClient() {
+        HttpServiceImpl server = new HttpServiceImpl();
+        Assert.assertFalse(server.isCalled());
+        ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+        Protocol protocol = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+        URL url = URL.valueOf("http://127.0.0.1:5342/"; + 
HttpService.class.getName() + "?version=1.0.0&client=simple");
+        Exporter<HttpService> exporter = 
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+        Invoker<HttpService> invoker = protocol.refer(HttpService.class, url);
+        HttpService client = proxyFactory.getProxy(invoker);
+        String result = client.sayHello("haha");
+        Assert.assertTrue(server.isCalled());
+        Assert.assertEquals("Hello, haha", result);
+        invoker.destroy();
+        exporter.unexport();
+    }
+
+    @Test
+    public void testTimeOut() {
+        HttpServiceImpl server = new HttpServiceImpl();
+        ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+        Protocol protocol = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+        URL url = URL.valueOf("http://127.0.0.1:5342/"; + 
HttpService.class.getName() + "?version=1.0.0&timeout=10");
+        Exporter<HttpService> exporter = 
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+        Invoker<HttpService> invoker = protocol.refer(HttpService.class, url);
+        HttpService client = proxyFactory.getProxy(invoker);
+        try {
+            client.timeOut(6000);
+            fail();
+        } catch (RpcException expected) {
+            Assert.assertEquals(true, expected.isTimeout());
+        } finally {
+            invoker.destroy();
+            exporter.unexport();
+        }
+
+    }
+
+    @Test
+    public void testCustomException() {
+        HttpServiceImpl server = new HttpServiceImpl();
+        ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+        Protocol protocol = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+        URL url = URL.valueOf("http://127.0.0.1:5342/"; + 
HttpService.class.getName() + "?version=1.0.0");
+        Exporter<HttpService> exporter = 
protocol.export(proxyFactory.getInvoker(server, HttpService.class, url));
+        Invoker<HttpService> invoker = protocol.refer(HttpService.class, url);
+        HttpService client = proxyFactory.getProxy(invoker);
+        try {
+            client.customException();
+            fail();
+        } catch (HttpServiceImpl.MyException expected) {
+        }
+        invoker.destroy();
+        exporter.unexport();
+    }
+
+}
diff --git 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
 
b/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpService.java
similarity index 87%
copy from 
dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
copy to 
dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpService.java
index 8629425..0d0d22c 100644
--- 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
+++ 
b/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpService.java
@@ -14,16 +14,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.alibaba.dubbo.rpc.protocol.hessian;
+package com.alibaba.dubbo.rpc.protocol.http;
 
 
 /**
- * HessianService
+ * HttpService
  */
-public interface HessianService {
+public interface HttpService {
 
     String sayHello(String name);
-
+    
     String sayHello(String name, int times);
 
     void timeOut(int millis);
diff --git 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianServiceImpl.java
 
b/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpServiceImpl.java
similarity index 90%
copy from 
dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianServiceImpl.java
copy to 
dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpServiceImpl.java
index 855de0a..1c78b3b 100644
--- 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianServiceImpl.java
+++ 
b/dubbo-rpc/dubbo-rpc-http/src/test/java/com/alibaba/dubbo/rpc/protocol/http/HttpServiceImpl.java
@@ -14,12 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.alibaba.dubbo.rpc.protocol.hessian;
+package com.alibaba.dubbo.rpc.protocol.http;
 
 /**
- * HessianServiceImpl
+ * HttpServiceImpl
  */
-public class HessianServiceImpl implements HessianService {
+public class HttpServiceImpl implements HttpService {
 
     private boolean called;
 
@@ -27,7 +27,7 @@ public class HessianServiceImpl implements HessianService {
         called = true;
         return "Hello, " + name;
     }
-
+    
     public String sayHello(String name, int times) {
         called = true;
         StringBuilder sb = new StringBuilder();
diff --git a/dubbo-rpc/dubbo-rpc-rest/pom.xml b/dubbo-rpc/dubbo-rpc-rest/pom.xml
index 026e2c2..724ae6d 100644
--- a/dubbo-rpc/dubbo-rpc-rest/pom.xml
+++ b/dubbo-rpc/dubbo-rpc-rest/pom.xml
@@ -105,5 +105,11 @@
             <artifactId>netty-all</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo-serialization-jdk</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
\ No newline at end of file
diff --git 
a/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestProtocolTest.java
 
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestProtocolTest.java
new file mode 100644
index 0000000..4764cf6
--- /dev/null
+++ 
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestProtocolTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 com.alibaba.dubbo.rpc.protol.rest;
+
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.common.extension.ExtensionLoader;
+import com.alibaba.dubbo.rpc.*;
+import junit.framework.Assert;
+import org.junit.Test;
+
+/**
+ * RestProtocolTest
+ */
+public class RestProtocolTest {
+
+    private Protocol protocol = 
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+    private ProxyFactory proxyFactory = 
ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+
+    @Test
+    public void testRestProtocol() {
+        
ServiceClassHolder.getInstance().pushServiceClass(RestServiceImpl.class);
+        RestServiceImpl server = new RestServiceImpl();
+        Assert.assertFalse(server.isCalled());
+        URL url = URL.valueOf("rest://127.0.0.1:5342/rest/say1?version=1.0.0");
+        Exporter<RestService> exporter = 
protocol.export(proxyFactory.getInvoker(server, RestService.class, url));
+        Invoker<RestService> invoker = protocol.refer(RestService.class, url);
+        RestService client = proxyFactory.getProxy(invoker);
+        String result = client.sayHello("haha");
+        Assert.assertTrue(server.isCalled());
+        Assert.assertEquals("Hello, haha", result);
+        invoker.destroy();
+        exporter.unexport();
+    }
+}
diff --git 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
 
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestService.java
similarity index 72%
copy from 
dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
copy to 
dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestService.java
index 8629425..30441b2 100644
--- 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
+++ 
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestService.java
@@ -14,20 +14,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.alibaba.dubbo.rpc.protocol.hessian;
+package com.alibaba.dubbo.rpc.protol.rest;
 
 
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MediaType;
+
 /**
- * HessianService
+ * RestService
  */
-public interface HessianService {
+@Path("/rest")
+public interface RestService {
 
+    @POST
+    @Path("/say1")
+    @Consumes({MediaType.TEXT_PLAIN})
     String sayHello(String name);
 
-    String sayHello(String name, int times);
-
-    void timeOut(int millis);
-
-    String customException();
-
 }
diff --git 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
 
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestServiceImpl.java
similarity index 70%
copy from 
dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
copy to 
dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestServiceImpl.java
index 8629425..3de80d2 100644
--- 
a/dubbo-rpc/dubbo-rpc-hessian/src/test/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianService.java
+++ 
b/dubbo-rpc/dubbo-rpc-rest/src/test/java/com/alibaba/dubbo/rpc/protol/rest/RestServiceImpl.java
@@ -14,20 +14,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.alibaba.dubbo.rpc.protocol.hessian;
-
+package com.alibaba.dubbo.rpc.protol.rest;
 
 /**
- * HessianService
+ * RestServiceImpl
  */
-public interface HessianService {
 
-    String sayHello(String name);
+public class RestServiceImpl implements RestService {
 
-    String sayHello(String name, int times);
+    private boolean called;
 
-    void timeOut(int millis);
+    public String sayHello(String name) {
+        called = true;
+        return "Hello, " + name;
+    }
 
-    String customException();
 
+    public boolean isCalled() {
+        return called;
+    }
 }

-- 
To stop receiving notification emails like this one, please contact
liu...@apache.org.

Reply via email to