网络编程指同一网络或者不同网络的计算机之间的数据交换
协议:网络的一种规则
端口:计算机与外部进行数据交互的一个门
-
网络编程的分类
网络通信和网络交互
java语言中的网络编程中只实现网络通信其根本就是socket和socketServer -
网络交互的实现方法
ajax跨域请求
RMI
RPC -
RMI
(一) 运行原理
RMI远程方法调用(Remote Method Invocation),能够让java虚拟机上的对象像调用本地对象一样调用另一个java虚拟机中的方法(底层是由socket和java序列化和反序列化支撑起来的)
首先服务端通过Registry生成一个桩(Stub)和骨架(Skeleton)用于描述方法和解析方法调用,客户端通过Registry获取桩(Stub),在通过桩(Stub)调用骨架(Skeleton),由服务端的Skeleton解析后调用相应的方法,最后将结果返回(二) RMI的用途
RMI是为了分布式java引用之间的远程通信提供服务,提供分布式服务,目前主要应用时封装在各个J2EE项目架构中,例如Sring,EJB(两者均分装了RMI技术)(三) 优点
1)面向对象 RMI可以将完整的对象作为参数和返回值进行传递
2)可移动属性 RMI可以将属性在客户端和服务端自由移动
3)安全 RMI使用java内置的安全机制
4)方便编写和使用(四 )缺点
RMI依赖于java远程信息交换协议JRMP(Java Rmote Messging Proticil),该协议为java定制,要求服务端和客户端均为java编写(五)编写实现
1)远程服务的接口定义
public interface IMyserver extends Remote{
//加法
public int add(int a,int b) throws RemoteException;
}
必须继承Remote接口,该接口是一个标记接口,且必须声明public,因为是网络通信(经常出现异常)还必须抛出RemoteException
2)远程服务的接口实现
public class MyServerImpl extends UnicastRemoteObject implements IMyserver{
private static final long serialVersionUID = 1L;
protected MyServerImpl() throws RemoteException {
}
@Override
public int add(int a, int b) throws RemoteException {
return a+b;
}
}
实现类需要继承UnicastRemoteObject
3)定义服务端程序入口
public static void main(String[] args) throws RemoteException, AlreadyBoundException {
Registry registry = LocateRegistry.createRegistry(1029);
//RMI默认端口1029
IMyserver server = new MyServerImpl();
registry.bind("server", server);
// bind(String name,Remote obj) 绑定对此注册表中指定 name 的远程引用。
//name : 与该远程引用相关的名称 obj : 对远程对象(通常是一个 stub)的引用
}
4)客户端实现
将服务端导出jar包导入到客户端
public static void main(String[] args) throws RemoteException, NotBoundException {
Registry registry = LocateRegistry.getRegistry("127.0.0.1", 1029);
IMyserver server = (IMyserver) registry.lookup("server");
System.out.println(server.add(1, 2));
}
-
RPC
RPC(Remoat Procedure Call) 远程过程调用协议,我们可以理解为是一种不同计算机之间的网络交互的协议,RPC其实就是将流从一台计算机传输到另外一台计算机,本次webService使用的是XFire框架(一)特点
1)通过网络传输
2)跨平台
3)基于请求响应
4)只调用过程,不需要关注细节(二)创建的RPC的调用技术
1)jdk原生(HttpURLConnection 报文发送)
2)Thrift
3)SpringCloud(基于Socket,SOA架构的分布式框架)
4)Doubbo (阿里巴巴,基于Socket,SOA架构的分布式框架)
5)WebService(跨越语言,基于SOAP协议,走xml数据或json数据)
6)Hessian(跨语言,走二进制)
7)HttpClient(通常用于RESTfull风格,跨语言,基于http和json)(三)WSDL
WSDL(Web Service Description Language)服务描述语言,将服务端的功能通过xml描述出来,且描述出来,且标识出服务的地址,然后提供调用者使用(四)在客户端代调用服务端的方式
1、内部访问 xfire代理工厂
备注:服务端开放源代码或者给出想要jar包
2、远程访问:通过wsdl回调服务端的函数
通过url来生成wsdl(五)代码实现
1、创建web项目导入jar包
2、编写接口以及实现类
public interface IIWss {
public int qiuHe(int canShu1,int canShu2);
public List<User> getList();
public User getUser();
}
//实现类
public class IWssImpl implements IIWss {
@Override
public List<User> getList() {
List<User> list = new ArrayList<User>();
list.add(new User(1, "zhy"));
list.add(new User(2,"zhu"));
return list;
}
@Override
public User getUser() {
return new User(3, "啦啦啦");
}
@Override
public int qiuHe(int canShu1, int canShu2) {
return canShu1+canShu2;
}
}
3、修改web.xml
<servlet>
<servlet-name>XFireServlet</servlet-name>
<servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>XFireServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
4、修改service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xfire.codehaus.org/config/1.0">
<service>
<name>IWss</name>
<serviceClass>com.bj.rd.IIWss</serviceClass>
<implementationClass>com.bj.rd.IWssImpl</implementationClass>
<style>wrapped</style>
<use>literal</use>
<scope>application</scope>
</service>
</beans>
5、创建普通java项目的客户端
5.1)webservice 内部访问
//webservice 内部访问
public static void main(String[] args) throws MalformedURLException {
//将opjo对象转换为web Service
Service service = new ObjectServiceFactory().create(IIWss.class);
//获取xfir
XFire xFire = XFireFactory.newInstance().getXFire();
//为xfir获取一个代理工厂对象
XFireProxyFactory factory = new XFireProxyFactory(xFire);
String url = "http://127.0.0.1:8080/WBServer/services/IWss";
//得到一个本地的服务代理
IIWss sr = (IIWss) factory.create(service, url);
//简单对象
System.out.println(sr.qiuHe(5, 3));
//复杂对象
System.out.println(sr.getList());
System.out.println(sr.getUser());
}
5.2)webservice 外部访问
//webservice 外部访问
public static void main(String[] args) throws MalformedURLException, Exception {
Client client = new Client(new URL("http://127.0.0.1:8080/WBServer/services/IWss?wsdl"));
Object[] invoke = client.invoke("qiuHe", new Object[]{1,2});
//简单对象
System.out.println(invoke[0]);
//复杂对象
Object[] user = client.invoke("getUser", new Object[]{""});
Object[] list = client.invoke("getList", new Object[]{""});
System.out.println(user[0]);
System.out.println(Arrays.toString(list));
}
注意:外部访问无法获取返回值为复杂对象的方法,只能获取返回值为简单对象的方法
由于service类在很多情况下并不是只有自己开发的,这时候很有可能你没有办法得到service类,但是service发布的wsdl文件可以得到。xfire可以通过wsdl生成client