最近项目中要求实现远程文件下载, 原先如果被下载文件放在项目应用的 web 路径下那可以通过很多经典的方式去实现,但现在被下载的文件和项目应用不在同一台服务器上, 原来的方式无法实现,因为被下载文件的路径都是以 // ip地址 / 目录1/目录1/ *.* 来表示的, 网上参考了一下, 好象可以用 java RMI 实现 , 所以写了一个Demo, 客户端和服务端都放在本机(winXP系统) (源码见附件 服务端:server.rar 客户端:client.rar)1.远程接口
FileInterface.java代码如下:
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface FileInterface extends Remote {
public byte[] downloadFile(String fileName) throws
RemoteException;
}
2.实现远程的接口
import java.io.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class FileImpl extends UnicastRemoteObject
implements FileInterface {
private String name;
public FileImpl(String s) throws RemoteException{
super();
name = s;
}
public byte[] downloadFile(String fileName){
try {
File file = new File(fileName);
byte buffer[] = new byte[(int)file.length()];
BufferedInputStream input = new
BufferedInputStream(new FileInputStream(fileName));
input.read(buffer,0,buffer.length);
input.close();
return(buffer);
} catch(Exception e){
System.out.println("FileImpl: "+e.getMessage());
e.printStackTrace();
return(null);
}}} 3.编写服务端
(1)创建并安装一个RMISecurityManager实例。
(2)创建一个远程对象的实例。
(3)使用RMI注册工具来注册这个对象。
FileServer.java 代码如下:
import java.io.*;
import java.rmi.*;
public class FileServer {
public static void main(String argv[]) {
if(System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
FileInterface fi = new FileImpl("FileServer");
Naming.rebind("//127.0.0.1/FileServer", fi);
} catch(Exception e) {
System.out.println("FileServer: "+e.getMessage());
e.printStackTrace();
}}} 4.编写客户端
import java.io.*;
import java.rmi.*;
public class FileClient{
public static void main(String argv[]) {
if(argv.length != 2) {
System.out.println("Usage: java FileClient fileName machineName");
System.exit(0);
}
try {
String name = "//" + argv[1] + "/FileServer";
FileInterface fi = (FileInterface) Naming.lookup(name);
byte[] filedata = fi.downloadFile(argv[0]);
File file = new File(argv[0]);
BufferedOutputStream output = new
BufferedOutputStream(new FileOutputStream(file.getName()));
output.write(filedata,0,filedata.length);
output.flush();
output.close();
} catch(Exception e) {
System.err.println("FileServer exception: "+ e.getMessage());
e.printStackTrace();
}}}
demo步骤:1. 使用rmiregistry或者start rmiregistry 命令来运行RMI注册工具到window系统默认的端口上:
prompt > rmiregistry (此处没写端口,默认使用1099)2. 运行服务FileServer
prompt > java -Djava.security.policy=policy.txt FileServer
此时不知道为什么老是报拒绝连接的错误,请各位大侠指正,不胜感激FileServer: Connection refused to host: 127.0.0.1; nested exception is:
java.net.ConnectException: Connection refused: connect
java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is:
java.net.ConnectException: Connection refused: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185 )
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at java.rmi.Naming.rebind(Naming.java:160)
at FileServer.main(FileServer.java:11)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:516)
at java.net.Socket.connect(Socket.java:466)
at java.net.Socket.<init>(Socket.java:366)
at java.net.Socket.<init>(Socket.java:179)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirect SocketFactory.java:22)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMaster SocketFactory.java:128)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:569) ... 6 moremail: [email protected]
FileInterface.java代码如下:
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface FileInterface extends Remote {
public byte[] downloadFile(String fileName) throws
RemoteException;
}
2.实现远程的接口
import java.io.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class FileImpl extends UnicastRemoteObject
implements FileInterface {
private String name;
public FileImpl(String s) throws RemoteException{
super();
name = s;
}
public byte[] downloadFile(String fileName){
try {
File file = new File(fileName);
byte buffer[] = new byte[(int)file.length()];
BufferedInputStream input = new
BufferedInputStream(new FileInputStream(fileName));
input.read(buffer,0,buffer.length);
input.close();
return(buffer);
} catch(Exception e){
System.out.println("FileImpl: "+e.getMessage());
e.printStackTrace();
return(null);
}}} 3.编写服务端
(1)创建并安装一个RMISecurityManager实例。
(2)创建一个远程对象的实例。
(3)使用RMI注册工具来注册这个对象。
FileServer.java 代码如下:
import java.io.*;
import java.rmi.*;
public class FileServer {
public static void main(String argv[]) {
if(System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
FileInterface fi = new FileImpl("FileServer");
Naming.rebind("//127.0.0.1/FileServer", fi);
} catch(Exception e) {
System.out.println("FileServer: "+e.getMessage());
e.printStackTrace();
}}} 4.编写客户端
import java.io.*;
import java.rmi.*;
public class FileClient{
public static void main(String argv[]) {
if(argv.length != 2) {
System.out.println("Usage: java FileClient fileName machineName");
System.exit(0);
}
try {
String name = "//" + argv[1] + "/FileServer";
FileInterface fi = (FileInterface) Naming.lookup(name);
byte[] filedata = fi.downloadFile(argv[0]);
File file = new File(argv[0]);
BufferedOutputStream output = new
BufferedOutputStream(new FileOutputStream(file.getName()));
output.write(filedata,0,filedata.length);
output.flush();
output.close();
} catch(Exception e) {
System.err.println("FileServer exception: "+ e.getMessage());
e.printStackTrace();
}}}
demo步骤:1. 使用rmiregistry或者start rmiregistry 命令来运行RMI注册工具到window系统默认的端口上:
prompt > rmiregistry (此处没写端口,默认使用1099)2. 运行服务FileServer
prompt > java -Djava.security.policy=policy.txt FileServer
此时不知道为什么老是报拒绝连接的错误,请各位大侠指正,不胜感激FileServer: Connection refused to host: 127.0.0.1; nested exception is:
java.net.ConnectException: Connection refused: connect
java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is:
java.net.ConnectException: Connection refused: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185 )
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at java.rmi.Naming.rebind(Naming.java:160)
at FileServer.main(FileServer.java:11)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:516)
at java.net.Socket.connect(Socket.java:466)
at java.net.Socket.<init>(Socket.java:366)
at java.net.Socket.<init>(Socket.java:179)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirect SocketFactory.java:22)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMaster SocketFactory.java:128)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:569) ... 6 moremail: [email protected]
解决方案 »
- 用Java怎么实现在线文本阅读器功能,譬如豆瓣、百度文库里的
- 问一个SSH的问题,
- sql 语句
- Myeclipse快捷键
- MyEclipse 7.0 如何优化,因启动速度太慢!
- 在weblogic上部署soap,出现BEA-101216的原因是什么?
- 合肥的程序员请进。。。。大家来个薪水调查吧
- 我想在jbuilder9.0中使用JDOM,搞了半天,就不知道怎么设置,希望好心人告知.
- 在学习j2ee的过程中,要求对javaAPI非常了解。问:怎么样才能学好并精通javaAPI?
- ejb怎么打包并DEPLOY到WEBLOGIC6上?
- weblogic 9.2 在windows 2003 server下是否可以安装?
- 什么是上下文?
郁闷得很!
都是说改java安全策略文件,我照着一些例子加了 还是不行
我用的java版本为1.6,用的策略文件是jre/lib/security/下的java.security
permission java.security.AllPermission "","";
};
还要注意:
1.客户端、服务器所使用java虚拟机的版本要一致,检查环境变量中的path,特别是在装了Oracle之后会自动设java虚拟机路径2.RMI注册机要在class所在目录启动,或者直接在服务器代码中编写:
LocateRegistry.createRegistry(1099);