Java远程调用技术入门篇
admin 发布于:2014-11-05 22:35:00
阅读:loading
这几天为了配合项目上的实现,将后续的功能能够迁移到一个单独的项目上,原有项目上的功能保持不变,新工程与老工程交互使用接口,此为背景,首先排除的webservice方式,好吧,对于它的就不提了(以前有4篇日志已经说过,有兴趣可自行查找),需要找一种实现起来简单方便的方式,来实现几个工程中相互调用,这里就简单介绍一下关于java远程调用的两个实现技术,作为入门级别的,采用原生的java实现。本着学习东西取之于网络,贡献于网络的原则,整理如下。
我理解的mi的实现机制是使用socket的方式传输数据(采用rmi协议),还记得上学时还学过这个东西呢,当时就输出hellowrold后再没有印象了,也一直是云里雾里,我的小伙伴们,你们还记得否?这回有机会再了解了解,将学习使用心得跟大家分享一下,作为入门级的教程共勉,如果想继续深入恐怕还得多找找其他的资源了。rmi作为JDK1.1就有的老牌技术了,网上资源也是一大堆,多看看别人写的就好。
1)从rmi的接口开始,只需要定义一个接口类继承Remote接口即可,剩下的就是业务方法了(必须要抛出RemoteException),这里就一切从简,定义一个返回类型为void的函数,输入name名称参数,如下
package com.sever;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface IHello extends Remote{
public void sayHello(String name) throws RemoteException;
}
2)接下来就是实现类,它的实现类不管需要实现此接口,还需要继承UnicastRemoteObject类,此外必须要有一个无参数的构造函数且抛出RemoteException异常,之后就是覆盖父类的sayHello函数了,我们这里覆盖就简单的打印一下,hello:name得了,参考如下:
package com.sever.impl;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import com.sever.IHello;
public class Hello extends UnicastRemoteObject implements IHello {
/**
*
*/
private static final long serialVersionUID = 1L;
public Hello() throws RemoteException{
super();
}
@Override
public void sayHello(String name) throws RemoteException {
System.out.println("hello , " + name);
}
}
3)启动服务端,服务端监听1099端口,启动完毕之后输出一句提示,参考代码如下:
package com;
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
import com.sever.impl.Hello;
public class RunHelloServer {
public static void main(String[] args) throws Exception {
try {
LocateRegistry.createRegistry(1099);
Naming.rebind("rmi://127.0.0.1:1099/Hello", new Hello());
System.out.println("Hello Server is ready.");
} catch (Exception e) {
System.out.println("Hello Server is faild : " + e);
e.printStackTrace();
}
}
}
4)客户端运行,传递name参数为chendd,参考代码如下:
package com;
import java.rmi.Naming;
import com.sever.IHello;
public class RunHelloClient {
public static void main(String[] args) throws Exception {
IHello hello = (IHello) Naming.lookup("rmi://127.0.0.1:1099/Hello");
hello.sayHello("chendd");
System.out.println("Client run over");
}
}
5)至于运行结果那就可想而知了,
服务端输出:Hello Server is ready.
客户端输出:Client run over
服务端输出:hello , chendd
6)至于rmi与spring整合的实现本次就略过了,由于实际的项目中两个项目中的spring版本不匹配,导致这个整合无法实现,除非调整版本,故采用的纯java方式的调用,最终由于公司项目中有一些其他不可能绕过的方式,而导致这种监听IP、端口的实现方式成为泡影。
第二种方式是使用Hessian实现
竟然孤陋寡闻的从来没听过这个低调的技术,相比WebService,Hessian更简单、快捷,采用的是二进制RPC协议,它很适合于发送二进制数据。http://hessian.caucho.com/ 这是它的官网,里面罗列了各种相关语言之间的支持,略高端啊,相比它采用http-servlet的方式来调用,在项目中添加此模块相关的servlet,故无需再监听端口,就能很好的绕过我这里实际的问题,所以最终采用它来实现项目中远程接口调用。
首先需要下载需要的jar文件,截止到今天所使用的版本为最新的版本,其他版本的之前也没什么了解,就使用当前最新饿版本吧。
hessian-4.0.37.jar (845k) hessian-4.0.37-src.jar (388k) 2013/09/18
既然是采用http-servlet的方式实现,那就先从servlet的代码开始吧,使用Servlet3.0的规范,直接使用@Servlet注解实现,并且需要继承HessianServlet(它就是一个servlet)类,其实这个Servlet类也是我们的业务实现类,相关参考代码如下:
1)接口定义类:
package com.hessian.server;
public interface IUserService {
public void sayHello();
}
2)接口实现类:
package com.hessian.server.impl;
import javax.servlet.annotation.WebServlet;
import com.caucho.hessian.server.HessianServlet;
import com.hessian.server.IUserService;
@WebServlet("/hessianServlet-userService")
public class UserService extends HessianServlet implements IUserService {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public void sayHello() {
System.out.println("sayHello..........OK.");
}
}
说明:和rmi不同的是,这种实现方式,无需绑定启动,只需要让tomcat启动就可以了,然后后面再调用这个servlet类,如果直接在浏览器中输入此Servlet的地址页面直接会报500错误,我们可以在HessianServlet中的265行中看到。
3)启动服务
所谓的启动服务就是启动tomcat。
4) 客户端调用
package com.hessian;
import com.hessian.server.IUserService;
public class Test {
public static void main(String[] args) {
IUserService hello = HessianHelper
.createClient(
"http://localhost:8080/HessianServer/hessianServlet-userService",
IUserService.class);
hello.sayHello();
}
}
工具类: (为省事儿直接拿的开源中国上的大牛的代码)
package com.hessian;
import java.net.MalformedURLException;
import com.caucho.hessian.client.HessianProxyFactory;
public class HessianHelper {
@SuppressWarnings("unchecked")
public static <T> T createClient(String hessianURL, Class<T> interfaceClass) {
T client = null;
try {
HessianProxyFactory factory = new HessianProxyFactory();
client = (T) factory.create(interfaceClass, hessianURL);
} catch (MalformedURLException e) {
e.printStackTrace();
}
return client;
}
}
点赞