2011-01-09 227 views
3

我想写一个servlet,它可以从客户端上传文件到服务器,并从服务器上下载文件到客户端从特定位置到特定位置。但是有两个问题阻止了我: 1.当从客户端上传文件到服务器时,如何告诉服务器在哪里存储文件? 2.(更重要的是)如何从服务器下载到客户端部分?使用servlet从服务器到客户端的一个文件

这是迄今为止代码:

import java.io.FileOutputStream; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 

public class Server extends Thread { 
    public static final int PORT = 3333; 
    public static final int BUFFER_SIZE = 100; 

@Override 
public void run() { 
    try { 
     ServerSocket serverSocket = new ServerSocket(PORT); 
     while (true) { 
      Socket s = serverSocket.accept(); 
      saveFile(s); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

private void saveFile(Socket socket) throws Exception { 
    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); 
    ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); 
    FileOutputStream fos = null; 
    byte [] buffer = new byte[BUFFER_SIZE];  
    Object o = ois.readObject(); 

    if (o instanceof String) { 
     fos = new FileOutputStream(o.toString()); 
    } else { 
     throwException(null); 
    } 
    Integer bytesRead = 0; 

    do { 
     o = ois.readObject(); 

     if (!(o instanceof Integer)) { 
      throwException(null); 
     } 

     bytesRead = (Integer)o; 

     o = ois.readObject(); 

     if (!(o instanceof byte[])) { 
      throwException(null); 
     } 

     buffer = (byte[]) o; 
     fos.write(buffer, 0, bytesRead); 
    } while (bytesRead == BUFFER_SIZE); 

    fos.close(); 

    ois.close(); 
    oos.close(); 
} 

public static void throwException(String message) throws Exception { 
    throw new Exception(message); 
} 

public static void main(String[] args) { 
    new Server().start(); 
} 

}

package com.filetransfer.web; 
import java.io.*; 
import java.net.Socket; 
import java.util.Arrays; 
import javax.servlet.*; 
import javax.servlet.http.*; 

public class FileTransfer extends HttpServlet { 

private static final long serialVersionUID = 1L; 
public static final int PORT = 3333; 
public static final int BUFFER_SIZE = 100; 
public static final String HOST = "localhost"; 

public void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException { 

    String action = request.getParameter("option"); 
    System.out.println(action); 
    if ("upload".equals(action)) { 
     uploadFile(request); 
    } else if ("download".equals(action)) { 
     downloadFile(request, response); 
    } 
} 
public void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException { 

    doGet(request, response); 
} 
public void reportError(HttpServletResponse response, String message) throws IOException { 
      response.sendError(HttpServletResponse.SC_NOT_FOUND, message); 
} 

public void uploadFile(HttpServletRequest request) { 

    String fileLocation = request.getParameter("localfile"); 
    File file = new File(fileLocation); 

    Socket socket; 
    try { 
     socket = new Socket(HOST, PORT); 
     ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); 
     ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); 

     oos.writeObject(file.getName()); 

     FileInputStream fis = new FileInputStream(file); 
     byte [] buffer = new byte[BUFFER_SIZE]; 
     Integer bytesRead = 0; 

     while ((bytesRead = fis.read(buffer)) > 0) { 
      oos.writeObject(bytesRead); 
      oos.writeObject(Arrays.copyOf(buffer, buffer.length)); 
     } 

     oos.close(); 
     ois.close(); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 


public void downloadFile(HttpServletRequest request, HttpServletResponse response) { 

     File file = new File(request.getParameter("remotefile")); 
     Socket socket; 
     InputStream inputStream = null; 
     OutputStream outputStream = null; 
     try { 
      socket = new Socket(HOST, PORT); 
      response.setContentLength((int)file.length()); 
      outputStream = response.getOutputStream(); 
      inputStream = new BufferedInputStream(new FileInputStream(file)); 
      int nextByte; 
      while ((nextByte = inputStream.read()) != -1) { 
       outputStream.write(nextByte); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      if (inputStream != null) { 
       try { 
        inputStream.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 

}

回答

5

由于您使用一个HTTP 的servlet,我强烈建议使用HTTP客户端。不要绕过专有和自发创建的请求/响应格式,而只是根据HTTP协议构建请求和响应。当您遵守某种运输标准时,毫无疑问,有几种API和工具可用于缓解工作。

在客户端,您可以使用java.net.URLConnectionApache HttpClient。通过HTTP从客户端发送文件到服务器(上传)通常需要multipart/form-data请求编码。通过HTTP从服务器发送文件到客户端(下载)通常只需要一个正确的Content-Type标题和整个文件作为响应主体。

this answer的底部,您可以找到一个示例如何通过URLConnection(和this answer示例Apache HttpClient 4)上载文件。在this answer中,您可以找到一个示例,了解如何在servlet中处理上载的文件。保存上传文件很简单:只需将获得的InputStream写入FileOutputStream即可。在this article中,您可以找到如何发送文件以供下载的示例。保存下载的文件也很简单,只需将URLConnection#getInputStream()写入FileOutputStream即可。

+3

BalusC在这里提出一个非常重要的观点。没有必要重新发明轮子。 – rfeak 2011-01-09 00:21:37

相关问题