最近项目中要求实现远程文件下载,  原先如果被下载文件放在项目应用的 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] 

解决方案 »

  1.   

    我也出现了这个错误。
    郁闷得很!
    都是说改java安全策略文件,我照着一些例子加了 还是不行 
    我用的java版本为1.6,用的策略文件是jre/lib/security/下的java.security
      

  2.   

    java在传输对象的时候好像需要将对象序列化,也就是继承java.io.Serializable 这个接口才能对象序列化,你看加上他行不行。呵呵呵
      

  3.   

    运行的时候加一个   -Djava.rmi.server.hostname=127.0.0.1   试试
      

  4.   

    安全策略文件的内容应该是:grant {  
        permission java.security.AllPermission "","";
    };
    还要注意:
    1.客户端、服务器所使用java虚拟机的版本要一致,检查环境变量中的path,特别是在装了Oracle之后会自动设java虚拟机路径2.RMI注册机要在class所在目录启动,或者直接在服务器代码中编写:
    LocateRegistry.createRegistry(1099);