hessian demo和hessian与spring整合demo
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/**
*@version 1.1
*@author iam00@
*@create Mar18,2010
*/
Hessian是一个轻量级的remoting on http工具,使用简单的方法提供了RMI(Remote Method Invocation,远程方法调用)的功能。
采用的是二进制RPC (Remote Procedure Call Protocol,远程过程调用协议)协议,因为采用的是二进制协议,所以它很适合于发送二进制数据。
在进行基于Hessian的项目开发时,应当注意以下几点:
▲JAVA服务器端必须具备以下几点:
·包含Hessian的jar包。
·设计一个接口,用来给客户端调用。
·实现该接口的功能。
·配置web.xml,配好相应的servlet。
·对象必须实现Serializable 接口。
·对于复杂对像可以使用Map的方法传递。
▲客户端必须具备以下几点:
·java客户端包含Hessian.jar的包。
·具有和服务器端结构一样的接口。
·利用HessianProxyFactory调用远程接口。
下面是一个hessian的简单例子。
Java服务器端:
环境:j2sdk1.4.2、Tomcat6.0
依赖的包:hessian-3.1.6.jar
新建一个名为HessianServer的web project。
将hessian-3.1.6.jar放入WEB-INF/lib文件夹中。
创建接口:
package server.demo;
public interface DemoApi {
public void setName(String name);
public String sayHello();
public User getUser();
}
实现接口:
package server.demo;
public class DemoService implements DemoApi { private String name;
public String sayHello() {
return"Hello "+name;
}
public void setName(String name) {
=name;
System.out.println("Hello "+name);
}
public User getUser() {
return new User("lingling", "pass");
}
}
创建User类,注意:一定要implements Serializable。
package server.demo;
import java.io.Serializable;
public class User implements Serializable { String name = "kitty";
String password = "nopass";
public User() {
super();
}
public User(String name, String password) { super();
= name;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
= name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
配置web.xml:
<servlet>
<servlet-name>first</servlet-name>
<servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
<init-param>
<param-name>service-class</param-name>
<param-value>server.demo.DemoService</param-value> </init-param>
</servlet>
<servlet-mapping>
<servlet-name>first</servlet-name>
<url-pattern>/helloworld</url-pattern>
</servlet-mapping>
将项目发布到tomcat服务器上。
Java客户端:
环境:j2sdk1.4.2
依赖的包:hessian-3.1.6.jar
创建一个名为HessianClient的java project,载入hessian-3.1.6.jar。
创建与服务器一样的接口及User类,注意它们所在的包路径也要与服务器相同,否则会出现ng.ClassNotFoundException。
接口:
package server.demo;
public interface DemoApi {
public void setName(String name);
public String sayHello();
public User getUser();
}
User类:
package server.demo;
import java.io.Serializable;
public class User implements Serializable { String name = "kitty";
String password = "nopass";
public User() {
super();
}
public User(String name, String password) { super();
= name;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
= name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) { this.password = password;
}
}
客户端程序:
package client.demo;
import .MalformedURLException;
import server.demo.DemoApi;
import com.caucho.hessian.client.HessianProxyFactory;
public class ClientTest {
public static void main(String[] args) throws MalformedURLException, ClassNotFoundException {
String url = "http://localhost:9520/HessianServer/helloworld";
HessianProxyFactory factory = new HessianProxyFactory();
DemoApi api = (DemoApi) factory.create(url);
api.setName("test");
System.out.println(api.sayHello());
System.out.println(api.getUser().getName());
System.out.println(api.getUser().getPassword());
}
}
现在,启动tomcat,运行ClientTest。
运行结果:
Hello test
lingling
pass
现在,在以上基础上将hessian与spring整合。
Java服务器端(即我们上面建的名为HessianServer的web project):
环境:j2sdk1.4.2、Tomcat6.0
依赖的包:
1.Hessian包:hessian-3.1.6.jar
2.spring-framework-2.0.2包:
a)aopalliance.jar
b)commons-logging.jar
c)log4j-1.2.14.jar
d)spring.jar
e)spring-aop.jar
f)spring-beans.jar
g)spring-context.jar
h)spring-core.jar
i)spring-jdbc.jar
j)spring-jms.jar
k)spring-web.jar
l)spring-webmvc.jar
配置web.xml,web.xml中增加:
<servlet>
<servlet-name>remote</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet </servlet-class>
<init-param>
<param-name>namespace</param-name>
<param-value>classes/remote-servlet</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>remote</servlet-name>
<url-pattern>/remote/*</url-pattern>
</servlet-mapping>
写spring的发布hessian服务的配置文件remote-servlet.xml,这个文件就建在工程的src下,即deploy到tomcat后,在WEB-INF/classes目录下。
注意:这个文件为什么叫remote-servlet.xml呢?因为我们在web.xml中有配置:
<servlet-name>remote</servlet-name>。
所以remote-servlet.xml的文件名必须以<servlet-name>中配置的servlet-name作为文件名的开头,且文件名的格式必须是[servlet-name]-servlet.xml格式,否则出错。
<param-value>classes/remote-servlet</param-value>所以文件名为
remote-servlet.xml。
以下是remote-servlet.xml的内容:
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"/dtd/spring-beans.dtd">
<beans>
<bean id="demoService" class="server.demo.DemoService" />
<bean name="/helloSpring"
class="org.springframework.remoting.caucho.HessianServiceExporter ">
<property name="service" ref="demoService" />
<property name="serviceInterface" value="server.demo.DemoApi" />
</bean>
</beans>
好了,现在可以测试一下了。
在刚才建的名为HessianClient的java project 中修改client.demo.ClientTest.java如下:
package client.demo;
import .MalformedURLException;
import server.demo.DemoApi;
import com.caucho.hessian.client.HessianProxyFactory;
public class ClientTest {
public static void main(String[] args) throws MalformedURLException, ClassNotFoundException {
// String url =
"http://localhost:9520/HessianServer/helloworld";
String url =
"http://localhost:9520/HessianServer/remote/helloSpring";
HessianProxyFactory factory = new HessianProxyFactory();
DemoApi api = (DemoApi) factory.create(DemoApi.class, url);
api.setName("test");
System.out.println(api.sayHello());
System.out.println(api.getUser().getName());
System.out.println(api.getUser().getPassword());
}
}
现在,启动tomcat,运行ClientTest。
运行结果:
Hello test
lingling
pass
如果客户端也使用spring呢?现在做一个spring整合hessian的客户端demo。
首先载入spring-framework-2.0.2包:
1)aopalliance.jar
2)commons-logging.jar
3)log4j-1.2.14.jar
4)spring.jar
5)spring-aop.jar
6)spring-beans.jar
7)spring-context.jar
8)spring-core.jar
9)spring-jdbc.jar
10)spring-jms.jar
11)spring-web.jar
12)spring-webmvc.jar
在名为HessianClient的java project中src目录下,新建一个
remote-client.xml,这个文件可随意命名。
remote-client.xml内容为:
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"/dtd/spring-beans.dtd">
<beans>
<bean id="helloSpring"
class="org.springframework.remoting.caucho.HessianProxyFactoryBea n">
<property name="serviceUrl">
<value>
http://localhost:9520/HessianServer/remote/helloSpring </value>
</property>
<property name="serviceInterface">
<value>server.demo.DemoApi</value>
</property>
</bean>
</beans>
在刚才建的名为HessianClient的java project中修改
client.demo.ClientTest.java如下:
package client.demo;
import .MalformedURLException;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext; import server.demo.DemoApi;
public class ClientTest {
public static void main(String[] args) throws MalformedURLException, ClassNotFoundException {
// String url =
"http://localhost:9520/HessianServer/helloworld";
// String url =
// "http://localhost:9520/HessianServer/remote/helloSpring";
// HessianProxyFactory factory = new HessianProxyFactory();
// DemoApi api = (DemoApi) factory.create(DemoApi.class, url);
ApplicationContext context = new ClassPathXmlApplicationContext( "remote-client.xml");
DemoApi api = (DemoApi) context.getBean("helloSpring");
api.setName("test");
System.out.println(api.sayHello());
System.out.println(api.getUser().getName());
System.out.println(api.getUser().getPassword());
}
}
现在,启动tomcat,运行ClientTest。
运行结果:
Hello test
lingling
pass
至此over~
PS:有时候可能因hessian或spring的版本问题使程序不能运行。
/**
*@version 1.1
*@author iam00@
*@add Mar18,2010
*/
反映问题:
假设有多个应用,需要不止一个接口是向下面这样加上吗?
<init-param>
<param-name>service-class</param-name>
<param-value>server.demo.DemoService</param-value>
</init-param>
答:这样加上肯定是不行的,可以再配置一个servlet啊,这个servlet的类还是
com.caucho.hessian.server.HessianServlet,但init-param可以是另外一个,url-pattern也是另一个。
如:
<servlet>
<servlet-name>mul</servlet-name>
<servlet-class>
com.caucho.hessian.server.HessianServlet
</servlet-class>
<init-param>
<param-name>service-class</param-name>
<param-value>server.mul.MulService</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mul</servlet-name>
<url-pattern>/hellomul</url-pattern>
</servlet-mapping>
这样,在客户端用HessianProxyFactory工厂创建对象的时候,url也变为第二个servlet所设置的url-pattern。
这协议是用二进制传输的,所以需要序列化是把,但如果是复杂的对象,而且对象之间还有复杂的关系,如果传输这样一些对象,怎样能维护他们的关系不被序列化破坏呢
其实,以我的理解,hessian是为了远程调用方法。
百度查到:对于复杂对象可以使用Map的方法传递。
我现在对此问题没有更深入的研究。
你所说的对象是不是实体类的对象?因为服务器端的实体类在客户端也会有相同的实体类,当然各实体类之间的关系也完全一样,客户端也会有一个服务器端的接口(api),用以调用方法。
也就是说,客户端比服务器端只少一个service(即真正实现api所有方法的类)。