Java RMI 实现代码动态下载

合集下载

JAVA_RMI使用快速入门

JAVA_RMI使用快速入门

JAVA_RMI使用快速入门Java RMI(Remote Method Invocation,远程方法调用)是一种用于实现分布式系统的Java API,它允许在不同的Java虚拟机上通过网络调用远程对象的方法。

在这篇文章中,我们将快速入门Java RMI,并了解如何使用它来创建一个简单的分布式系统。

1.理解RMI的概念RMI的基本思想是将远程调用看作是本地调用的一种特殊形式,在RMI中,客户端和服务器可以通过网络传输Java对象的引用。

客户端可以通过远程对象的引用来调用它的方法,就像调用本地对象一样。

2.创建远程接口首先,我们需要定义一个远程接口,它列出了远程对象上可用的方法。

这个接口必须扩展java.rmi.Remote接口,并且每个方法都必须声明抛出java.rmi.RemoteException异常。

下面是一个简单的例子:```javaimport java.rmi.Remote;import java.rmi.RemoteException;public interface Hello extends RemoteString sayHello( throws RemoteException;```3.实现远程接口接下来,我们需要实现远程接口,并发布它作为一个RMI对象。

通过扩展java.rmi.server.UnicastRemoteObject类并实现远程接口,我们可以创建一个远程对象。

下面是实现上面接口的一个例子:```javaimport java.rmi.RemoteException;import java.rmi.server.UnicastRemoteObject;public class HelloImpl extends UnicastRemoteObject implements Hellopublic HelloImpl( throws RemoteExceptionsuper(;}public String sayHello( throws RemoteExceptionreturn "Hello, world!";}```4.注册远程对象在将远程对象发布到网络之前,我们需要创建一个注册表来管理远程对象的绑定。

JAVA实现下载文件功能的两种方法

JAVA实现下载文件功能的两种方法

JAVA实现下载⽂件功能的两种⽅法第⼀种⽅法:public HttpServletResponse download(String path, HttpServletResponse response) {try {// path是指欲下载的⽂件的路径。

File file = new File(path);// 取得⽂件名。

String filename = file.getName();// 取得⽂件的后缀名。

String ext = filename.substring(stIndexOf(".") + 1).toUpperCase();// 以流的形式下载⽂件。

InputStream fis = new BufferedInputStream(new FileInputStream(path));byte[] buffer = new byte[fis.available()];fis.read(buffer);fis.close();// 清空responseresponse.reset();// 设置response的Headerresponse.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));response.addHeader("Content-Length", "" + file.length());OutputStream toClient = new BufferedOutputStream(response.getOutputStream());response.setContentType("application/octet-stream");toClient.write(buffer);toClient.flush();toClient.close();} catch (IOException ex) {ex.printStackTrace();}return response;}public void downloadLocal(HttpServletResponse response) throws FileNotFoundException {// 下载本地⽂件String fileName = "Operator.doc".toString(); // ⽂件的默认保存名// 读到流中InputStream inStream = new FileInputStream("c:/Operator.doc");// ⽂件的存放路径// 设置输出的格式response.reset();response.setContentType("bin");response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");// 循环取出流中的数据byte[] b = new byte[100];int len;try {while ((len = inStream.read(b)) > 0)response.getOutputStream().write(b, 0, len);inStream.close();} catch (IOException e) {e.printStackTrace();}}public void downloadNet(HttpServletResponse response) throws MalformedURLException {// 下载⽹络⽂件int bytesum = 0;int byteread = 0;URL url = new URL("/logo.gif");try {URLConnection conn = url.openConnection();InputStream inStream = conn.getInputStream();FileOutputStream fs = new FileOutputStream("c:/abc.gif");byte[] buffer = new byte[1204];int length;while ((byteread = inStream.read(buffer)) != -1) {bytesum += byteread;System.out.println(bytesum);fs.write(buffer, 0, byteread);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}第⼆种⽅法:public void downLoad(String filePath, HttpServletResponse response, boolean isOnLine) throws Exception {File f = new File(filePath);if (!f.exists()) {response.sendError(404, "File not found!");return;}BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));byte[] buf = new byte[1024];int len = 0;response.reset(); // ⾮常重要if (isOnLine) { // 在线打开⽅式URL u = new URL("file:///" + filePath);response.setContentType(u.openConnection().getContentType());response.setHeader("Content-Disposition", "inline; filename=" + f.getName());// ⽂件名应该编码成UTF-8} else { // 纯下载⽅式response.setContentType("application/x-msdownload");response.setHeader("Content-Disposition", "attachment; filename=" + f.getName());}OutputStream out = response.getOutputStream();while ((len = br.read(buf)) > 0)out.write(buf, 0, len);br.close();out.close();}以上就是JAVA实现下载⽂件功能的两种⽅法的详细内容,更多关于JAVA实现下载⽂件的资料请关注其它相关⽂章!。

javaRMI及简单实例

javaRMI及简单实例

远程方法调用实验报告1.摘要简单介绍了java中的RMI框架的基本原理及应用,给出了java 中创建一个RMI应用的基本步骤。

在此基础上设计了一个采用RMI技术实现远程方法调用的实验,客户端调用服务器端的远程对象的方法,获取服务器端的系统时间,将结果返回客户端。

此外还对实验结果还进行了分析。

2.实验背景RMI采用客户/服务器通信方式。

在服务器上部署了提供各种服务的远程对象,客户端请求访问服务器上的远程对象的方法。

如图1所示,是RemoteServiceClass一个远程对象,它运行在服务器上,客户端请求调用RemoteServiceClass对象的echo()方法。

图1 客户端请求调用服务器上的远程对象的方法如图2所示,RMI采用代理来负责客户和远程对象之间通过Socket进行通信的细节。

RMI框架为远程对象分别生成了客户端代理和服务器端代理。

位于客户端的代理类称为存根(Stub),位于服务器端的代理类称为骨架(Skeleton)。

图2 RMI框架采用代理来封装通信细节当客户端调用远程对象的一个方法时,实际上是调用本地存根对象的相应方法。

存根对象和远程对象具有同样的接口。

存根采用一种与平台无关的编码方式,把方法的参数编码为字节序列,这个编码过程称为参数编组。

RMI主要采用java序列化机制进行参数编组。

接着,存根把请求信息发送给服务器,服务器端接收到客户端的请求信息,然后由相应的骨架对象来处理这一请求信息,把处理后的返回值或者异常编组后发送给客户。

客户端的存根接收到服务器发送过来的编组后的返回值或者异常,再对它进行反编组,就得到调用远程方法的返回结果。

存根与骨架类通过Socket来通信。

开发人员无须手工编写客户端的存根类及服务器端的骨架类,它们都由RMI框架创造。

在JDK5.0以前的版本中,需要用rmic命令来为远程对象生成静态的代理类(包括存根和骨架类)。

而在JDK5.0中,RMI框架会在运行时自动为远程对象生成动态代理类(包括存根和骨架类),从而更彻底封装了RMI 框架的实现细节,简化了RMI框架的使用方式。

java代码动态编译

java代码动态编译

Java代码动态编译1. 简介在Java开发中,编写好的代码需要经过编译才能运行。

通常情况下,我们会使用Java的编译器将代码转换成字节码,然后再由Java虚拟机(JVM)执行。

但有时候,我们可能需要在程序运行过程中动态地编译代码,即实现Java代码动态编译。

本文将详细介绍Java代码动态编译的概念、用途和实现方式。

2. 动态编译的概念动态编译是指在程序运行过程中,将一段字符串类型的Java代码转换成可执行的字节码,并且执行该字节码。

相比于传统的静态编译,动态编译允许我们在不修改源代码的情况下,根据特定的需求生成代码并执行。

3. 动态编译的用途动态编译在某些场景下非常有用。

下面列举了几种常见的用途:3.1 插件开发动态编译可以用于插件化开发。

我们可以允许用户在程序运行时加载、卸载和更新插件,而无需重启整个应用程序。

插件以字符串的形式传入,通过动态编译生成可执行的字节码,然后被加载和执行。

3.2 动态织入动态编译还可以用于AOP(面向切面编程)。

在AOP中,我们可以在运行时根据特定规则将切面代码织入到目标代码中,实现类似于日志记录、性能监控等功能。

3.3 脚本语言支持通过动态编译,Java程序可以支持解释脚本语言,比如JavaScript、Groovy等。

这样做的好处是,程序允许用户通过脚本语言编写部分逻辑,动态地加载和执行。

3.4 运行时代码生成有时候我们需要根据特定的需求生成代码,然后立即执行。

动态编译可以满足这一需求。

通过字符串拼接生成代码,然后动态编译执行,可以减少反射等运行时开销。

4. 动态编译的实现方式在Java中,动态编译的实现方式有多种,下面介绍两种常见的方式:4.1 使用Java Compiler APIJava Compiler API允许我们在程序运行时动态地将Java代码编译为字节码。

它提供了一个接口javax.tools.JavaCompiler,通过该接口我们可以获取到Java编译器,并使用它编译代码。

rio枚举过程

rio枚举过程

rio枚举过程以下是标题为"RIO枚举过程"的内容:RIO枚举过程RIO (Remote Insecure Object)枚举是一种针对Java RMI(Remote Method Invocation)服务的攻击方式,它利用Java序列化数据的特性来执行任意代码。

RIO枚举的过程主要分为以下几个步骤:1. 扫描目标主机需要扫描目标主机开放的TCP端口,通常Java RMI服务默认监听在1099端口。

可以使用Nmap等工具进行端口扫描。

2. 获取RMI注册表信息如果1099端口开放,就可以尝试连接RMI注册表并获取注册的服务信息。

可以使用各种工具或自己编写代码连接注册表并列出绑定的服务。

3. 下载RMI stub文件从注册表获取到绑定服务的stub文件路径后,就可以下载stub文件。

stub文件包含了服务的接口定义和远程引用信息。

4. 反编译stub文件下载的stub文件是Java字节码格式,需要使用反编译工具(如javap)将其反编译为可读的Java源代码。

5. 寻找可利用的gadget反编译后的Java代码中可能包含一些可利用的gadget(小工具),这些gadget可以被链接在一起形成利用链,从而实现任意代码执行。

6. 构造利用链根据找到的gadget,构造出可以执行任意代码的利用链。

利用链通常是一系列特殊构造的Java对象序列。

7. 触发利用链将构造好的利用链通过RMI服务传递给远程服务端,从而在服务端触发任意代码执行。

RIO枚举过程利用了Java RMI和序列化的特性,需要一定的Java安全知识和代码审计能力。

成功的RIO攻击可以在目标服务器上执行任意命令,从而控制整个系统。

因此,及时修补Java组件漏洞并限制不必要的RMI服务是防御RIO攻击的关键。

java下载功能

java下载功能

java下载功能Java是一种跨平台的编程语言,能够在各种操作系统上运行,因此非常适合用于开发具有下载功能的应用程序。

Java提供了丰富的API和库,使开发者能够轻松地实现下载功能。

下面是一些常用的Java下载功能的实现方式:1. 使用URLConnection类来进行下载:URLConnection类是Java提供的用于网络连接的类,可以通过该类来实现下载。

使用URLConnection的步骤包括创建URL对象、打开连接、获取输入流、创建输出流、将数据从输入流写入输出流等。

2. 使用HttpClient库来进行下载:HttpClient是一个功能强大的开源HTTP客户端库,可以用于发送HTTP请求并处理HTTP响应。

通过使用HttpClient库,可以实现更为复杂的下载功能,例如断点续传、多线程下载等。

3. 使用多线程来进行下载:在下载大文件时,为了加快下载速度,可以使用多线程来并行下载。

通过将文件分成多个部分,每个部分由一个线程负责下载,可以同时下载多个部分,提高下载速度。

4. 使用下载管理器来进行下载:下载管理器是一种用于管理下载任务的工具,可以对下载任务进行管理和控制,例如暂停、取消、进度监控等。

Java提供了一些第三方库,如Downpour 和Download4j,可以用于实现下载管理器。

5. 使用流式处理来进行下载:在Java中,可以使用流式处理来处理大文件的下载。

通过使用BufferedInputStream和BufferedOutputStream,可以将下载的文件分块读取并写入本地文件,避免一次性读取整个文件导致内存溢出。

总之,Java提供了多种方式来实现下载功能,开发者可以根据需求选择合适的方法来实现。

通过合理利用Java的API和库,能够实现高效、安全的下载功能,并提供给用户优质的下载体验。

java跨项目调用方法

java跨项目调用方法

java跨项目调用方法Java跨项目调用方法背景在开发多个独立的Java项目时,有时我们会遇到需要在一个项目中调用另一个项目中的方法的情况。

这种情况下,我们就需要跨项目进行方法调用。

本文将介绍几种常用的方法来实现Java跨项目调用。

1. 通过Java RMI实现跨项目调用Java RMI(Remote Method Invocation)提供了一种机制,使得一个Java应用可以调用运行在另一个Java虚拟机上的对象的方法。

通过使用Java RMI,我们可以在不同的项目中建立远程连接,实现方法的调用。

使用Java RMI实现跨项目调用的步骤如下:1.定义接口:在被调用项目中定义接口,并在接口中声明需要暴露给其他项目调用的方法。

2.实现接口:在被调用项目中实现接口,并在实现类中实现接口中声明的方法。

3.启动RMI Registry:运行被调用项目时,需要启动RMIRegistry,用于注册被调用对象。

4.注册对象:在被调用项目中,将实现类注册到RMI Registry中,以供其他项目调用。

5.获取远程对象:在调用项目中,通过RMI Registry获取远程对象的引用。

6.调用方法:通过远程对象的引用,调用被调用项目中的方法。

2. 使用WebService实现跨项目调用WebService是一种基于Web的服务技术,通过使用HTTP协议和XML格式进行通信。

我们可以通过在被调用项目中发布一个WebService,然后在调用项目中通过SOAP协议调用WebService的方式实现跨项目方法的调用。

使用WebService实现跨项目调用的步骤如下:1.定义接口:在被调用项目中定义接口,并在接口中声明需要暴露给其他项目调用的方法。

2.实现接口:在被调用项目中实现接口,并在实现类中实现接口中声明的方法。

3.发布WebService:在被调用项目中通过WebService框架(如Apache CXF、Apache Axis等)发布WebService。

Java中RMI的实现机制

Java中RMI的实现机制
维普资讯
第 1 8卷 第 4期 20 0 un fS z o c to a iest o ra o u h u Vo ain lUnv ri l y
V0 . 8 N . 11 o4 NO .2 o V o7
中图分类号 :T 3 1 文献标识码 :A 文章编号 :10 — 4 5 (0 70 —0 7 0 P1 0 8 5 7 一 2 0 )4 0 5 — 3
Jv MI 实 可 以 被 看 作 是 R C的 Jv aa R 其 P aa版 本。 但是 传统 R C并 不能很 好地 应用 于分 布式对象 P
以下工 作 :1定 位远程对 象 。应 用程 序可使 用两 种 () 机 制 中 的 一 种得 到对 远 程对 象 的 引用 。它 既 可 用
系统。而 Jv M 则支持存储于不 同地址空间的 R 的 简单命 名 工具 r rg t aaR I MI mi ir 注册 它 的远程 对 e sy来 程序级对象之间彼此进行通信 , 实现远程对象之间 象 ,也 可 以将远 程对象 引用作 为常规操 作 的一部 分 的无 缝远 程调用 。R 目前使 用 Jv MI aa远程 消息交换 来进行传递和返回。 2与远程对象通信。 () 远程对象 协 议 J M aa R m t Mesgn rt o) 行 间通信 的细节 由 R I R P Jv e oe s ig Poo 1 进 a c M 处理。( ) 3 给作为参数或返回 通信。R P是专为 Jv 的远程对象制定的协议。 值 传递 的对象 加 载类 字节码 。因为 R 允 许调用 程 JM aa 因 MI 此 ,aaR 具 有 Jv' i n e u nw ee Jv MI aaWr eO c,R n A y h r“ ‘ t 序将纯 Jv 对象传给远程对象 ,所以 ,M 将提供 aa RI 的优 点 , 分 布式应 用 系统 的 百分 之百 纯 Jv 解 决 必要 的机制 ,既可 以加载对 象 的代 码又 可 以传 输对 是 aa 方案 。 Jv MI 用 aaR 开发 的应 用系统 可 以部署在 任何 象 的数 据 。在 R 分布 式应 用程 序运 行 时 , 务器 M1 服 支持 J E Jv u n i n e tJv , 行环境 ) R (aa R n E v o m n a a运 r 的 调用 注 册服务 程序 以使 名字 与远 程对象 相关联 。 客 平 台上 。但 由于 J MP是 专 为 Jv 对 象制 定 的 , R aa 因 户 机在 服务器 上 的注册 服务 程序 中用远 程对象 的名 此 , I 于用 非 Jv 语 言开 发 的应 用 系统 的支 持 字查 找该 远程 对象 , 后调用 它 的方 法 。 RM 对 aa 然 不足 ,不 能与用非 Jv 语 言 书写 的对象 进行 通信 。 aa 在 R 分 布式应 用系 统 中 , 务器 与客户 机之 M1 服 本 文 拟 从 程序 的 角度 举 例介 绍 怎 样 利 用 R 实 现 间传 递 的 Jv 对 象必须 是 可序列化 的对象 。不 可序 MI aa Jv 分布式应 用 。 aa 列化 的对 象不 能在对象 流 中进 行传递 。对 象序列 化 1 R 系统 运行 一般原理 MI 扩展 了核 心 Jv 输入/ 出类 , aa 输 同时也 支持 对象 。对 R 应用 程序通 常包 括两个 独立 的程序 :服务 象序列化支持把对象编码 以及将通过它们可访问到 MI 器程序和客户机程序。典型的服务器应用程序将创 的对象编码变成字节流 ;它也支持流中对象图形 的 建多个远程对象 , 使这些远程对象能够被引用 , 然后 互补重构造。序列化用于轻型持久性和借助于套接 等待客户 机调用 这些远 程对象 的方 法 。而典 型 的客 字或 远 程方法 调用 ( MI进 行 的通信 。为 编写应 用 R ) 户机程序则从服务器中得到一个或多个远程对象的 程序 , 除多数瞬态应用程序外 , 都必须具备存储和检 引用 ,然 后调用 远程对象 的方 法 。R 为服 务器 和 索 Jv 对 象 的能 力 。以序列化 方式 存储 和检索对 象 MI aa 客户机进行通信和信息传递提供了一种机制。 的关 键 在 于提供重新 构造该 对象 所需 的足够 对象 状 利用 R I M 编写分布式对象应用程序需要完成 态。 存储到流的对象可能会支持 Sr lal 可序列 eaz e iib (

java实现调用url来下载pdf并且加水印,追加excel转成pdf

java实现调用url来下载pdf并且加水印,追加excel转成pdf

java实现调⽤url来下载pdf并且加⽔印,追加excel转成pdf ⽔印jar包:excel转pdf的jar包+license破解认证:第⼀种:使⽤spire.pdf.jar包或者导⼊依赖。

<!--filtutil依赖--><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.2</version></dependency><!--pdf依赖--><dependency><groupId>e-iceblue</groupId><artifactId>spire.pdf.free</artifactId><version>2.2.2</version></dependency><repositories><repository><id>com.e-iceblue</id><name>e-iceblue</name><url>/nexus/content/groups/public/</url></repository></repositories>代码:package pdfwatermark.controller;import com.spire.pdf.PdfDocument;import com.spire.pdf.PdfPageBase;import com.spire.pdf.graphics.*;import lombok.extern.slf4j.Slf4j;import mons.io.FileUtils;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.awt.*;import java.awt.geom.Dimension2D;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import .HttpURLConnection;import .URL;import java.time.LocalDate;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;import java.util.Map;@Slf4j@RestController@RequestMapping(value = "/pdf")public class PdfWaterMark {@ResponseBody@RequestMapping(value = "/loadPdf")public void loadPdf(HttpServletRequest request, HttpServletResponse response) throws IOException {String strUrl = "http://ip:port/apiIn/00000.pdf";URL url = new URL(strUrl);HttpURLConnection conn = (HttpURLConnection) url.openConnection();//得到输⼊流InputStream inputStream = conn.getInputStream();String[] urlSplit = strUrl.split("/");int i = urlSplit.length;String[] nextSplit = urlSplit[urlSplit.length - 1].split("\\.");//解析出名字String fileName = nextSplit[0];("fileName:" + nextSplit[0]);("localdateTime:" + LocalDateTime.now() + ",localdate" + LocalDate.now());//来使得唯⼀DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");String str = formatter.format(LocalDateTime.now());for (int m = 1; m < 3; m++) {int rd = (int) (Math.random() * 10);str = str + rd;}//保存路径String filePath = "D://" + nextSplit[0] + "-" + str + ".pdf";java.io.File file = new java.io.File(filePath);FileUtils.copyInputStreamToFile(inputStream, file);//获取当前登陆⽤户// Map<String,Object> map = UserController.findCurrentUser(request,response);// String name = (String)map.get("name");waterMark(filePath, "hlh");}public void waterMark(String inputPdf, String waterMarkName) {//创建PdfDocument类的对象PdfDocument pdf = new PdfDocument();//加载测试⽂档pdf.loadFromFile(inputPdf);//获取⽂档第1页PdfPageBase page = pdf.getPages().get(0);pdf.getPages().getCount();//⽂档总页数,就可以对⽂档中所有页数加⽔印,但Spire.pdf.jar免费10页。

java方法跨系统调用方法

java方法跨系统调用方法

java方法跨系统调用方法Java作为一种广泛应用于企业级应用的编程语言,其跨系统调用方法的使用十分重要。

在企业级应用中,常常需要调用其他系统的功能,比如数据库、消息队列等,而跨系统调用方法可以帮助我们方便地实现这些功能。

本文将介绍Java中跨系统调用方法的实现方式。

一、Java中的跨系统调用方法Java中的跨系统调用方法主要有以下几种:1. 远程方法调用(Remote Method Invocation,简称RMI)RMI是Java中的一种机制,允许在不同的Java虚拟机之间进行远程方法调用。

通过RMI,我们可以在一个Java虚拟机中调用另一个Java虚拟机中的对象的方法,而不需要进行任何网络编程。

RMI 使用Java的序列化机制来传递参数和返回值。

2. Java消息服务(Java Message Service,简称JMS)JMS是一种Java中的消息传递规范,用于在不同的Java应用程序之间传递消息。

JMS可以实现点对点通信和发布/订阅通信模式。

在JMS中,消息被发送到一个消息队列中,然后被接收者从队列中读取。

JMS实现了Java应用程序之间的解耦,使得应用程序可以独立地进行开发和部署。

3. Web服务Web服务是一种跨平台、跨语言的服务,可以通过HTTP协议进行调用。

Web服务通常使用SOAP协议进行通信,SOAP是一种基于XML的协议,用于在网络上交换结构化的和可扩展的信息。

通过Web服务,我们可以方便地实现不同系统之间的互操作性。

4. RESTful服务RESTful服务是一种基于HTTP协议的Web服务,它使用HTTP协议中的GET、POST、PUT、DELETE等方法来实现对资源的操作。

RESTful服务主要使用JSON或XML作为数据格式,具有轻量、灵活、易于扩展等特点。

二、实现跨系统调用方法的步骤实现跨系统调用方法的步骤如下:1. 定义接口在调用其他系统的功能时,需要定义一个接口,该接口定义了需要调用的方法和参数。

JAVA RMI 对计算器编程实现

JAVA RMI 对计算器编程实现

JAVA RMI 对计算器编程实现摘要:本文围绕Java编程语言在网络编程方面的具体应用,论述了面向对象方法,对计算器程序进行需求分析、概要设计、详细设计,最后使用java rmi编程实现了全过程。

Java 作为一种风靡一时的网络开发语言,其巨大的威力就体现在它强大的开发分布式网络应用的能力上,而RMI就是开发百分之百纯Java的网络分布式应用系统的核心解决方案之一。

其实它可以被看作是RPC的Java版本。

但是传统RPC并不能很好地应用于分布式对象系统。

而Java RMI 则支持存储于不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的无缝远程调用。

RMI目前使用Java远程消息交换协议JRMP(Java RemoteMessaging PRotocol)进行通信。

JRMP是专为Java的远程对象制定的协议。

因此,Java RMI 具有Java的"Write Once,Run Anywhere"的优点,是分布式应用系统的百分之百纯Java解决方案。

用Java RMI开发的应用系统可以部署在任何支持JRE(Java Run Environment Java,运行环境)的平台上。

本文拟从程序的角度举例介绍怎样利用RMI实现Java分布式应用。

关键词:JAVA RMI 分布式应用Abstract : This paper focuses on the specific application in the Java programming language network programming , discusses the object-oriented method, the calculator program needs analysis , outline design , detailed design , and finally the use of java rmi programming the entire process. As a rage Java web development language, and its enormous power is reflected in the ability of its powerful development of distributed network applications , while the core 100% pure Java RMI is to develop a network of distributed application system one of the solutions . In fact, it can be seen as RPC Java version. But traditional RPC is not well applied to distributed object systems . The Java RMI supports communication between the stored procedures in different address spaces each object class , seamless remote call remote objects. Currently the use of Java RMI remote message exchange protocol JRMP (Java Remote Messaging PRotocol) communication. JRMP is a protocol designed for Java remote object making. Thus , the advantages of "Write Once, Run Anywhere" The Java RMI with Java , and is 100% pure Java distributed application system solutions. Applications developed using Java RMI systems can be deployed on any platform supported JRE (Java Run Environment Java, Runtime Environment) . This paper , for example from the perspective of how to introduce the use of the program 's implementation of Java RMI distributed applications .Keywords: JAVA RMI Distributed Application1引言随着科学技术的发展,计算机领域也在飞速的发展,人们对于计算器的要求越来越高。

如何编译github java源代码

如何编译github java源代码

编译GitHub上的Java源代码是一项重要的技能,它有助于开发人员理解开源项目的工作原理,并进行定制化开发。

下面,我们将介绍如何使用常见的工具和技术来编译GitHub上的Java源代码。

一、下载源代码1. 在GitHub上搜索并找到你感兴趣的Java开源项目。

2. 点击项目页面上的“Clone or download”按钮,复制项目的Git 仓库URL。

3. 在本地的命令行界面中,使用git clone命令将项目克隆到本地。

二、配置开发环境1. 确保你的开发环境中已经安装了Java Development Kit(JDK),并配置了JAVA_HOME环境变量。

2. 如果项目使用了Maven或Gradle等构建工具,你需要在本地安装相应的工具,并配置好对应的环境变量。

三、使用Maven编译Java源代码1. 打开命令行界面,进入到项目的根目录。

2. 执行mvn clean install命令,Maven将会下载依赖、编译源代码并打包项目。

四、使用Gradle编译Java源代码1. 打开命令行界面,进入到项目的根目录。

2. 执行gradle build命令,Gradle将会下载依赖、编译源代码并打包项目。

五、使用Ant编译Java源代码1. 确保你已经安装了Ant,并配置了ANT_HOME环境变量。

2. 在项目根目录的命令行界面中,执行ant命令,Ant将会根据build.xml文件编译源代码。

六、使用集成开发环境(IDE)编译Java源代码1. 打开你喜欢的IDE,比如IntelliJ IDEA、Eclipse等。

2. 导入项目,IDE将会自动下载依赖并编译源代码。

七、其他注意事项1. 在编译过程中可能会遇到依赖缺失、版本不兼容等问题,需要仔细阅读项目的文档和日志,进行相应的调整。

2. 如果项目包含单元测试,你可能需要在编译之前执行测试,并确保所有测试用例通过。

3. 如果你对源代码进行了修改,可以使用相同的步骤来编译并测试你的修改。

rmi协议

rmi协议

RMI协议RMI(Remote Method Invocation)是Java中的一种远程通信协议。

它允许在不同Java虚拟机(JVM)之间进行方法调用。

RMI协议允许程序员在分布式系统中使用面向对象的编程方式。

RMI协议的概述RMI协议通过Java的序列化机制和远程代理实现了远程方法调用。

它允许在不同的JVM之间传递对象引用,从而调用远程对象的方法。

RMI协议的核心是Java远程对象和远程接口。

Java远程对象Java远程对象是可以在不同的JVM之间传递的对象。

它们必须实现java.rmi.Remote接口,并且其方法必须声明java.rmi.RemoteException异常。

Java远程对象可以通过在服务器上创建对象实例,然后将其绑定到RMI注册表中,从而使客户端可以访问它们。

远程接口远程接口是一组方法的集合,这些方法可以通过RMI协议在不同的JVM之间进行调用。

远程接口必须扩展java.rmi.Remote接口,并且其方法也必须声明java.rmi.RemoteException异常。

远程接口定义了客户端可以调用的方法列表。

RMI的工作原理RMI协议的工作原理可以分为以下几个步骤:1.服务器端创建并导出远程对象:服务器程序创建远程对象,并通过RMI框架将其导出为远程对象。

服务器上的RMI注册表负责管理导出的远程对象。

2.客户端查找远程对象:客户端程序通过RMI注册表查找服务器端导出的远程对象。

RMI注册表返回一个远程对象的引用。

3.客户端通过远程对象调用方法:客户端使用远程对象引用来调用远程对象的方法。

RMI框架处理方法调用,并通过网络将方法调用请求发送给服务器端。

4.服务器端执行方法:服务器端接收到客户端的方法调用请求,并执行相应的方法。

服务器端的方法执行结果通过网络返回给客户端。

5.客户端接收方法执行结果:客户端接收到服务器端返回的方法执行结果,并继续执行后续的操作。

RMI协议的优势RMI协议具有以下优势:1.简化分布式编程:RMI协议使得分布式系统中的方法调用变得简单,程序员可以像调用本地方法一样调用远程方法。

java内调用远程接口的方法

java内调用远程接口的方法

java内调用远程接口的方法Java内调用远程接口的方法主要有两种方式:使用Java RMI(远程方法调用)和使用Web服务。

1. 使用Java RMI:- 在远程接口所在的项目中定义接口和实现类,并继承java.rmi.Remote接口。

- 将接口和实现类编译打包成JAR文件,并将JAR文件发布到远程服务器上。

- 在调用方项目中,使用java.rmi.Naming类的lookup()方法获取远程接口的实例。

- 通过远程接口实例调用接口中定义的方法。

示例代码:```java// 远程接口定义public interface RemoteService extends java.rmi.Remote {public String sayHello() throws java.rmi.RemoteException;}// 远程接口实现类public class RemoteServiceImpl extends java.rmi.server.UnicastRemoteObject implementsRemoteService {public RemoteServiceImpl() throws java.rmi.RemoteException {super();}public String sayHello() throws java.rmi.RemoteException {return "Hello, World!";}}// 调用方代码public class Client {public static void main(String[] args) {try {// 获取远程接口实例RemoteService remoteService = (RemoteService) java.rmi.Naming.lookup("rmi://localhost/RemoteService");// 调用远程接口方法String result = remoteService.sayHello();System.out.println(result);} catch (Exception e) {e.printStackTrace();}}}```2. 使用Web服务:- 在远程接口所在的项目中定义接口和实现类,并使用@WebService注解标记接口和实现类。

java实现文件下载.

java实现文件下载.

在BlogJava上已经有一位作者阐述了文件上传的问题, 地址是在Struts 2中实现文件上传 , 因此我就不再讨论那个话题了。

我今天简单介绍一下Struts 2的文件下载问题。

我们的项目名为 struts2hello ,所使用的开发环境是MyEclipse 6,当然其实用哪个 IDE 都 是一样的,只要把类库放进去就行了,文件下载不需要再加入任何额外的包。

读者可以参考 文档:http://beansoft.java­/myeclipse_doc_cn/struts2_demo.pdf ,来了解怎么下载 和配置基本的 Struts 2开发环境。

为了便于大家对比,我把完整的 struts.xml 的配置信息列出来:Xml代码1 <?xml version="1.0" encoding="UTF-8" ?>2 <!DOCTYPE struts PUBLIC3 "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"4 "/dtds/struts-2.0.dtd">56 <struts>7 <package name="default" extends="struts-default" >8 <!-- 在这里添加 Action 定义 -->910 <!-- 简单文件下载 -->11 <action name="download" class="example.FileDownloadAction">12 <result name="success" type="stream">13 <param name="contentType">text/plain</param>14 <param name="inputName">inputStream</param>15 <paramname="contentDisposition">attachment;filename="struts2中文.txt"</param>16 <param name="bufferSize">4096</param>17 </result>18 </action>1920 <!-- 文件下载,支持中文附件名 -->21 <action name="download2" class="example.FileDownloadAction2">22 <!-- 初始文件名 -->23 <param name="fileName">Struts 中文附件.txt</param>24 <result name="success" type="stream">25 <param name="contentType">text/plain</param>26 <param name="inputName">inputStream</param>27 <!-- 使用经过转码的文件名作为下载文件名, downloadFileName属性28 对应 action类中的方法 getDownloadFileName() -->29 <paramname="contentDisposition">attachment;filename="${downloadFileName}"</param>30 <param name="bufferSize">4096</param>31 </result>32 </action>3334 <!-- 下载现有文件 -->35 <action name="download3" class="example.FileDownloadAction3">36 <param name="inputPath">/download/系统说明.doc</param>37 <!-- 初始文件名 -->38 <param name="fileName">系统说明.doc</param>39 <result name="success" type="stream">40 <paramname="contentType">application/octet-stream;charset=ISO8859-1</param>41 <param name="inputName">inputStream</param>42 <!-- 使用经过转码的文件名作为下载文件名, downloadFileName属性43 对应 action类中的方法 getDownloadFileName() -->44 <paramname="contentDisposition">attachment;filename="${downloadFileName}"</param>45 <param name="bufferSize">4096</param>46 </result>47 </action>4849 </package>5051 </struts>Xml代码52 <?xml version="1.0" encoding="UTF-8" ?>53 <!DOCTYPE struts PUBLIC54 "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"55 "/dtds/struts-2.0.dtd">5657 <struts>58 <package name="default" extends="struts-default" >59 <!-- 在这里添加 Action 定义 -->6061 <!-- 简单文件下载 -->62 <action name="download" class="example.FileDownloadAction">63 <result name="success" type="stream">64 <param name="<SPAN class=hilite3><SPANstyle="BACKGROUND-COLOR:#aaffaa">contentType</SPAN></SPAN>">text/plain</param>65 <param name="inputName">inputStream</param>66 <paramname="contentDisposition">attachment;filename="<SPAN class=hilite1><SPANstyle="BACKGROUND-COLOR: #ffff00">struts2</SPAN></SPAN>中文.txt"</param>67 <param name="bufferSize">4096</param>68 </result>69 </action>7071 <!-- 文件下载,支持中文附件名 -->72 <action name="download2" class="example.FileDownloadAction2">73 <!-- 初始文件名 -->74 <param name="fileName">Struts 中文附件.txt</param>75 <result name="success" type="stream">76 <param name="<SPAN class=hilite3><SPANstyle="BACKGROUND-COLOR:#aaffaa">contentType</SPAN></SPAN>">text/plain</param>77 <param name="inputName">inputStream</param>78 <!-- 使用经过转码的文件名作为下载文件名, downloadFileName 属性79 对应 action类中的方法 getDownloadFileName() -->80 <paramname="contentDisposition">attachment;filename="${downloadFileName}"</param>81 <param name="bufferSize">4096</param>82 </result>83 </action>8485 <!-- 下载现有文件 -->86 <action name="download3" class="example.FileDownloadAction3">87 <param name="inputPath">/download/系统说明.<SPANclass=hilite5>doc</SPAN></param>88 <!-- 初始文件名 -->89 <param name="fileName">系统说明.<SPANclass=hilite5>doc</SPAN></param>90 <result name="success" type="stream">91 <param name="<SPAN class=hilite3><SPANstyle="BACKGROUND-COLOR:#aaffaa">contentType</SPAN></SPAN>">application/octet-stream;charset=ISO885 9-1</param>92 <param name="inputName">inputStream</param>93 <!-- 使用经过转码的文件名作为下载文件名, downloadFileName 属性94 对应 action类中的方法 getDownloadFileName() -->95 <paramname="contentDisposition">attachment;filename="${downloadFileName}"</param>96 <param name="bufferSize">4096</param>97 </result>98 </action>99100 </package>101102</struts>Struts 2中对文件下载做了直接的支持,相比起自己辛辛苦苦的设置种种HTTP 头来说,现 在实现文件下载无疑要简便的多。

RMI原理及实现

RMI原理及实现
象,它就象服务器上的对象的代理,向客户端提供能够被服务器调用的方法。然后,Stub 就会向服务器端的 Skeleton 发送方法调用,Skeleton 就会在服务器端执行接收到的方法。
Stub 和 Skeleton 之间通过远程调用层进行相互通讯,远程调用层遵循 TCP/IP 协议收发 数据。下面我们来大致了解一种称为为“绑定”的技术。
?远程客户端:这是一个帮助我们访问远程方法提供帮助的类,它也是最终用户。 我们将使用查找和调用远程方法的方法在该类中调用远程方法。
编程 我们将首先编写远程对象,并将代码保存为名字为 AddServer.Java 的文件: import Java.rmi.*; public interface AddServer extends Remote { public int AddNumbers(int firstnumber,int secondnumber) throws RemoteException; } 我们来看看上面的代码。首先,为了使用其内容,我们导入 rmi 包。然后,我们创
C:\jdk\bin\Javac workingdir\RmiClient.Java 在对我们的代码进行测试前,还必须首先启动 RMI Registry。RMI Registry 存储有 所有绑定的数据,没有它,RMI 就不能正常地运行! 启动 Rmi Registry 服务器: C:\jdk\bin\start rmiregistry 我们会注意到,这时会出现一个空白的 DOS 提示符窗口,这表明 Rmi Registry 服 务器在运行,注意不要关闭该窗口。然后,我们首先在一个 DOS 提示符窗口中运行 Rmi 服 务器,然后在另一个 DOS 提示符窗口中运行 Rmi 客户端。 启动 RMI 服务器:

用Java语言实现文件的下载

用Java语言实现文件的下载

用Java语言实现文件的下载
李玲;李宇丽
【期刊名称】《长春光学精密机械学院学报》
【年(卷),期】1998(021)002
【摘要】介绍了Java网络通信方面的内容。

在基于HTTP、FTP协议的前提下,运用Java丰富的类库,完成了文件的下载,并对网络安全性做了初步的探讨。

【总页数】5页(P66-70)
【作者】李玲;李宇丽
【作者单位】长春邮电学院计算机工程系;长春邮电学院计算机工程系
【正文语种】中文
【中图分类】TP393
【相关文献】
1.一种能实现文件权限控制的文件上传下载系统 [J], 秦高德
2.浅谈在JSP中实现文件下载以及统计下载次数 [J], 孙青格乐
3.用Java语言在机顶盒实现符合MHP规范的文件和目录对象的接收 [J], 鞠啸东;郑世宝
4.利用java语言实现文件上传功能 [J], 王文龙;王武魁
5.用JAVA语言实现GIF图像文件的编码 [J], 贝雨馨;徐晓霞
因版权原因,仅展示原文概要,查看原文内容请购买。

Java实现HTTP文件下载

Java实现HTTP文件下载

Java实现HTTP文件下载序言许多用户可能会遇到这样的情况:在网站上发现一个很好的资源,但是这个资源是分成了很多个文件存放的,如果想把它保存到本地,只有靠用户点击另存来完成保存,如果资源分了几百甚至上千上万,那简直是个灾难。

在Internet上很多的资源分成多个文件存放时,它的文件命名是有一定的规则的;正因如此,我们就可以用程序来完成这个资源的完全下载。

1. 基础知识在Internet上,我们要下载网站上的某个资源,我们会获得一个URL(Uniform Resource Locator),它是一个服务器资源定位的描述,下载的过程总是如下步骤:步骤1:客户端发起连接请求一个URL步骤2:服务器解析URL,并将指定的资源返回一个输入流给客户步骤3:客户端接收输入流,将流中的内容存到文件2. 网络连接的建立Java提供了对URL访问和大量的流操作的的API,我们可以很容易的完成对网络上资源的存取,下面的代码段就完成了对一个网站的资源进行访问:3. 代理的访问Java 中通过代理服务器访问外网的方法已经是世人皆知的秘密了。

这里就不再多描述了,访问的JAVA代码如下:4. 网络资源的保存在上节中,我们已经获取了指定网络资源的输入流,接下来我们要完成的就是读取输入流中的所以内容,并将其保存在文件中。

示例代码:上面的示例代码就将网络资源的内容保存到了本地指定的文件中。

5. 代码清单import java.io.*;import .*;import java.util.*;/*** <p>Description: 将指定的HTTP网络资源在本地以文件形式存放</p>**/public class SaveFile {public final static boolean DEBUG = true; //调试用private static int BUFFER_SIZE = 8096; //缓冲区大小private Vector vDownLoad = new Vector(); //URL列表private Vector vFileList = new Vector(); //下载后的保存文件名列表/*** 构造方法*/public SaveFile() {}/*** 清除下载列表*/public void resetList() {vDownLoad.clear();vFileList.clear();}/*** 增加下载列表项** @param url String* @param filename String*/public void addItem(String url, String filename) { vDownLoad.add(url);vFileList.add(filename);}/*** 根据列表下载资源*/public void downLoadByList() {String url = null;String filename = null;//按列表顺序保存资源for (int i = 0; i < vDownLoad.size(); i++) {url = (String) vDownLoad.get(i);filename = (String) vFileList.get(i);try {saveToFile(url, filename);} catch (IOException err) {if (DEBUG) {System.out.println("资源[" + url + "]下载失败"); }}}if (DEBUG) {System.out.println("下载完成");}}/*** 将HTTP资源另存为文件** @param destUrl String* @param fileName String* @throws Exception*/public void saveToFile(String destUrl, String fileName) throws IOException {FileOutputStream fos = null;BufferedInputStream bis = null;HttpURLConnection httpUrl = null;URL url = null;byte[] buf = new byte[BUFFER_SIZE];int size = 0;//建立链接url = new URL(destUrl);httpUrl = (HttpURLConnection) url.openConnection();//连接指定的资源httpUrl.connect();//获取网络输入流bis = new BufferedInputStream(httpUrl.getInputStream());//建立文件fos = new FileOutputStream(fileName);if (this.DEBUG)System.out.println("正在获取链接[" + destUrl + "]的内容...\n将其保存为文件[" +fileName + "]");//保存文件while ((size = bis.read(buf)) != -1)fos.write(buf, 0, size);fos.close();bis.close();httpUrl.disconnect();}/*** 将HTTP资源另存为文件** @param destUrl String* @param fileName String* @throws Exception*/public void saveToFile2(String destUrl, String fileName) throws IOException {FileOutputStream fos = null;BufferedInputStream bis = null;HttpURLConnection httpUrl = null;URL url = null;byte[] buf = new byte[BUFFER_SIZE];int size = 0;//建立链接url = new URL(destUrl);httpUrl = (HttpURLConnection) url.openConnection();// String authString = "username" + ":" + "password";String authString = "50301" + ":" + "88888888";String auth = "Basic " +newsun.misc.BASE64Encoder().encode(authString.getBytes());httpUrl.setRequestProperty("Proxy-Authorization", auth);//连接指定的资源httpUrl.connect();//获取网络输入流bis = new BufferedInputStream(httpUrl.getInputStream());//建立文件fos = new FileOutputStream(fileName);if (this.DEBUG)System.out.println("正在获取链接[" + destUrl + "]的内容...\n将其保存为文件[" +fileName + "]");//保存文件while ((size = bis.read(buf)) != -1)fos.write(buf, 0, size);fos.close();bis.close();httpUrl.disconnect();}/*** 设置代理服务器** @param proxy String* @param proxyPort String*/public void setProxyServer(String proxy, String proxyPort) {//设置代理服务器System.getProperties().put("proxySet", "true");System.getProperties().put("proxyHost", proxy);System.getProperties().put("proxyPort", proxyPort);}public void setAuthenticator(String uid, String pwd) {Authenticator.setDefault(new MyAuthenticator());}/*** 主方法(用于测试)** @param argv String[]*/public static void main(String argv[]) {HttpGet oInstance = new HttpGet();try {// //增加下载列表(此处用户可以写入自己代码来增加下载列表)// oInstance.addItem("/java/网络编程001.zip","./网络编程1.zip");//// oInstance.addItem("/java/网络编程002.zip","./网络编程2.zip");// oInstance.addItem("/java/网络编程003.zip","./网络编程3.zip");// //开始下载// oInstance.downLoadByList();oInstance.saveToFile("/java/网络编程001.zip", "./down.zip");}catch (Exception err) {System.out.println(err.getMessage());}}}。

下载功能实现

下载功能实现

下载功能实现下载功能是指用户通过互联网将某种文件或资源保存到本地设备中的操作。

实现下载功能一般需要以下几个步骤:确定下载链接、创建下载请求、接收和保存文件。

首先,要实现下载功能,需要确定下载链接。

下载链接是文件或资源在服务器上的地址,通过该链接可以访问到文件或资源。

一般情况下,下载链接是通过点击下载按钮或从其他网页上获取的。

用户需要将下载链接输入到程序中,以便程序可以发送下载请求,并将文件或资源保存到本地设备中。

接下来,需要创建下载请求。

下载请求是通过发送HTTP请求到服务器来获取文件或资源的过程。

一般来说,下载请求使用GET方法,并将下载链接作为请求的URL。

如果需要用户身份验证,还需要在请求中包含相应的身份验证信息。

通过发送下载请求,服务器将返回文件或资源的数据。

最后,需要接收和保存文件。

一旦下载请求被服务器接收并处理,服务器将开始发送文件或资源的数据。

程序需要接收服务器发送的数据,并将其保存到本地设备中的指定位置。

保存文件的方式可以是将数据写入到硬盘中的指定文件,或将数据保存到内存中的缓冲区。

保存文件时,还需要考虑文件命名、文件格式和文件存储路径等问题。

在实现下载功能时,还需要考虑以下几个方面。

首先是下载速度的问题。

下载速度取决于用户的网络连接质量、服务器的带宽和文件或资源的大小等因素。

为了提高下载速度,可以采用分块下载、多线程下载或断点续传等技术。

其次是下载进度的显示。

可以通过在用户界面上显示当前下载进度、已下载的文件大小和剩余时间等信息,来让用户了解下载的进展情况。

另外,还要考虑断点续传功能。

如果下载过程中发生了连接中断或程序异常结束等情况,可以通过保存已下载部分的文件信息,让用户可以继续下载未完成的部分。

总之,实现下载功能需要确定下载链接、创建下载请求以及接收和保存文件。

通过合理的下载策略,可以提高下载速度和用户体验。

在实现过程中,还需要考虑下载进度的显示和断点续传功能等问题,以提高程序的健壮性和用户满意度。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Java RMI 实现代码动态下载育龙网 WWW.CHINA-B.C0M 2009年06月11日来源:互联网育龙网核心提示:摘要:本译文将向你介绍JavaTMRMI动态类文件下载的应用,学习完本文,你将会对JavaTMRMI有进一步的认识。

希望你能参考我的上一篇译摘要:本译文将向你介绍JavaTMRMI动态类文件下载的应用,学习完本文,你将会对JavaTMRMI有进一步的认识。

希望你能参考我的上一篇译文:开始学习Java RMI,远程方法调用-基础篇。

1.概要Java平台一个重要的优点就是可以动态的从一个给定的URL下载Java软件到一个正在运行JVM的独立进程中,该进程通常位于一个不同物理系统中。

这样可以让一个远程系统运行一个程序,例如一个Applet,它从来没有被安装到本地的存储介质上。

在该文档的前几部分,我们先讨论Applet的codebase,以帮助我们更好的介绍有关Java RMI的codebase.举例来说,一个运行在浏览器中的虚拟机,可以把java.applet.Applet的子类和其相关类的字节码下载下来(到本地)。

运行该浏览器的系统以前从没有运行过该Applet,也没有在本地安装。

一旦所有的类从服务端下载完成,浏览器借助本地资源就开始运行这个Applet程序。

Java RMI正是采用了这个优点,下载、运行这些从来没有在本地安装过的类。

调用Java RMI的API的虚拟机,不仅仅像那些浏览器中,能够下载任意Java类文件,其中含有那些特定Java RMI存根类,它使借助服务器资源的远程调用的执行成为可能。

Codebase观点源于Java程序语言的ClassLoaders的应用。

当一个Java程序使用一个ClassLoader时,那么它需要知道它被允许到那里调用类。

通常,一个类调用者和HTTP Server 一起使用,Server为Java平台应用提供编译过的类。

很可能,你提到第一对有关ClassLoader/codebase就是AppletClassLoader和作为HTML标签<applet的“codebase”属性。

本文档假设你有些Java RMI编程经验,同时写过一些含有applet标签的HTML文件。

例如,在HTML源文件中(applet标签)将含有一些类似下面的代码:<applet height=100 width=100 codebase="myclasses/" code="My.class" <param name="ticker" </applet2.什么是codebase类代码址可以为一个源文件,或是一个目录,虚拟机可以由此加载类。

举个例子来说,如果你邀请一个朋友到家吃晚饭,你需要告诉你朋友你的居住方向,以便你的朋友能够确定你家的位置。

同样,你可以把代码库址(Codebase)看作一个你指给JVM的方向,让JVM能够找到1. 远程对象代码库址(codebase)是通过在远程对象服务端设定java.rmi.server.codebase 属性指定的。

在Java RMI 注册表的帮助下,Java RMI 服务端注册了一个远程对象,并绑定了一个名字。

服务端JVM中代码库址(codebase)设定给在Java RMI注册表中的远程对象引用提供了注解。

2. Java RMI客户端请求一个(已知)命名的远程对象的引用。

客户端使用该引用(远程对象的存根实例)进行对远程对象的方法调用。

3. Java RMI注册表向请求的类返回一个引用(存根实例)。

客户端会优先于codebase在本地的classpath中寻找存根类,如果发现了,那么它就会在本地调用该类。

然而,如果在本地的classpath找不到该stub的存根类,客户端就会试着从远程对象代码库址(codebase)中检索该类。

4. 客户端从代码库址(codebase)请求类。

客户端使用的代码库址(codebase)就是存根实例注解的URL,它是在存根类被注册表加载时注解的。

回到第一步1,为导出对象的存根做注解,然后随着绑定的名字被注册到注册表中。

5. 定义的存根类(和其需要的其他类)被下载到客户端。

注意:第4和5是相同的步骤,当远程对象被一个名字绑定到注册表中时,注册表就开始调用该远程对象类。

当注册表试着调用远程对象的存根类时,从代码库址(codebase)中,它和远程对象一起请求该类的定义。

6. 现在客户端已经具备了调用远程对象方法的所有条件。

存根(在这过程中)像一个服务端的远程对象的代理一样;不像applet使用代码库址(codebase)运行代码在本地的虚拟机中,Java RMI 客户端使用远程的代码库址(codebase)运行代码在另一个,可能是远程JVM 中。

如图三所示:图三:Java RMI 客户端远程方法调用4.在Java RMI中利用codebase属性,实现非存根(sub)类的下载除了下载存根类(stub)和其辅助类到客户端,java.rmi.server.codebase属性还被用来指定其他的,不仅仅是stub类的下载地址。

当客户端调用远程对象的方法时,该方法可能无参或是有许多的参数,根据方法参数类型,这样就可能有三种不同情况发生。

第一种情况,所有的(远程)方法参数(或是返回值)都是原始的数据类型,这样远程对象知道如何的解释他们作为方法的参数,同时也无需检查classpath和codebase属性。

第二种情况,至少有一个参数或是返回值是一个对象,然而远程对象可以在本地的classpath中可以找到该对象类的定义。

第三种情况(如图四,第六步所示),远程方法收到一个对象参数,然而远程对象在本地的classpath中没有找到对象的定义。

这种远程方法的调用情况如图四所示。

客户端发送的对象类可能是(远程方法)参数类的子类型,它可能是两者其中之一:一个接口的实现,该接口为方法的参数(或是返回值)类型一个类的子类,该类为方法的参数(或是返回值)类型图四:Java RMI客户端远程方法调用,传递一个未知的参数类型的子类型类似applet的代码库址(codebase),客户端设定的代码库址(codebase),用于其他JVM下载远程类,非远程类和接口地址。

如果在客户端的应用中设定了代码库址(codebase)属性,那么客户端在调用子类型时,代码库址(codebase)就被作为参数加到子类型的实例上。

如果在客户端没有设定代码库址(codebase),那么远程对象就会错误的使用自己的代码库址(codebase)。

5.命令行例子在applet情况下,代码库址(codebase)是嵌在网页中的,就如我们在本文的第一部分看到的HTML例子。

在Java RMI应用时,codebase不是依靠一个镶嵌在网页中类的引用实现的,客户端会和Java RMI的注册表沟通获得远程对象的应用。

由于远程对象的代码库址(codebase)可以指向任意URL,不能仅是一个相对于已知的URL地址,必须是存根类(stub)和其相关类目录的绝对地址。

代码库址(codebase)可以指向:一个目录地址,该目录中含有类包子目录一个Jar文件路径,含有类包的目录压缩文件满足以上条件的多个目录或是多个Jar文件,中间用空格间隔注意:如果代码库址(codebase)设定为一目录地址,那么结尾一定要是“/”。

例子:如果你把要下载类在“webvector”HTTP服务器的export目录下(在Web根目录下),那么的你的代码库址(codebase)就该这样设置:-Djava.rmi.server.codebase=http://webvector/export/如果你把要下载类放在“webline”HTTP服务器的public目录下(在Web根目录下),一个名字为“mystuff.jar”的Jar文件,你的代码库址(codebase)就该如此设置:-Djava.rmi.server.codebase=http://webline/public/mystuff.jar现在我们假设你把要下载的类分为两个文件“myStuff.jar”和“myOtherStuff.jar”,而且这两个文件放在不同的服务器上(名字是:“webfront”和“webwave”),你的代码库址(codebase)属性就该这样设定:-Djava.rmi.server.codebase="http://webfront/myStuff.jar http://webwave/myOtherStuff.jar"6.疑难问题解答如果你的Java RMI 程序配置正确,任何一个可以序列化的类,包含Java RMI 存根类,都是可以被下载下来的。

动态的存根(stub)能够正常的下载,需要满足几种状况:A. 通过URL提供的存根类和存根类依赖的任何类能够被客户端可达。

B. 在服务程序中通过调用bind或是rebind设定(或是在程序安装的过程中激活)(译注:rebind(String url, Remote obj)或是bind(String url, Remote obj)),如下情况:如步骤A中设定的URL同时如果设定的为一个目录,那么必须是“/”结尾。

C. rmiregistry在它相关的classpath中找不到存根类或是其依赖的其他类。

这也是为什么我们在注册表调用存根时,给它加上代码库址(codebase)的参数的原因了,在服务端或是安装代码中,作为一个调用的结果。

D. 客户端安装的SecurityManager允许存根(stub)下载。

在Java 2 SE或是高版本中,这将意味着客户端必须在策略文件中进行合适的配置。

在使用Java RMI的java.rmi.server.codebase系统变量时,有两种经常性的问题,我们将在下边讨论。

6.1 运行Java RMI服务端可能碰到的问题你碰到的第一个问题可能是收到ClassNotFoundException的异常,当你向注册表绑定(bind或是rebind)一个远程对象和名字时。

这种异常通常是由不合法的codebase属性引起的,导致了在注册表中不能定位远程对象的存根(stub)或是存根需要的其他类。

同远程对象本身相比,远程对象的存根(stub)实现了所有同样的接口,这需要特别的注意。

因此这些接口,同其他定制的类作为方法参数或是返回值,也必须能够通过指定的代码库址(codebase)下载。

通常,由于忽略了属性设定时URL中末尾“/”,导致这个异常的抛出。

其他的一些原因可能是:属性值不是一个URL;URL路径拼写错误或是不正确;设定的URL中存根类(stub)和其相关的类不存在。

相关文档
最新文档