注:
如果调用到download方法的时候,出现 java.io.IOException: stream is closed
则此时应该是jar包的问题,貌似这是hessian的一个bug : 关于该bug
解决方法下载hessian.jar的源码包,修改 com.caucho.hessian.client.HessianProxy :
在 Object value = in.readReply(method.getReturnType()); 这一句话之后加上下面代码:
- if (value instanceof InputStream) {
- value = new ResultInputStream(conn, is, in, (InputStream) value);
- is = null;
- conn = null;
- }
然后重新打包,使用这个新的jar包就没问题了。。。
然后,就可以看到sayHello、下载、上传成功的结果了。。。
最后提供一个我自己修改过之后的hessian.jar
转自百度百科:http://baike.baidu.com/view/2255290.htm
Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能. 相比WebService,Hessian更简单、快捷。采用的是二进制RPC协议,因为采用的是二进制协议,所以它很适合于发送二进制数据
在进行基于Hessian的项目开发时,应当注意以下几点:
▲JAVA服务器端必须具备以下几点:
·包含Hessian的jar包
·设计一个接口,用来给客户端调用
·实现该接口的功能
·配置web.xml,配好相应的servlet
·对象必须实现Serializable 接口
·对于复杂对象可以使用Map的方法传递
▲客户端必须具备以下几点:
·java客户端包含Hessian.jar的包。C#中引用hessianCSharp.dll
·具有和服务器端结构一样的接口。包括命名空间都最好一样
·利用HessianProxyFactory调用远程接口。
简单JAVA客户端例子:
服务器端
新建一个名EasyHession的webProject项目,将Hessian.jar放入web-inf下的lib中
创建接口:
package com.tch.test.hessian; import java.io.InputStream; public interface BasicAPI { public void setGreeting(String greeting); public String hello(); public User getUser(); /** * Created on: 2013-12-11 * <p>Discription: 下载数据</p> * @return InputStream */ public InputStream download(String path) throws Exception; }
实现接口:
package com.tch.test.hessian; import java.io.FileInputStream; import java.io.InputStream; public class BasicService implements BasicAPI { private String _greeting = "Hello, world"; public void setGreeting(String greeting) { _greeting = greeting; System.out.println("set greeting success:" + _greeting); } public String hello() { return _greeting; } public User getUser() { return new User("prance", "meshow"); } public InputStream download(String path) throws Exception{ System.out.println(path+"******************************"); InputStream inputStream = new FileInputStream(path); return inputStream; } }
创建一个实现Serializable的projo类也可以是Bean。
package com.tch.test.hessian; import java.io.Serializable; public class User implements Serializable { private static final long serialVersionUID = 1L; String userName = "snoopy"; String password = "showme"; public User(String user, String pwd) { this.userName = user; this.password = pwd; } public String getUserName() { return userName; } public String getPassword() { return password; } }
接下来是配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class> <init-param> <param-name>service-class</param-name> <param-value>com.tch.test.hessian.BasicService</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
将一切配置成功后,将项目发布到web 服务器上去,可以是Tomcat,Rain等等。
java客户端
创建一个名为HessianClient的JAVAProject,载入hessian.jar包
创建与服务器端一样的接口,及基础类
package hessian;
package com.tch.test.hessian; import java.io.InputStream; public interface BasicAPI { public void setGreeting(String greeting); public String hello(); public User getUser(); /** * Created on: 2013-12-11 * <p>Discription: 下载数据</p> * @return InputStream */ public InputStream download(String path) throws Exception; }
package com.tch.test.hessian; import java.io.Serializable; public class User implements Serializable { private static final long serialVersionUID = 1L; String userName = "snoopy"; String password = "showme"; public User(String user, String pwd) { this.userName = user; this.password = pwd; } public String getUserName() { return userName; } public String getPassword() { return password; } }
创建客户端程序
package com.tch.test.hessian; import java.io.InputStream; import com.caucho.hessian.client.HessianProxyFactory; public class BasicClient { public static void main(String[] args) throws Exception { String url = "http://127.0.0.1:8080/dubboprovider/hello"; HessianProxyFactory factory = new HessianProxyFactory(); BasicAPI basic = (BasicAPI) factory.create(BasicAPI.class, url); System.out.println("Hello:" + basic.hello()); System.out.println("Hello:" + basic.getUser().getUserName()); System.out.println("Hello:" + basic.getUser().getPassword()); basic.setGreeting("HelloGreeting"); System.out.println("Hello:" + basic.hello()); InputStream inputStream = basic.download("D:\\MyBackup\\我的文档\\Downloads\\a.txt"); // 执行远程方法 byte b[] = new byte[1024]; int n; try { while ((n = inputStream.read(b)) != -1) { System.out.print(new String(b,0,n,"utf-8")); } } catch (Exception e) { e.printStackTrace(); }finally{ inputStream.close(); } } }
就可以看到结果信息了。。。就如同本地调用一样