本期概述
上期我们学习了html页面采集后的数据查询, 但这仅仅是在本地查询数据库,如果我们想通过远程操作来进行数据的采集,存储和查询,那又该怎么做呢?
今天我们一起来学习下:如何通过本地客户端远程访问服务端进行数据的采集,存储和查询.
数据采集页面 2011-2012赛季英超球队战绩
学习简单远程访问(RMI实例)
首先我们学习下简单的客户端远程访问服务端的例子.
这里用到了 Java RMI (Remote Method Invocation)
Java RMI是一种机制, 是能够让一个 java虚拟机 调用 另一个java 虚拟机上对象的方法, 从而实现远程访问.
但是通过客户端实现该远程访问,必须绑定一个远程接口对象(意味着客户端可以访问到的服务端上的方法必须全部包含在这个接口里).
好了,我们来写下例子代码.
定义远程接口
首先,我们需要写个远程接口HelloInterface 该接口继承了远程对象Remote.
接口HelloInterface里面有个sayHello的方法,用于客户端连接后 打招呼.
由于sayHello方法继承了远程Remote对象, 所以需要抛一个 RemoteException 远程异常.
package Remote_Interface; import java.rmi.Remote; import java.rmi.RemoteException; /** * 接口HelloInterface 继承了 远程接口 Remote 用于客户端Client远程调用 * @author SoFlash - 博客园 http://www.cnblogs.com/longwu */ public interface HelloInterface extends Remote{ public String sayHello(String name) throws RemoteException; }
实现接口(实现接口在服务端)
接下来,我们实现下 该接口里的方法, 实现接口的方法在服务端.
这里的HelloInterfaceImpl类 实现了接口HelloInterface里的方法.
注意:这里HelloInterfaceImpl 同样继承了 UnicastRemoteObject 远程对象,这个必须写,虽然不写 代码智能提示不会提示有错,但服务端启动后会莫名其妙报错.
由于 UnicastRemoteObject 远程对象 需要抛出一个RemoteException 异常, 所以这里用了一个构造方法 HelloInterfaceImpl() 来抛这个异常.
package Server; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import Remote_Interface.HelloInterface; /** * HelloInterfaceImpl 用于实现 接口HelloInterface 的远程 SayHello方法 * @author SoFlash - 博客园 http://www.cnblogs.com/longwu */ @SuppressWarnings("serial") // 继承 UnicastRemoteObject 远程对象 这个一定要写 否则 服务端启动报异常 public class HelloInterfaceImpl extends UnicastRemoteObject implements HelloInterface{ //HelloInterfaceImpl的构造方法 用于抛出UnicastRemoteObject 远程对象里的异常 protected HelloInterfaceImpl() throws RemoteException { } public String sayHello(String name) throws RemoteException { //该信息 在客户端上发出 String strHello = "你好! " + name+" 欢迎访问服务端!"; //这条信息 是在服务端上 打印出来 System.out.println(name +" 正在 访问本服务端!"); return strHello; } }
编写服务端
接下来,我们来写 服务端,由于RMI 实现远程访问的机制是指:客户端通过在RMI注册表上寻找远程接口对象的地址(服务端地址) 达到实现远程访问的目的,
所以,我们需要在 服务端 创建一个远程对象的注册表,用于绑定和注册 服务端地址 和 远程接口对象,便于后期客户端能够成功找到服务端 (详细请看代码注释).
package Server; import java.net.MalformedURLException; import java.rmi.AlreadyBoundException; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import Remote_Interface.HelloInterface; /** * Server 类 用于 启动 注册服务端 * @author SoFlash - 博客园 http://www.cnblogs.com/longwu */ public class Server { public static void main(String[] args) { try { // 定义远程接口HelloInterface 对象 用于绑定在服务端注册表上 该接口由HelloInterfaceImpl()类实现 HelloInterface hInterface = new HelloInterfaceImpl(); int port = 6666; // 定义一个端口号 // 创建一个接受对特定端口调用的远程对象注册表 注册表上需要接口一个指定的端口号 LocateRegistry.createRegistry(port); // 定义 服务端远程地址 URL格式 String address = "rmi://localhost:" + port + "/hello"; // 绑定远程地址和接口对象 Naming.bind(address,hInterface); // 如果启动成功 则弹出如下信息 System.out.println(">>>服务端启动成功"); System.out.println(">>>请启动客户端进行连接访问"); } catch (MalformedURLException e) { System.out.println("地址出现错误!"); e.printStackTrace(); } catch (AlreadyBoundException e) { System.out.println("重复绑定了同一个远程对象!"); e.printStackTrace(); } catch (RemoteException e) { System.out.println("创建远程对象出现错误!"); e.printStackTrace(); } } }
编写客户端
服务端写完了,我们来写下访问服务端需要的客户端.
客户端上同样需要定义一个 远程访问的地址 - 即服务端地址,
然后,通过在RMI注册表上寻找 该地址; 如果找到 则建立连接.
package Client; import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; import Remote_Interface.HelloInterface; /** * Client 用于连接 并访问 服务端Server * @author SoFlash - 博客园 http://www.cnblogs.com/longwu */ public class Client { public static void main(String[] args) { // 定义一个端口号 该端口号必须与服务端的端口号相同 int port = 6666; // 同样定义一个远程地址 该地址为服务端的远程地址 所以 与服务端的地址是一样的 String address = "rmi://localhost:" + port + "/hello"; // 在RMI注册表上需找 对象为HelloInterface的地址 即服务端地址 try { HelloInterface hInterface = (HelloInterface) Naming.lookup(address); // 一旦客户端找到该服务端地址 则 进行连接 System.out.println("<<<客户端访问成功!"); //客户端 Client 调用 远程接口里的 sayHello 方法 并打印出来 System.out.println(hInterface.sayHello("SoFlash")); } catch (MalformedURLException e) { System.out.println("错误的地址!"); e.printStackTrace(); } catch (RemoteException e) { System.out.println("创建远程对象出错!"); e.printStackTrace(); } catch (NotBoundException e) { System.out.println("未绑定的远程对象!"); e.printStackTrace(); } } }
运行程序
首先,启动服务端,这里用的是 导出的服务端可运行jar文件.
然后,启动客户端来访问,服务端反馈一条访问成功信息:你好! SoFlash 欢迎访问服务端!
同时服务端显示:客户端用户SoFlash 正在访问本服务端
例子介绍完了,你是否明白了呢? :p
附上例子 源代码 下载 Remote_Hello.zip
jar文件 客户端 Hello_Client_jar.zip 服务端 Hello_Server_jar.zip
远程数据采集实现
定义远程接口
例子学完,那么让我们来 一起实现下 远程访问服务端 实现 足球网站的数据采集.
首先,我们写个 远程接口DataQueryInterface,它继承了远程对象Remote 里面包含了一些空方法,在服务端的DataQueryImpl类里面实现.
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
编写服务端(服务端包含了接口的实现)
接口完成, 我们来写下服务端代码.
Server类是包含了一个主函数 并且 绑定了远程接口对象(详细介绍 请看代码注释).
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
DataCollectionAndStorage 类 以及里面的dataCollectAndStore() 方法 用于收集和存储数据.
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
实现接口(在服务端)
DataQueryImpl 类 用于实现接口DataQueryInterface 以及里面的所有方法 (具体请看代码及注释).
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
DataStructure类 简单的数据结构 用于页面采集到的数据 临时性的存储.
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
GroupMethod类 以及 里面的regularGroup()方法 用于匹配 并抓取 html 页面上需要的数据.
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
MySql类 用于实施 MySql数据库操作 里面包含了2个方法
- datatoMySql() 方法 用于向数据库里插入数据
- queryMySql() 方法 用于查询数据
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
编写客户端
客户端 Client 类包含了一个客户端主函数,用于连接并访问服务端.
通过在RMI注册表上需找 服务端的地址 来获取对服务端的连接和访问 (详细请看 代码注释).
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
运行数据采集器
代码写好了, 我们来运行看看.
启动服务端
启动客户端来连接服务端
输入1 清空数据 服务端方 显示 "数据库清空成功!"
同时客户端显示 "服务端上数据清空完毕!"
输入2 操作服务端插入数据
我们看到 大量的数据被成功插入到服务端上.
客户端也最终 显示 "服务端上数据收集成功!".
输入3 在客户端上查看服务端上收集到的所有球队名称.
输入4选择 按球队查询比赛结果,再输入球队名称 查看到该球队的比赛记录. 这里查看的球队是 NewCastle
输入5 选择按日期查看比赛结果,这里查看的日期是 03.01.2012
我们输入1 清空下数据库,检测下是否真正清空.
输入3 通过查看所有球队名称来检测 是否数据库里的数据已被清空.
这样,我们的客户端远程访问服务端就做好了. :)
这里我们的java网页数据采集器教程也就告于段落了,如果对此感兴趣的学友,可以订阅本博客或是关注一下! 欢迎常来学习和讨论. :)
附上源代码 htmlDataQuery_RemoteVisit.zip
以及 jar文件 服务端 htmlDataQuery_Server_jar.zip 客户端 htmlDataQuery_Client_jar.zip