使用eclipse开发RCP系统,如果需要系统保持更新,不可避免的需要实现RCP的更新功能。
对于教程上RCP更新的实现的这里不赘述。本文探讨的是对于部署在支持http协议的更新服务器的RCP系统,利用http协议实现系统的更新。
大略看过一下org.eclipse.update.core及相关更新功能插件代码,基本原理是一样的,都是使用httpURL下载更新代码,并且eclipse做的功能更为强大,比如features及plugins的查找安装、低版本过滤、环境过滤、多线程下载、下载对话框、进度条、站点解析、异常等等,不过eclipse在更高的版本已经抛弃了这种更新方式。这里只是截取部分代码加上自己的理解所写。使用单线程。
背景
1. RCP系统部署在tomcat-6.0.30服务器上.
2. RCP系统基于features。
3. RCP系统更新内容(features,plugins)的打包构建方式与等同于普通方式。
4. site站点的创建可以是在eclipse创建site更新站点的方式。
使用httpUrlConnection实现下载
假定一个字符串urlString指向一个网络上的资源地址。
locationFileName是将资源下载到本地时所指定的名称。那么可以使用以下代码片段来下载一个资源。
publicstaticboolean download(String destUrl, String locationFileName)
{
URL url = getURL(destUrl); //通过new URL(string)方式得到URL
if (null == url)
{
returnfalse;
}
Downloader dl = new Downloader();
HttpURLConnection httpUrl = dl.getURLConnection(url);
if (null == httpUrl)
{
returnfalse;
}
BufferedInputStream bis = null;
FileOutputStream fos = null;
try
{
// 获取网络输入流
bis = new BufferedInputStream(httpUrl.getInputStream());
// 建立文件
fos = new FileOutputStream(locationFileName);
int size = 0;
byte[] buf = newbyte[UpdateConstants.BUFFER_SIZE];
// 保存文件
while ((size = bis.read(buf)) != -1)
{
fos.write(buf, 0, size);
}
fos.close();
bis.close();
httpUrl.disconnect();
returntrue;
}
catch (Exception e)
{
e.printStackTrace();
}
returnfalse;
}
/**
* 功能描述 : 检测当前URL是否可连接或是否有效,
* 最多连接网络 5 次, 如果 5 次都不成功说明该地址不存在或视为无效地址.
* @param url
* 指定URL网络地址
* @return String
*/
publicsynchronized HttpURLConnection getURLConnection(URL url)
{
int counts = 0;
while (counts++ < 5)
{
try
{
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
if (200 == connection.getResponseCode())
{
return connection;
}
}
catch (IOException ex)
{
continue;
}
}
System.out.println(“no connect”);
returnnull;
}
实现RCP更新
1. 远程服务器是url=http://10.80.21.10:8080/sdfx,
2. 站点的更新配置文件是site.xml.
3. 本地客户端的feature都在features/文件夹下,plugin都在plugins/文件夹下。
第一步,找服务器上的feature
触发更新操作后,首先通过httpURLConnection将(url+”/site.xml”)指定site.xml文件读入一个新建缓冲输入流如下:
// 获取网络输入流
bis = new BufferedInputStream(httpUrl.getInputStream());
DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
document = parser.parse(bis);
site.xml文件格式固定,我们通过document解析这个文件,得到我们需要更新的feature的列表。我们得到了这些feature的名称,也就得到了他们的绝对URL路径。
第二步,判断是否需要更新
将第一步得到的featureList中的元素与本地的所有的localFeatureList中的元素通过名称中的id部分一一对比,如果找到相同的id的feature在服务器上有更新的版本,那么久认为这个站点是有更新的内容的。
第三步,下载每一个feature
在第一步中找到了许多feature,经过第二步过滤后,对剩下的feature进行下载,并放到本地的feature目录下。下载到本地后feature名称沿用。这里,关键的是feature的URL路径需要构建正确。下载的代码亦然如上。要注意的是下载待本地的feature文件是一个jar包,需要通过解压jar来获得里面的信息。通过unjar方法来做到上述(解压后删除源文件)。
/**
* 解压
* @param fileName
* @param locationPath
* @return
*/
privateboolean unJar(String fileName, String locationPath)
{
File file = new File(fileName);
try
{
JarFile jarFile = new JarFile(file);
unzip(jarFile, locationPath, 8192);
jarFile.close();
}
catch (IOException e)
{
e.printStackTrace();
returnfalse;
}
if (file.exists())
{
file.delete();
}
returntrue;
}
/**
* 解压缩zip格式的压缩文件。
* @param zipFile zip压缩包
* @param localPath 解压的目的地
* @param bufferSize 解压过程中使用的buffer的大小
*/
publicstaticvoid unzip(ZipFile zipFile, String localPath, int bufferSize)
{
byte[] buffer = newbyte[bufferSize];
ZipInputStream zip = null;
ZipEntry zipEntry = null;
try
{
zip = new ZipInputStream(new FileInputStream(zipFile.getName()));
while ((zipEntry = zip.getNextEntry()) != null)
{
File file = new File(localPath, zipEntry.getName()).getAbsoluteFile();
if (zipEntry.isDirectory())
{
file.mkdirs();
}
else
{
File parent = file.getParentFile();
if (!parent.exists())
{
parent.mkdirs();
}
file.createNewFile();
long size = zipEntry.getSize();
FileOutputStream fos = null;
try
{
fos = new FileOutputStream(file);
int readLen = -1;
while (size != 0)
{
readLen = zip.read(buffer);
size -= readLen;
if (readLen != -1)
{
fos.write(buffer, 0, readLen);
}
}
}
finally
{
if (fos != null)
{
fos.close();
}
}
}
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (zip != null)
{
zip.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
第四步,解析feature.xml文件找plugin
解压后,在文件夹中有固定名称为feature.xml文件,我们来解析这个文件。解析后我们得到一个plugins的信息列表。我们得到了这个列表,也就知道了需要下载的plugins的绝对URL。
第五步,下载每一个plugin
对于每一个plugin信息,检查这个plugin是否是一个第三方的依赖插件(我们只用到了某一个功能),如果是并且本地已经有了该插件,我们可以忽略。而,如果这个插件需要依赖第三方的插件,还需要检查这个插件依赖的插件是否已经存在于本地客户端中了,如果没有,则不可以安装该插件(这里有瑕疵, 就是要求必须要先安装依赖插件)。
如果上面的条件已经具备,下面就是需要构建一个指向该plugin的URL。然后下载这个plugin。下载成功后,我们还需要根据feature中的该plugin的unpack属性来确认该plugin是否需要解压。解压过程如上。
在下载每一个feature中的plugin之前我们需要做一个list来存放我们已经下载plugin,用来保证在某一个plugin下载失败时,该feature全部回滚。
其他
在打包构建时,我们还可以在feature工程中打包一个updateConfig.ini文件,这个文件中记录本次更新中需要删除的一些插件(防止插件扩展了同一个扩展点,但是这个扩展点又不允许同时有两个扩展的冲突)、需要更新的第三方插件、是不是替换本地客户端的某些资源文件、是不是需要二次启动。
通过配置该文件,我们能修改客户端的某些配置文件(如config.ini),覆盖资源文件(xml,xls等RCP系统工作过程中所需要的),删除一些插件(给系统瘦身,RCP系统的普通更新方式是增量更新,不删除过时的插件)、以及是否需要重启动。
重启动:有些资源或功能不能通过在更新中来完成,比如config.ini文件需要重写时,如果本地客户端旧代码中没有在更新时就修改config.ini的功能代码,而是想通过刚刚更新下去的代码来在重启时来修改config.ini文件,就需要二次启动。因为在eclipse启动时,eclipse本身首先来加载config.ini文件,系统启动进入到我们能控制的代码时,再修改config.ini文件已经不起作用(如果不重启的话),因此我们可以在主插件启动时,检测updateConfig.ini文件,看其是否指明了在启动时需要做的工作(为防止每次都重启,可以通过修改updateConfig.ini中的属性或是有无unpdateConfig.ini文件来判定)。
相关推荐
本文将详细介绍如何利用HttpURLConnection实现Android应用中的断点续传功能。 首先,理解断点续传的概念。断点续传是指当下载或上传文件过程中因网络问题中断后,可以从上次中断的位置继续进行,而不是重新开始。这...
1. **创建连接**:使用`URL`对象构造一个`HttpURLConnection`实例,通常会通过`openConnection()`方法来实现。例如: ```java URL url = new URL("http://yourserver.com/upload"); HttpURLConnection connection...
本篇文章将详细讲解如何使用`HttpURLConnection`实现文件上传,同时涉及到服务器端处理上传文件的代码。我们将讨论以下核心知识点: 1. **HttpURLConnection介绍**: `HttpURLConnection`是Java标准库中的类,它是...
HttpURLConnection实现三方接口HTTP调用调用,带有FILE文件参数
CUrl类是一个基于Java的HttpURLConnection实现的网络通信工具,其设计灵感来源于命令行工具CUrl。CUrl命令行工具广泛用于在各种协议下发送数据,包括HTTP、HTTPS、FTP等,而CUrl类则是将这种功能移植到了Java平台,...
实例Demo程序来示范使用HttpURLConnection实现多线程下载。 使用多线程下载文件可以更快完成文件的下载,因为客户端启动多条线程进行下载就意味着服务器也需要为该客户端提供响应的服务。假设服务器同时最多服务100...
本教程将详细讲解如何使用HttpURLConnection实现单线程、多线程下载以及多线程续点下载。 **一、单线程下载** 单线程下载是最基础的下载方式,它通过一个连接获取服务器资源并写入本地文件。以下是一个简单的单...
在本文中,我们将深入探讨如何使用HttpURLConnection实现文件上传,同时也会涉及普通参数的传递。 首先,我们需要理解HTTP请求的基本结构。HTTP请求通常由以下几个部分组成:请求行、请求头、空行和请求体。在文件...
本例演示最简单的android客户端和服务器端通信,客户端使用android4.0以上版本,服务器端为dynamic web project工程,使用时将client...因为android6.0以上不再支持httpclient通信,故本例使用HttpURLConnection类演示
虽然`HttpURLConnection`本身不支持异步操作,但可以在单独的线程或使用ExecutorService来实现异步HTTP请求。 8. **重定向处理**: 默认情况下,`HttpURLConnection`会自动处理HTTP状态码为3xx的重定向。如果不想...
总结来说,Java实现多次HttpURLConnection共享session的关键在于正确处理Cookie,保存服务器返回的Session ID,并在后续请求中携带这个ID。通过这种方式,即使没有浏览器环境,也能模拟登录状态,爬取登录后的内容。...
在给定的代码片段中,展示了如何使用`HttpURLConnection`进行文件下载。 首先,我们看到代码引入了`java.io`、`java.net`和`java.util`这三个包。`java.io`包含了输入/输出流,用于处理数据的读写;`java.net`包含...
可以使用Java的HttpURLConnection或者Apache HttpClient库来实现。数据格式可能是JSON或XML,取决于服务器接口的要求。 5. 错误处理:在数据上传过程中,需要考虑网络异常、服务器错误等可能性,通过try-catch语句...
本文将详细介绍这两种方式的实现原理及如何在实际项目中使用。 首先,`HttpURLConnection`是Java标准库提供的网络通信接口,它是低级别的API,允许应用程序与HTTP服务器进行交互。使用`HttpURLConnection`进行网络...
本例子是关于如何将`AsyncTask`与`HttpURLConnection`结合,实现一个简单的网络请求。 `AsyncTask`是Android提供的轻量级异步任务框架,它允许开发者在后台线程执行耗时操作,并在主线程更新UI。`AsyncTask`包含三...
JAVA通过HttpURLConnection上传和下载...这些方法可以帮助开发者快速实现文件上传和下载的功能,从而提高开发效率和质量。同时,HttpURLConnection也可以用于发送其他类型的HTTP请求,例如GET、POST、PUT、DELETE等。
它是Java中实现HTTP通信的基础,相较于旧的`java.net.URL`和`java.net.HttpURLConnection`,它提供了更多的控制和优化选项,如设置请求方法、自定义头信息、处理响应码等。在这个主题中,我们将深入探讨...
在Java编程中,`HttpURLConnection`是用于处理HTTP协议的核心类,它提供了向网络资源发起...`HttpURLConnection`虽然简洁,但在高级功能上可能需要结合其他库,如OkHttp或Apache HttpClient,以实现更高效的网络通信。
本知识点将深入探讨如何使用`HttpURLConnection`与Servlet协同工作,处理多文件参数以及实现断点上传功能。 首先,`HttpURLConnection`是Java API中的一个核心类,它负责提供HTTP协议的连接功能。相比Apache ...