修改HttpServer扩展点

git-svn-id: http://code.alibabatech.com/svn/dubbo/trunk@174 1a56cb94-b969-4eaa-88fa-be21384802f2
This commit is contained in:
william.liangf 2011-11-02 08:45:17 +00:00
parent 60bc67ce59
commit 4990572d21
19 changed files with 631 additions and 216 deletions

View File

@ -41,6 +41,6 @@
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
</dependency>
</dependency>
</dependencies>
</project>

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}
}

View File

@ -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<String, HttpProcessor> processors = new ConcurrentHashMap<String, HttpProcessor>();
private static final Map<Integer, HttpHandler> handlers = new ConcurrentHashMap<Integer, HttpHandler>();
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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,2 @@
com.alibaba.dubbo.remoting.http.servlet.ServletHttpBinder
com.alibaba.dubbo.remoting.http.jetty.JettyHttpBinder

View File

@ -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;
}
}

View File

@ -42,6 +42,12 @@
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@ -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<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>();
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 <T> Exporter<T> export(Invoker<T> 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<T> exporter = new HessianRpcExporter<T>(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);
}

View File

@ -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<T> extends AbstractExporter<T> implements HttpProcessor {
public class HessianRpcExporter<T> extends AbstractExporter<T> implements HttpHandler {
private HessianSkeleton skeleton;
@ -42,9 +42,9 @@ public class HessianRpcExporter<T> extends AbstractExporter<T> 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(),

View File

@ -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<T> extends AbstractInvoker<T> {
protected static final String HESSIAN_EXCEPTION_PREFIX = HessianException.class.getPackage().getName() + "."; //fix by tony.chenl
protected Invoker<T> invoker;
protected Invoker<T> invoker;
protected HessianConnectionFactory hessianConnectionFactory = new HttpClientConnectionFactory();
@SuppressWarnings("unchecked")
public HessianRpcInvoker(Class<T> 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

View File

@ -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 {
}
}

View File

@ -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);
}
}