2011-01-09 237 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

相關問題