diff --git a/dubbo-remoting-http/pom.xml b/dubbo-remoting-http/pom.xml
index 31fceaedd9..d3a45efc8e 100644
--- a/dubbo-remoting-http/pom.xml
+++ b/dubbo-remoting-http/pom.xml
@@ -41,6 +41,6 @@
org.mortbay.jetty
jetty
-
+
\ No newline at end of file
diff --git a/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/HttpBinder.java b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/HttpBinder.java
new file mode 100644
index 0000000000..a7356bbb5c
--- /dev/null
+++ b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/HttpBinder.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1999-2011 Alibaba Group.
+ *
+ * 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 com.alibaba.dubbo.remoting.http;
+
+import com.alibaba.dubbo.common.Adaptive;
+import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.common.Extension;
+import com.alibaba.dubbo.common.URL;
+
+/**
+ * HttpBinder
+ *
+ * @author william.liangf
+ */
+@Extension("jetty")
+public interface HttpBinder {
+
+ /**
+ * bind the server.
+ *
+ * @param url server url.
+ * @return server.
+ */
+ @Adaptive({Constants.SERVER_KEY})
+ HttpServer bind(URL url, HttpHandler handler);
+
+}
\ No newline at end of file
diff --git a/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/HttpProcessor.java b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/HttpHandler.java
similarity index 85%
rename from dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/HttpProcessor.java
rename to dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/HttpHandler.java
index 4c9fd30cd7..6550a3b966 100644
--- a/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/HttpProcessor.java
+++ b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/HttpHandler.java
@@ -26,8 +26,8 @@ import javax.servlet.http.HttpServletResponse;
*
* @author william.liangf
*/
-public interface HttpProcessor {
-
+public interface HttpHandler {
+
/**
* invoke.
*
@@ -36,6 +36,6 @@ public interface HttpProcessor {
* @throws IOException
* @throws ServletException
*/
- public abstract void invoke(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException;
-
+ void handle(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException;
+
}
\ No newline at end of file
diff --git a/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/HttpServer.java b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/HttpServer.java
index ae4826fb5b..37b9ae2782 100644
--- a/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/HttpServer.java
+++ b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/HttpServer.java
@@ -15,12 +15,56 @@
*/
package com.alibaba.dubbo.remoting.http;
-public interface HttpServer {
+import java.net.InetSocketAddress;
- void start();
-
- void stop();
-
- int getPort();
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.remoting.Resetable;
+public interface HttpServer extends Resetable {
+
+ /**
+ * get http handler.
+ *
+ * @return http handler.
+ */
+ HttpHandler getHttpHandler();
+
+ /**
+ * get url.
+ *
+ * @return url
+ */
+ URL getUrl();
+
+ /**
+ * get local address.
+ *
+ * @return local address.
+ */
+ InetSocketAddress getLocalAddress();
+
+ /**
+ * close the channel.
+ */
+ void close();
+
+ /**
+ * Graceful close the channel.
+ */
+ void close(int timeout);
+
+ /**
+ * is bound.
+ *
+ * @return bound
+ */
+ boolean isBound();
+
+ /**
+ * is closed.
+ *
+ * @return closed
+ */
+ boolean isClosed();
+
}
\ No newline at end of file
diff --git a/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/JettyHttpServer.java b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/JettyHttpServer.java
deleted file mode 100644
index 7342b8aa61..0000000000
--- a/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/JettyHttpServer.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 1999-2011 Alibaba Group.
- *
- * 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 com.alibaba.dubbo.remoting.http;
-
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.nio.SelectChannelConnector;
-import org.mortbay.jetty.servlet.ServletHandler;
-import org.mortbay.jetty.servlet.ServletHolder;
-import org.mortbay.thread.QueuedThreadPool;
-
-import com.alibaba.dubbo.common.logger.Logger;
-import com.alibaba.dubbo.common.logger.LoggerFactory;
-import com.alibaba.dubbo.common.utils.NetUtils;
-
-public class JettyHttpServer implements HttpServer {
-
- private static final Logger logger = LoggerFactory.getLogger(JettyHttpServer.class);
-
- private String host;
-
- private int port;
-
- private int threads;
-
- private Server server;
-
- public JettyHttpServer(int port, int threads) {
- this.port = port;
- this.threads = threads;
- }
-
- public JettyHttpServer(String host, int port, int threads) {
- this.host = host;
- this.port = port;
- this.threads = threads;
- }
-
- public void start() {
- QueuedThreadPool threadPool = new QueuedThreadPool();
- threadPool.setDaemon(true);
- threadPool.setMaxThreads(threads);
- threadPool.setMinThreads(threads);
-
- SelectChannelConnector connector = new SelectChannelConnector();
- if (NetUtils.isValidLocalHost(host)) {
- connector.setHost(host);
- }
- connector.setPort(port);
-
- ServletHandler handler = new ServletHandler();
- ServletHolder holder = handler.addServletWithMapping(ServiceDispatcherServlet.class, "/*");
- holder.setInitOrder(1);
-
- server = new Server();
- server.setThreadPool(threadPool);
- server.addConnector(connector);
- server.addHandler(handler);
- try {
- server.start();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to start jetty server on " + host + ":" + port + ", cause: " + e.getMessage(), e);
- }
- }
-
- public void stop() {
- if (server != null) {
- try {
- server.stop();
- } catch (Exception e) {
- logger.warn(e.getMessage(), e);
- }
- }
- }
-
- public int getPort() {
- return port;
- }
-
-}
\ No newline at end of file
diff --git a/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/jetty/JettyHttpBinder.java b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/jetty/JettyHttpBinder.java
new file mode 100644
index 0000000000..dc67f11b18
--- /dev/null
+++ b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/jetty/JettyHttpBinder.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1999-2011 Alibaba Group.
+ *
+ * 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 com.alibaba.dubbo.remoting.http.jetty;
+
+import com.alibaba.dubbo.common.Extension;
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.remoting.http.HttpHandler;
+import com.alibaba.dubbo.remoting.http.HttpServer;
+import com.alibaba.dubbo.remoting.http.HttpBinder;
+
+/**
+ * JettyHttpTransporter
+ *
+ * @author william.liangf
+ */
+@Extension("jetty")
+public class JettyHttpBinder implements HttpBinder {
+
+ public HttpServer bind(URL url, HttpHandler handler) {
+ return new JettyHttpServer(url, handler);
+ }
+
+}
\ No newline at end of file
diff --git a/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/jetty/JettyHttpServer.java b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/jetty/JettyHttpServer.java
new file mode 100644
index 0000000000..cb30752fff
--- /dev/null
+++ b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/jetty/JettyHttpServer.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 1999-2011 Alibaba Group.
+ *
+ * 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 com.alibaba.dubbo.remoting.http.jetty;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.handler.AbstractHandler;
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.thread.QueuedThreadPool;
+
+import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.common.logger.Logger;
+import com.alibaba.dubbo.common.logger.LoggerFactory;
+import com.alibaba.dubbo.common.utils.NetUtils;
+import com.alibaba.dubbo.remoting.http.HttpHandler;
+import com.alibaba.dubbo.remoting.http.support.AbstractHttpServer;
+
+public class JettyHttpServer extends AbstractHttpServer {
+
+ private static final Logger logger = LoggerFactory.getLogger(JettyHttpServer.class);
+
+ private Server server;
+
+ public JettyHttpServer(URL url, final HttpHandler handler){
+ super(url, handler);
+
+ int threads = url.getParameter(Constants.THREADS_KEY, Constants.DEFAULT_THREADS);
+ QueuedThreadPool threadPool = new QueuedThreadPool();
+ threadPool.setDaemon(true);
+ threadPool.setMaxThreads(threads);
+ threadPool.setMinThreads(threads);
+
+ SelectChannelConnector connector = new SelectChannelConnector();
+ if (NetUtils.isValidLocalHost(url.getHost())) {
+ connector.setHost(url.getHost());
+ }
+ connector.setPort(url.getPort());
+
+ server = new Server();
+ server.setThreadPool(threadPool);
+ server.addConnector(connector);
+ server.addHandler(new AbstractHandler() {
+ public void handle(String target, HttpServletRequest request,
+ HttpServletResponse response, int dispatch) throws IOException,
+ ServletException {
+ handler.handle(request, response);
+ }
+ });
+
+ try {
+ server.start();
+ } catch (Exception e) {
+ throw new IllegalStateException("Failed to start jetty server on " + url.getAddress() + ", cause: "
+ + e.getMessage(), e);
+ }
+ }
+
+ public void close() {
+ super.close();
+ if (server != null) {
+ try {
+ server.stop();
+ } catch (Exception e) {
+ logger.warn(e.getMessage(), e);
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/ServiceDispatcherServlet.java b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/servlet/DispatcherServlet.java
similarity index 51%
rename from dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/ServiceDispatcherServlet.java
rename to dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/servlet/DispatcherServlet.java
index c65c2902d8..29e7a3455a 100644
--- a/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/ServiceDispatcherServlet.java
+++ b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/servlet/DispatcherServlet.java
@@ -13,57 +13,45 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.alibaba.dubbo.remoting.http;
+package com.alibaba.dubbo.remoting.http.servlet;
-import java.io.IOException;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.alibaba.dubbo.remoting.http.HttpHandler;
/**
* Service dispatcher Servlet.
*
* @author qian.lei
*/
-public class ServiceDispatcherServlet extends HttpServlet {
+public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 5766349180380479888L;
- private static final String FORM_CONTENT_TYPE = "application/x-www-form-urlencoded";
-
- private static final Map processors = new ConcurrentHashMap();
+ private static final Map handlers = new ConcurrentHashMap();
- public static void addProcessor(int port, String uri, HttpProcessor processor) {
- processors.put(key(port, uri), processor);
+ static void addHttpInvoker(int port, HttpHandler processor) {
+ handlers.put(port, processor);
}
- public static void removeProcessor(int port, String uri) {
- processors.remove(key(port, uri));
- }
-
- private static String key(int port, String uri) {
- return port + ":" + (uri.startsWith("/") ? uri : "/" + uri);
+ static void removeHttpInvoker(int port) {
+ handlers.remove(port);
}
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
- String uri = request.getRequestURI();
- String contentType = request.getContentType();
- if (contentType == null || FORM_CONTENT_TYPE.equalsIgnoreCase(contentType)) {
- int i = uri.lastIndexOf('/');
- if (i >= 0) {
- uri = uri.substring(0, i);
- }
- }
- HttpProcessor processor = processors.get(key(request.getLocalPort(), uri));
- if( processor == null ) {// service not found.
+ HttpHandler handler = handlers.get(request.getLocalPort());
+ if( handler == null ) {// service not found.
response.sendError(HttpServletResponse.SC_NOT_FOUND, "Service not found.");
} else {
- processor.invoke(request, response);
+ handler.handle(request, response);
}
}
diff --git a/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/servlet/ServletHttpBinder.java b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/servlet/ServletHttpBinder.java
new file mode 100644
index 0000000000..ef459ee34a
--- /dev/null
+++ b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/servlet/ServletHttpBinder.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1999-2011 Alibaba Group.
+ *
+ * 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 com.alibaba.dubbo.remoting.http.servlet;
+
+import com.alibaba.dubbo.common.Adaptive;
+import com.alibaba.dubbo.common.Extension;
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.remoting.http.HttpBinder;
+import com.alibaba.dubbo.remoting.http.HttpHandler;
+import com.alibaba.dubbo.remoting.http.HttpServer;
+
+/**
+ * ServletHttpTransporter
+ *
+ * @author william.liangf
+ */
+@Extension("servlet")
+public class ServletHttpBinder implements HttpBinder {
+
+ @Adaptive()
+ public HttpServer bind(URL url, HttpHandler handler) {
+ return new ServletHttpServer(url, handler);
+ }
+
+}
\ No newline at end of file
diff --git a/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/ServletHttpServer.java b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/servlet/ServletHttpServer.java
similarity index 57%
rename from dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/ServletHttpServer.java
rename to dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/servlet/ServletHttpServer.java
index 93a0b6a9e2..0b9433a85e 100644
--- a/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/ServletHttpServer.java
+++ b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/servlet/ServletHttpServer.java
@@ -13,24 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.alibaba.dubbo.remoting.http;
+package com.alibaba.dubbo.remoting.http.servlet;
-public class ServletHttpServer implements HttpServer {
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.remoting.http.HttpHandler;
+import com.alibaba.dubbo.remoting.http.support.AbstractHttpServer;
+
+public class ServletHttpServer extends AbstractHttpServer {
- private final int port;
-
- public ServletHttpServer(int port){
- this.port = port;
+ public ServletHttpServer(URL url, HttpHandler handler){
+ super(url, handler);
+ DispatcherServlet.addHttpInvoker(url.getPort(), handler);
}
-
- public void start() {
- }
-
- public void stop() {
- }
-
- public int getPort() {
- return port;
- }
-
+
}
\ No newline at end of file
diff --git a/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/support/AbstractHttpServer.java b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/support/AbstractHttpServer.java
new file mode 100644
index 0000000000..49febe9b95
--- /dev/null
+++ b/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/support/AbstractHttpServer.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1999-2011 Alibaba Group.
+ *
+ * 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 com.alibaba.dubbo.remoting.http.support;
+
+import java.net.InetSocketAddress;
+
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.remoting.http.HttpHandler;
+import com.alibaba.dubbo.remoting.http.HttpServer;
+
+/**
+ * AbstractHttpServer
+ *
+ * @author william.liangf
+ */
+public abstract class AbstractHttpServer implements HttpServer {
+
+ private final URL url;
+
+ private final HttpHandler handler;
+
+ private volatile boolean closed;
+
+ public AbstractHttpServer(URL url, HttpHandler handler){
+ if (url == null) {
+ throw new IllegalArgumentException("url == null");
+ }
+ if (handler == null) {
+ throw new IllegalArgumentException("handler == null");
+ }
+ this.url = url;
+ this.handler = handler;
+ }
+
+ public HttpHandler getHttpHandler() {
+ return handler;
+ }
+
+ public URL getUrl() {
+ return url;
+ }
+
+ public void reset(URL url) {
+ }
+
+ public boolean isBound() {
+ return true;
+ }
+
+ public InetSocketAddress getLocalAddress() {
+ return url.toInetSocketAddress();
+ }
+
+ public void close() {
+ closed = true;
+ }
+
+ public void close(int timeout) {
+ close();
+ }
+
+ public boolean isClosed() {
+ return closed;
+ }
+
+}
\ No newline at end of file
diff --git a/dubbo-remoting-http/src/main/resources/META-INF/services/com.alibaba.dubbo.remoting.http.HttpBinder b/dubbo-remoting-http/src/main/resources/META-INF/services/com.alibaba.dubbo.remoting.http.HttpBinder
new file mode 100644
index 0000000000..46f65c42ed
--- /dev/null
+++ b/dubbo-remoting-http/src/main/resources/META-INF/services/com.alibaba.dubbo.remoting.http.HttpBinder
@@ -0,0 +1,2 @@
+com.alibaba.dubbo.remoting.http.servlet.ServletHttpBinder
+com.alibaba.dubbo.remoting.http.jetty.JettyHttpBinder
\ No newline at end of file
diff --git a/dubbo-remoting/src/main/java/com/alibaba/dubbo/remoting/exchange/support/SimpleFuture.java b/dubbo-remoting/src/main/java/com/alibaba/dubbo/remoting/exchange/support/SimpleFuture.java
new file mode 100644
index 0000000000..c09a0f04c7
--- /dev/null
+++ b/dubbo-remoting/src/main/java/com/alibaba/dubbo/remoting/exchange/support/SimpleFuture.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 1999-2011 Alibaba Group.
+ *
+ * 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 com.alibaba.dubbo.remoting.exchange.support;
+
+import com.alibaba.dubbo.remoting.RemotingException;
+import com.alibaba.dubbo.remoting.exchange.ResponseCallback;
+import com.alibaba.dubbo.remoting.exchange.ResponseFuture;
+
+/**
+ * SimpleFuture
+ *
+ * @author william.liangf
+ */
+public class SimpleFuture implements ResponseFuture {
+
+ private final Object value;
+
+ public SimpleFuture(Object value){
+ this.value = value;
+ }
+
+ public Object get() throws RemotingException {
+ return value;
+ }
+
+ public Object get(int timeoutInMillis) throws RemotingException {
+ return value;
+ }
+
+ public void setCallback(ResponseCallback callback) {
+ callback.done(value);
+ }
+
+ public boolean isDone() {
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/dubbo-rpc-hessian/pom.xml b/dubbo-rpc-hessian/pom.xml
index 5ff8ae46dd..891c06128e 100644
--- a/dubbo-rpc-hessian/pom.xml
+++ b/dubbo-rpc-hessian/pom.xml
@@ -42,6 +42,12 @@
com.caucho
hessian
+
+
+ org.apache.httpcomponents
+ httpclient
+ provided
+ true
\ No newline at end of file
diff --git a/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocol.java b/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocol.java
index 41cf0d8a17..ff6e317e82 100644
--- a/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocol.java
+++ b/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianProtocol.java
@@ -15,22 +15,25 @@
*/
package com.alibaba.dubbo.rpc.protocol.hessian;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import com.alibaba.dubbo.common.Constants;
-import com.alibaba.dubbo.common.Extension;
-import com.alibaba.dubbo.common.URL;
-import com.alibaba.dubbo.remoting.http.HttpServer;
-import com.alibaba.dubbo.remoting.http.JettyHttpServer;
-import com.alibaba.dubbo.remoting.http.ServiceDispatcherServlet;
-import com.alibaba.dubbo.remoting.http.ServletHttpServer;
-import com.alibaba.dubbo.rpc.Exporter;
-import com.alibaba.dubbo.rpc.Invoker;
-import com.alibaba.dubbo.rpc.ProxyFactory;
-import com.alibaba.dubbo.rpc.RpcException;
-import com.alibaba.dubbo.rpc.protocol.AbstractProtocol;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.alibaba.dubbo.common.Extension;
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.remoting.http.HttpBinder;
+import com.alibaba.dubbo.remoting.http.HttpHandler;
+import com.alibaba.dubbo.remoting.http.HttpServer;
+import com.alibaba.dubbo.rpc.Exporter;
+import com.alibaba.dubbo.rpc.Invoker;
+import com.alibaba.dubbo.rpc.ProxyFactory;
+import com.alibaba.dubbo.rpc.RpcException;
+import com.alibaba.dubbo.rpc.protocol.AbstractProtocol;
/**
* http rpc support.
@@ -42,7 +45,13 @@ public class HessianProtocol extends AbstractProtocol {
private final Map serverMap = new ConcurrentHashMap();
- private ProxyFactory proxyFactory;
+ private HttpBinder httpTransporter;
+
+ private ProxyFactory proxyFactory;
+
+ public void setHttpTransporter(HttpBinder httpTransporter) {
+ this.httpTransporter = httpTransporter;
+ }
public void setProxyFactory(ProxyFactory proxyFactory) {
this.proxyFactory = proxyFactory;
@@ -50,40 +59,37 @@ public class HessianProtocol extends AbstractProtocol {
public int getDefaultPort() {
return 80;
+ }
+
+ private class HessianHandler implements HttpHandler {
+
+ public void handle(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ String uri = request.getRequestURI();
+ HessianRpcExporter> exporter = (HessianRpcExporter>) exporterMap.get(uri);
+ exporter.handle(request, response);
+ }
+
}
public Exporter export(Invoker invoker) throws RpcException {
- URL url = invoker.getUrl();
-
- final String uri = url.getPath(); // service uri also exporter cache key.
-
- int threads = url.getParameter(Constants.THREADS_KEY, Constants.DEFAULT_THREADS);
+ final URL url = invoker.getUrl();
+ final String uri = url.getAbsolutePath(); // service uri also exporter cache key.
String addr = url.getHost() + ":" + url.getPort();
HttpServer server = serverMap.get(addr);
if (server == null) {
- String type = url.getParameter(Constants.SERVER_KEY, "jetty");
- if ("servlet".equals(type)) {
- server = new ServletHttpServer(url.getPort());
- } else if ("jetty".equals(type)) {
- // 和Dubbo协议一样,总是绑定到0.0.0.0上
- server = new JettyHttpServer(url.getPort(), threads);
- } else {
- throw new IllegalArgumentException("Unsupported http server " + type
- + ", only support servlet, jetty!");
- }
- server.start();
+ server = httpTransporter.bind(url, new HessianHandler());
serverMap.put(addr, server);
}
HessianRpcExporter exporter = new HessianRpcExporter(invoker, proxyFactory) {
public void unexport() {
super.unexport();
- exporterMap.remove(uri);
+ exporterMap.remove(uri);
}
};
exporterMap.put(uri, exporter);
- ServiceDispatcherServlet.addProcessor(url.getPort(), uri, exporter);
return exporter;
}
@@ -100,9 +106,9 @@ public class HessianProtocol extends AbstractProtocol {
if (server != null) {
try {
if (logger.isInfoEnabled()) {
- logger.info("Close hessian server 0.0.0.0:" + server.getPort());
+ logger.info("Close hessian server " + server.getUrl());
}
- server.stop();
+ server.close();
} catch (Throwable t) {
logger.warn(t.getMessage(), t);
}
diff --git a/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianRpcExporter.java b/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianRpcExporter.java
index 71d7395ad6..6994d2ee06 100644
--- a/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianRpcExporter.java
+++ b/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianRpcExporter.java
@@ -21,7 +21,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import com.alibaba.dubbo.remoting.http.HttpProcessor;
+import com.alibaba.dubbo.remoting.http.HttpHandler;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.ProxyFactory;
import com.alibaba.dubbo.rpc.RpcContext;
@@ -33,7 +33,7 @@ import com.caucho.hessian.server.HessianSkeleton;
*
* @author qian.lei
*/
-public class HessianRpcExporter extends AbstractExporter implements HttpProcessor {
+public class HessianRpcExporter extends AbstractExporter implements HttpHandler {
private HessianSkeleton skeleton;
@@ -42,9 +42,9 @@ public class HessianRpcExporter extends AbstractExporter implements HttpPr
skeleton = new HessianSkeleton(proxyFactory.getProxy(invoker), invoker.getInterface());
}
- public void invoke(HttpServletRequest request, HttpServletResponse response)
+ public void handle(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
- if (request.getMethod().equalsIgnoreCase("POST") == false) {
+ if (! request.getMethod().equalsIgnoreCase("POST")) {
response.setStatus(500);
} else {
RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(),
diff --git a/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianRpcInvoker.java b/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianRpcInvoker.java
index 29548ad03e..d3bd05a116 100644
--- a/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianRpcInvoker.java
+++ b/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HessianRpcInvoker.java
@@ -15,17 +15,18 @@
*/
package com.alibaba.dubbo.rpc.protocol.hessian;
-import com.alibaba.dubbo.common.Constants;
-import com.alibaba.dubbo.common.URL;
-import com.alibaba.dubbo.rpc.Invocation;
-import com.alibaba.dubbo.rpc.Invoker;
-import com.alibaba.dubbo.rpc.ProxyFactory;
-import com.alibaba.dubbo.rpc.Result;
-import com.alibaba.dubbo.rpc.RpcException;
-import com.alibaba.dubbo.rpc.RpcResult;
-import com.alibaba.dubbo.rpc.protocol.AbstractInvoker;
-import com.caucho.hessian.HessianException;
-import com.caucho.hessian.client.HessianProxyFactory;
+import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.dubbo.rpc.Invocation;
+import com.alibaba.dubbo.rpc.Invoker;
+import com.alibaba.dubbo.rpc.ProxyFactory;
+import com.alibaba.dubbo.rpc.Result;
+import com.alibaba.dubbo.rpc.RpcException;
+import com.alibaba.dubbo.rpc.RpcResult;
+import com.alibaba.dubbo.rpc.protocol.AbstractInvoker;
+import com.caucho.hessian.HessianException;
+import com.caucho.hessian.client.HessianConnectionFactory;
+import com.caucho.hessian.client.HessianProxyFactory;
/**
* hessian rpc invoker.
@@ -36,24 +37,24 @@ public class HessianRpcInvoker extends AbstractInvoker {
protected static final String HESSIAN_EXCEPTION_PREFIX = HessianException.class.getPackage().getName() + "."; //fix by tony.chenl
- protected Invoker invoker;
+ protected Invoker invoker;
+
+ protected HessianConnectionFactory hessianConnectionFactory = new HttpClientConnectionFactory();
@SuppressWarnings("unchecked")
public HessianRpcInvoker(Class serviceType, URL url, ProxyFactory proxyFactory){
super(serviceType, url);
- int timeout;
- String t = url.getParameter(Constants.TIMEOUT_KEY);
- if (t != null && t.length() > 0) {
- timeout = Integer.parseInt(t);
- } else {
- timeout = Constants.DEFAULT_TIMEOUT;
- }
-
- java.net.URL httpUrl = url.setProtocol("http").toJavaURL();
- HessianProxyFactory hessianProxyFactory = new HessianProxyFactory();
+ HessianProxyFactory hessianProxyFactory = new HessianProxyFactory();
+ String client = url.getParameter(Constants.CLIENT_KEY, Constants.DEFAULT_HTTP_CLIENT);
+ if ("httpclient".equals(client)) {
+ hessianProxyFactory.setConnectionFactory(hessianConnectionFactory);
+ } else if (client != null && client.length() > 0 && ! Constants.DEFAULT_HTTP_CLIENT.equals(client)) {
+ throw new IllegalStateException("Unsupported http protocol client=\"" + client + "\"!");
+ }
+ int timeout = url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
hessianProxyFactory.setConnectTimeout(timeout);
hessianProxyFactory.setReadTimeout(timeout);
- invoker = proxyFactory.getInvoker((T)hessianProxyFactory.create(serviceType, httpUrl, Thread.currentThread().getContextClassLoader()), serviceType, url);
+ invoker = proxyFactory.getInvoker((T)hessianProxyFactory.create(serviceType, url.setProtocol("http").toJavaURL(), Thread.currentThread().getContextClassLoader()), serviceType, url);
}
@Override
diff --git a/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnection.java b/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnection.java
new file mode 100644
index 0000000000..a0576836d2
--- /dev/null
+++ b/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnection.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 1999-2011 Alibaba Group.
+ *
+ * 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 com.alibaba.dubbo.rpc.protocol.hessian;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.message.BasicHeader;
+
+import com.caucho.hessian.client.HessianConnection;
+
+/**
+ * HttpClientConnection
+ *
+ * @author william.liangf
+ */
+public class HttpClientConnection implements HessianConnection {
+
+ private final HttpClient httpClient;
+
+ private final ByteArrayOutputStream output;
+
+ private final HttpPost request;
+
+ private volatile HttpResponse response;
+
+ public HttpClientConnection(HttpClient httpClient, URL url) {
+ this.httpClient = httpClient;
+ this.output = new ByteArrayOutputStream();
+ this.request = new HttpPost(url.toString());
+ }
+
+ public void addHeader(String key, String value) {
+ request.addHeader(new BasicHeader(key, value));
+ }
+
+ public OutputStream getOutputStream() throws IOException {
+ return output;
+ }
+
+ public void sendRequest() throws IOException {
+ request.setEntity(new ByteArrayEntity(output.toByteArray()));
+ this.response = httpClient.execute(request);
+ }
+
+ public int getStatusCode() {
+ return response == null || response.getStatusLine() == null ? 0 : response.getStatusLine().getStatusCode();
+ }
+
+ public String getStatusMessage() {
+ return response == null || response.getStatusLine() == null ? null : response.getStatusLine().getReasonPhrase();
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return response == null || response.getEntity() == null ? null : response.getEntity().getContent();
+ }
+
+ public void close() throws IOException {
+ HttpPost request = this.request;
+ if (request != null) {
+ request.abort();
+ }
+ }
+
+ public void destroy() throws IOException {
+ }
+
+}
diff --git a/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnectionFactory.java b/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnectionFactory.java
new file mode 100644
index 0000000000..b9f6247f15
--- /dev/null
+++ b/dubbo-rpc-hessian/src/main/java/com/alibaba/dubbo/rpc/protocol/hessian/HttpClientConnectionFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1999-2011 Alibaba Group.
+ *
+ * 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 com.alibaba.dubbo.rpc.protocol.hessian;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.HttpConnectionParams;
+
+import com.caucho.hessian.client.HessianConnection;
+import com.caucho.hessian.client.HessianConnectionFactory;
+import com.caucho.hessian.client.HessianProxyFactory;
+
+/**
+ * HttpClientConnectionFactory
+ *
+ * @author william.liangf
+ */
+public class HttpClientConnectionFactory implements HessianConnectionFactory {
+
+ private final HttpClient httpClient = new DefaultHttpClient();
+
+ public void setHessianProxyFactory(HessianProxyFactory factory) {
+ HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), (int) factory.getConnectTimeout());
+ HttpConnectionParams.setSoTimeout(httpClient.getParams(), (int) factory.getReadTimeout());
+ }
+
+ public HessianConnection open(URL url) throws IOException {
+ return new HttpClientConnection(httpClient, url);
+ }
+
+}