Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能. 相比WebService,Hessian更简单、快捷。采用的是二进制RPC协议,因为采用的是二进制协议,所以它很适合于发送二进制数据
注意事项
在进行基于Hessian的项目开发时,应当注意以下几点:
▲JAVA服务器端必须具备以下几点:
·包含Hessian的jar包 ·设计一个接口,用来给客户端调用
·实现该接口的功能
·配置web.xml,配好相应的servlet
·传递的对象必须实现Serializable 接口(不是接口实现类)
·对于复杂对象可以使用Map的方法传递
▲客户端必须具备以下几点:
·java客户端包含Hessian.jar的包。C#中引用hessianCSharp.dll
·具有和服务器端结构一样的接口。包括命名空间都最好一样
·利用HessianProxyFactory调用远程接口。
a)服务端:
1.准备相关jar包
hessian3.1.6
2.编写相应接口和类
接口:
package com.hundsun.nms.timer.service;
import java.math.BigDecimal;
import java.util.Date;
/**
* @ClassName: TimerExteriorService
* @Description: TODO
* @Author JiangMing
* @Date 2011-2-12 下午02:12:20
* @Copyright: 版权由 HundSun 拥有
*/
public interface TimerExteriorService
{
public void operTimer(String exeOper, String jobName, String operation, BigDecimal terminalId, String period,
Date date, String time, int day, String paramInfo, boolean isRemote) throws Exception;
}
实现类:
package com.hundsun.nms.timer.service.impl;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import org.apache.log4j.Logger;
import com.caucho.hessian.client.HessianProxyFactory;
import com.hundsun.nms.timer.TimeSchedule;
import com.hundsun.nms.timer.service.TimerExteriorService;
/**
* @ClassName: TimerExteriorService
* @Description: TODO
* @Author JiangMing
* @Date 2011-2-12 下午02:20:53
* @Copyright: 版权由 HundSun 拥有
*/
public class TimerExteriorServiceImpl implements com.hundsun.nms.timer.service.TimerExteriorService
{
// 定义一个Logger对象,用于打印错误日志
private static final Logger log = Logger.getLogger(TimerExteriorServiceImpl.class);
private TimeSchedule timeSchedule;
private List<String> urlList;
public TimeSchedule getTimeSchedule()
{
return timeSchedule;
}
public void setTimeSchedule(TimeSchedule timeSchedule)
{
this.timeSchedule = timeSchedule;
}
@Override
public void operTimer(String exeOper, String jobName, String operation, BigDecimal terminalId, String period,
Date date, String time, int day, String paramInfo, boolean isRemote) throws Exception
{
try
{
if (timeSchedule.isRunning())
{
timeSchedule.jobSchedule(jobName, operation, terminalId, exeOper, period, date, time, day, paramInfo);
} else if (!isRemote)
{
HessianProxyFactory factory = new HessianProxyFactory();
factory.setOverloadEnabled(true);
TimerExteriorService timerExteriorService;
for (String url : urlList)
{
timerExteriorService = (TimerExteriorService) factory.create(TimerExteriorService.class, url);
timerExteriorService.operTimer(exeOper, jobName, operation, terminalId, period, date, time, day,
paramInfo, true);
}
}
} catch (Exception e)
{
log.error(e);
throw e;
}
}
public List<String> getUrlList()
{
return urlList;
}
public void setUrlList(List<String> urlList)
{
this.urlList = urlList;
}
}
3.配置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/conf/spring/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>
4.编写remote-servlet.xml文件
此文件名称以<servlet-name>remote</servlet-name>名字开头,并且加上-servlet.xml一段,组成完整的文件名.
<!-- 远程调用配置-->
<!--<bean id="defaultHandlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>-->
<!-- 要发布的服务实例bean,urlList参数为集群中其他机器的地址(充当客户端调用其他机器提供的服务)-->
<bean id="timerExteriorService" class="com.hundsun.nms.timer.service.impl.TimerExteriorServiceImpl">
<property name="timeSchedule" ref="timeSchedule"/>
<property name="urlList">
<list>
<value>http://localhost:8080/nms/remote/timerExterior</value>
</list>
</property>
</bean>
<!--发布hessian服务配置start-->
<bean name="timerExterior" class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service" ref="timerExteriorService"/>
<property name="serviceInterface" value="com.hundsun.nms.timer.service.TimerExteriorService"/>
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/timerExterior">timerExterior</prop>
</props>
</property>
</bean>
<!--发布hessian服务配置end-->
解释:
<bean id="timerExteriorService" class="com.hundsun.nms.timer.service.impl.TimerExteriorServiceImpl">是具体的hessian实现类,因为你此类也承担着hessian客户端的职责,所以可以设置要访问的其他远程hessian地址---urlList
<property name="service" ref="timerExteriorService"/>是需要发布的服务,其实就是实现了某个接口的普通bean
<property name="serviceInterface" value="com.hundsun.nms.timer.service.TimerExteriorService"/>是发布的服务类的接口
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">是访问hessian的具体名称,因为web.xml中设置/remote/*,所以此名称用来替换*即最后的访问路径为:http://xxx.xxx.com/nms/remote/timerExterior;
/
如果单纯客户端访问hessian服务
还有一种spring配置客户端的方式,可像普通bean一样使用
<bean name="hessianService" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
<property name="serviceUrl" value="http://localhost:8080/nms/remote/timerExterior" />
<property name="serviceInterface" value="com.hundsun.nms.timer.service.TimerExteriorService" />
</bean>
hessianService就是可以使用的bean,将hessianService注入到需要的地方即可。
注意:如果是跟spingmvc结合,在和通过HessianServiceExporter提供HTTP服务一起使用的时候,需要在-servlet.xml文件中配置
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>,否则会把所有请求映射到controller
而且mvc的请求映射要配置
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
否则controller访问不了
具体样例如下:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
<!--发布hessian服务配置start-->
<bean name="remoteExporter" class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service" ref="remoteService"/>
<property name="serviceInterface" value="com.referee.service.RemoteService"/>
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/nc/remoteExporter.htm">remoteExporter</prop>
</props>
</property>
</bean>
样例结束
客户端的调用还有一种方法,使用HessianProxyFactory直接调用,例子如下:
public class NormalClient {
public static void main(String[] args) throws MalformedURLException {
//Spring Hessian代理Servelet
String url = "http://localhost:8080/HessianSpring/remote/helloSpring";
HessianProxyFactory factory = new HessianProxyFactory();
Isay api = (Isay) factory.create(Isay.class, url);
System.out.println(api.sayHello("chen", "weitang"));
}
}
注意事项
在进行基于Hessian的项目开发时,应当注意以下几点:
▲JAVA服务器端必须具备以下几点:
·包含Hessian的jar包 ·设计一个接口,用来给客户端调用
·实现该接口的功能
·配置web.xml,配好相应的servlet
·传递的对象必须实现Serializable 接口(不是接口实现类)
·对于复杂对象可以使用Map的方法传递
▲客户端必须具备以下几点:
·java客户端包含Hessian.jar的包。C#中引用hessianCSharp.dll
·具有和服务器端结构一样的接口。包括命名空间都最好一样
·利用HessianProxyFactory调用远程接口。
a)服务端:
1.准备相关jar包
hessian3.1.6
2.编写相应接口和类
接口:
package com.hundsun.nms.timer.service;
import java.math.BigDecimal;
import java.util.Date;
/**
* @ClassName: TimerExteriorService
* @Description: TODO
* @Author JiangMing
* @Date 2011-2-12 下午02:12:20
* @Copyright: 版权由 HundSun 拥有
*/
public interface TimerExteriorService
{
public void operTimer(String exeOper, String jobName, String operation, BigDecimal terminalId, String period,
Date date, String time, int day, String paramInfo, boolean isRemote) throws Exception;
}
实现类:
package com.hundsun.nms.timer.service.impl;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import org.apache.log4j.Logger;
import com.caucho.hessian.client.HessianProxyFactory;
import com.hundsun.nms.timer.TimeSchedule;
import com.hundsun.nms.timer.service.TimerExteriorService;
/**
* @ClassName: TimerExteriorService
* @Description: TODO
* @Author JiangMing
* @Date 2011-2-12 下午02:20:53
* @Copyright: 版权由 HundSun 拥有
*/
public class TimerExteriorServiceImpl implements com.hundsun.nms.timer.service.TimerExteriorService
{
// 定义一个Logger对象,用于打印错误日志
private static final Logger log = Logger.getLogger(TimerExteriorServiceImpl.class);
private TimeSchedule timeSchedule;
private List<String> urlList;
public TimeSchedule getTimeSchedule()
{
return timeSchedule;
}
public void setTimeSchedule(TimeSchedule timeSchedule)
{
this.timeSchedule = timeSchedule;
}
@Override
public void operTimer(String exeOper, String jobName, String operation, BigDecimal terminalId, String period,
Date date, String time, int day, String paramInfo, boolean isRemote) throws Exception
{
try
{
if (timeSchedule.isRunning())
{
timeSchedule.jobSchedule(jobName, operation, terminalId, exeOper, period, date, time, day, paramInfo);
} else if (!isRemote)
{
HessianProxyFactory factory = new HessianProxyFactory();
factory.setOverloadEnabled(true);
TimerExteriorService timerExteriorService;
for (String url : urlList)
{
timerExteriorService = (TimerExteriorService) factory.create(TimerExteriorService.class, url);
timerExteriorService.operTimer(exeOper, jobName, operation, terminalId, period, date, time, day,
paramInfo, true);
}
}
} catch (Exception e)
{
log.error(e);
throw e;
}
}
public List<String> getUrlList()
{
return urlList;
}
public void setUrlList(List<String> urlList)
{
this.urlList = urlList;
}
}
3.配置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/conf/spring/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>
4.编写remote-servlet.xml文件
此文件名称以<servlet-name>remote</servlet-name>名字开头,并且加上-servlet.xml一段,组成完整的文件名.
<!-- 远程调用配置-->
<!--<bean id="defaultHandlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>-->
<!-- 要发布的服务实例bean,urlList参数为集群中其他机器的地址(充当客户端调用其他机器提供的服务)-->
<bean id="timerExteriorService" class="com.hundsun.nms.timer.service.impl.TimerExteriorServiceImpl">
<property name="timeSchedule" ref="timeSchedule"/>
<property name="urlList">
<list>
<value>http://localhost:8080/nms/remote/timerExterior</value>
</list>
</property>
</bean>
<!--发布hessian服务配置start-->
<bean name="timerExterior" class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service" ref="timerExteriorService"/>
<property name="serviceInterface" value="com.hundsun.nms.timer.service.TimerExteriorService"/>
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/timerExterior">timerExterior</prop>
</props>
</property>
</bean>
<!--发布hessian服务配置end-->
解释:
<bean id="timerExteriorService" class="com.hundsun.nms.timer.service.impl.TimerExteriorServiceImpl">是具体的hessian实现类,因为你此类也承担着hessian客户端的职责,所以可以设置要访问的其他远程hessian地址---urlList
<property name="service" ref="timerExteriorService"/>是需要发布的服务,其实就是实现了某个接口的普通bean
<property name="serviceInterface" value="com.hundsun.nms.timer.service.TimerExteriorService"/>是发布的服务类的接口
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">是访问hessian的具体名称,因为web.xml中设置/remote/*,所以此名称用来替换*即最后的访问路径为:http://xxx.xxx.com/nms/remote/timerExterior;
/
如果单纯客户端访问hessian服务
还有一种spring配置客户端的方式,可像普通bean一样使用
<bean name="hessianService" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
<property name="serviceUrl" value="http://localhost:8080/nms/remote/timerExterior" />
<property name="serviceInterface" value="com.hundsun.nms.timer.service.TimerExteriorService" />
</bean>
hessianService就是可以使用的bean,将hessianService注入到需要的地方即可。
注意:如果是跟spingmvc结合,在和通过HessianServiceExporter提供HTTP服务一起使用的时候,需要在-servlet.xml文件中配置
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>,否则会把所有请求映射到controller
而且mvc的请求映射要配置
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
否则controller访问不了
具体样例如下:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
<!--发布hessian服务配置start-->
<bean name="remoteExporter" class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service" ref="remoteService"/>
<property name="serviceInterface" value="com.referee.service.RemoteService"/>
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/nc/remoteExporter.htm">remoteExporter</prop>
</props>
</property>
</bean>
样例结束
客户端的调用还有一种方法,使用HessianProxyFactory直接调用,例子如下:
public class NormalClient {
public static void main(String[] args) throws MalformedURLException {
//Spring Hessian代理Servelet
String url = "http://localhost:8080/HessianSpring/remote/helloSpring";
HessianProxyFactory factory = new HessianProxyFactory();
Isay api = (Isay) factory.create(Isay.class, url);
System.out.println(api.sayHello("chen", "weitang"));
}
}