修改hessian协议通过

git-svn-id: http://code.alibabatech.com/svn/dubbo/trunk@81 1a56cb94-b969-4eaa-88fa-be21384802f2
This commit is contained in:
william.liangf 2011-10-27 02:47:07 +00:00
parent 1a71da597b
commit f736416d84
4 changed files with 23 additions and 209 deletions

View File

@ -61,7 +61,7 @@ public class HessianProtocol extends AbstractProtocol {
serverMap.put(addr, server);
}
HessianRpcExporter<T> exporter = new HessianRpcExporter<T>(invoker) {
HessianRpcExporter<T> exporter = new HessianRpcExporter<T>(invoker, proxyFactory) {
public void unexport() {
super.unexport();
exporterMap.remove(uri);

View File

@ -8,43 +8,38 @@ import javax.servlet.http.HttpServletResponse;
import com.alibaba.dubbo.remoting.http.HttpProcessor;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.ProxyFactory;
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.dubbo.rpc.protocol.AbstractExporter;
import com.caucho.hessian.server.HessianSkeleton;
/**
* hessian rpc exporter.
*
* @author qian.lei
*/
public class HessianRpcExporter<T> extends AbstractExporter<T> implements HttpProcessor {
public class HessianRpcExporter<T> extends AbstractExporter<T> implements HttpProcessor
{
private HessianSkeletonInvoker mSkeleton;
private HessianSkeleton skeleton;
public HessianRpcExporter(Invoker<T> invoker)
{
super(invoker);
mSkeleton = new HessianSkeletonInvoker(invoker.getInterface(), this);
}
public HessianRpcExporter(Invoker<T> invoker, ProxyFactory proxyFactory) {
super(invoker);
skeleton = new HessianSkeleton(proxyFactory.getProxy(invoker), invoker.getInterface());
}
public void invoke(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
if( request.getMethod().equalsIgnoreCase("POST") == false )
{
response.setStatus(500);
}
else
{
RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), request.getRemotePort());
try
{
mSkeleton.invoke(request.getInputStream(), response.getOutputStream());
}
catch(Throwable e)
{
throw new ServletException(e);
}
}
}
public void invoke(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
if (request.getMethod().equalsIgnoreCase("POST") == false) {
response.setStatus(500);
} else {
RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(),
request.getRemotePort());
try {
skeleton.invoke(request.getInputStream(), response.getOutputStream());
} catch (Throwable e) {
throw new ServletException(e);
}
}
}
}

View File

@ -1,134 +0,0 @@
package com.alibaba.dubbo.rpc.protocol.hessian;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.alibaba.dubbo.rpc.RpcInvocation;
import com.caucho.hessian.io.AbstractHessianOutput;
import com.caucho.hessian.io.Hessian2Input;
import com.caucho.hessian.io.Hessian2Output;
import com.caucho.hessian.io.HessianOutput;
import com.caucho.services.server.AbstractSkeleton;
import com.caucho.services.server.ServiceContext;
class HessianSkeletonInvoker extends AbstractSkeleton {
private HessianRpcExporter<?> mExporter;
HessianSkeletonInvoker(Class<?> serviceType, HessianRpcExporter<?> exporter) {
super(serviceType);
mExporter = exporter;
}
public void invoke(InputStream is, OutputStream os) throws Throwable {
Hessian2Input in = new Hessian2Input(is);
// if (this.serializerFactory != null) {
// in.setSerializerFactory(this.serializerFactory);
// }
int code = in.read();
if (code != 'c')
throw new IOException("expected 'c' in hessian input at " + code);
AbstractHessianOutput out;
int major = in.read();
in.read(); // minor version, skip it.
if (major >= 2)
out = new Hessian2Output(os);
else
out = new HessianOutput(os);
// if (this.serializerFactory != null) {
// out.setSerializerFactory(this.serializerFactory);
// }
// see com.alibaba.dubbo.rpc.http.hessian.v3_2_0.hessian.server.HessianSkeleton
ServiceContext context = ServiceContext.getContext();
// backward compatibility for some frameworks that don't read
// the call type first
in.skipOptionalCall();
String header;
while ((header = in.readHeader()) != null) {
Object value = in.readObject();
context.addHeader(header, value);
}
String methodName = in.readMethod();
Method method = getMethod(methodName);
if (method != null) {
} else if ("_hessian_getAttribute".equals(methodName)) {
String attrName = in.readString();
in.completeCall();
String value = null;
if ("java.api.class".equals(attrName))
value = getAPIClassName();
else if ("java.home.class".equals(attrName))
value = getHomeClassName();
else if ("java.object.class".equals(attrName))
value = getObjectClassName();
out.startReply();
out.writeObject(value);
out.completeReply();
out.close();
return;
} else if ((method = HessianUtils.getFrameworkMethod(methodName)) == null) {
out.startReply();
out.writeFault("NoSuchMethodException",
"The service has no method named: " + in.getMethod(), null);
out.completeReply();
out.close();
return;
}
Class<?>[] args = method.getParameterTypes();
Object[] values = new Object[args.length];
for (int i = 0; i < args.length; i++) {
values[i] = in.readObject(args[i]);
}
Object result = null;
try {
RpcInvocation inv = new RpcInvocation(method, values);
result = mExporter.getInvoker().invoke(inv).recreate();
} catch (Throwable e) {
if (e instanceof InvocationTargetException) {
e = ((InvocationTargetException) e).getTargetException();
}
out.startReply();
out.writeFault("ServiceException", e.getMessage(), e);
out.completeReply();
out.close();
return;
}
// The complete call needs to be after the invoke to handle a
// trailing InputStream
in.completeCall();
out.startReply();
out.writeObject(result);
out.completeReply();
out.close();
}
}

View File

@ -1,47 +0,0 @@
package com.alibaba.dubbo.rpc.protocol.hessian;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.dubbo.rpc.service.EchoService;
import com.alibaba.dubbo.rpc.service.GenericService;
/**
*
*
* @author qianlei
*/
public class HessianUtils
{
private final static Method[] FrameworkMethods;
static
{
List<Method> methods = new ArrayList<Method>();
Class<?> c = EchoService.class;
for( Method method : c.getDeclaredMethods() )
methods.add(method);
c = GenericService.class;
for( Method method : c.getDeclaredMethods() )
methods.add(method);
FrameworkMethods = methods.toArray(new Method[0]);
}
private HessianUtils(){}
public static Method getFrameworkMethod(String name)
{
if( name != null )
{
for( Method method : FrameworkMethods )
if( name.startsWith(method.getName()) )
return method;
}
return null;
}
}