1. 程式人生 > >Java 檔案上傳與下載

Java 檔案上傳與下載

日常開發中,時常遇到檔案的上傳與下載。這裡就檔案的上傳和下載功能做一個共通的Java類,方便以後呼叫!

1.首先是檔案的下載共通類:


    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.net.URI;
    import java.net.URL;
    import java.net.URLEncoder;

    import javax.servlet.ServletOutputStream;
    import javax.servlet
.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.springframework
.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.oreilly.servlet.ServletUtils; public class FileDownloadUtil { public static String constFileName(String fileName) { return fileName.substring
(0, fileName.indexOf(".") - 24) + fileName.substring(fileName.indexOf(".")); } /** * 下載檔案介面 * * @param request * @param response * @author wul * @return */ public void downloadFile(HttpServletRequest request, HttpServletResponse response) { String fileDirStr = request.getParameter("fileDir").replace("/", "\\\\"); // 獲取檔名稱 int bIndex = fileDirStr.indexOf("\\", 2); String fileName = fileDirStr.substring(bIndex + 2, fileDirStr.length()); fileDirStr = fileDirStr.replace("\\", "/"); try { /* 封裝請求路徑 */ URL url = new URL(SystemPropertyHandler.getProperty("fileServerURL") + fileDirStr); URI uri = new URI(url.getProtocol(), url.getHost() + ":" + url.getPort(), url.getPath(), url.getQuery(), null); // 構造Http請求 HttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost(uri); // 執行請求 HttpResponse responses = client.execute(post); // 獲得請求檔案輸入流 InputStream is = responses.getEntity().getContent(); // 生命位元組碼 int read = 0; byte[] bytes = new byte[1024]; String PROCESSPATH_JILIANG = fileName; String path = request.getSession().getServletContext().getRealPath(PROCESSPATH_JILIANG); // 將輸入流持久化寫入本地檔案流 FileOutputStream fo = new FileOutputStream(path); // OutputStream os = response.getOutputStream(); while ((read = is.read(bytes)) != -1) { fo.write(bytes, 0, read); } // 轉換檔名稱Byte,支援中文檔名 fileName = new String(fileName.getBytes("utf8"), "utf-8"); fileName = constFileName(fileName); fileName = URLEncoder.encode(fileName, "UTF-8"); fileName = fileName.replace("+", " "); // 設定response響應頭 // 把響應設定為二進位制流 ,* = application/octet-stream 可下載任何型別的檔案 // setContentType瀏覽器會開啟下載框 response.setContentType("application/octet-stream;charset=UTF-8"); // 設定編碼 request.setCharacterEncoding("UTF-8"); response.setHeader("Content-Disposition", "attachment; filename=" + fileName); ServletOutputStream out = null; try { out = response.getOutputStream(); // 輸出到頁面下載框 ServletUtils.returnFile(path, out); } catch (Exception e) { e.printStackTrace(); } finally { if (null != out) { out.close(); } fo.close(); File file = new File(path); file.delete(); } } catch (Exception e) { e.printStackTrace(); } } /** * 下載檔案 * * @param fileDir */ public static String downloadFile(String fileDir, String directory) { String fileDirStr = fileDir.replace("/", "\\\\"); // 獲取檔名稱 int bIndex = fileDirStr.indexOf("\\", 2); String fileName = fileDirStr.substring(bIndex + 2, fileDirStr.length()); fileDirStr = fileDirStr.replace("\\", "/"); try { /* 封裝請求路徑 */ URL url = new URL(SystemPropertyHandler.getProperty("fileServerURL") + fileDirStr); URI uri = new URI(url.getProtocol(), url.getHost() + ":" + url.getPort(), url.getPath(), url.getQuery(), null); // 構造Http請求 HttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost(uri); // 執行請求 HttpResponse responses = client.execute(post); // 獲得請求檔案輸入流 InputStream is = responses.getEntity().getContent(); // 生命位元組碼 int read = 0; byte[] bytes = new byte[1024]; fileName = constFileName(fileName); fileName = fileName.substring(fileName.lastIndexOf("\\") + 1); String path = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession().getServletContext().getRealPath(directory + fileName); // 將輸入流持久化寫入本地檔案流 FileOutputStream fo = new FileOutputStream(path); while ((read = is.read(bytes)) != -1) { fo.write(bytes, 0, read); } fo.close(); return path; } catch (Exception e) { e.printStackTrace(); } return null; } }
該類提供了兩種不同的傳參方式,第一種方法引數為 HttpServletRequest request, HttpServletResponse response,通過 request 獲取伺服器檔案路徑 fileDir,通過 response 設定傳送到客戶端的響應的內容型別及響應頭。第二種方法則直接傳伺服器檔案地址,下載到本地的地址。這裡的 SystemPropertyHandler 類是讀取配置檔案的共通類,主要用來讀取配置檔案中配置的下載及上傳地址等相關資訊。

2.再就是檔案的上傳共通類:

    import java.io.File;
    import java.net.URLEncoder;
    import java.nio.charset.Charset;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.Enumeration;
    import java.util.List;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import org.apache.http.HttpResponse;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.mime.HttpMultipartMode;
    import org.apache.http.entity.mime.MultipartEntity;
    import org.apache.http.entity.mime.content.ContentBody;
    import org.apache.http.entity.mime.content.FileBody;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.util.EntityUtils;
    import org.springframework.web.multipart.MultipartFile;

    import com.oreilly.servlet.MultipartRequest;

    public class FileUploadUtil {

        /**
         * 重寫generateContentType,去掉charset的設定,瀏覽器不設定charset,這裡的post請求也要去掉charset的設定
         * @author Administrator
         *
         */
        public class CustomMultipartEntity extends MultipartEntity {

            public CustomMultipartEntity(
                    HttpMultipartMode mode,
                    String boundary,
                    Charset charset){
                super(mode,boundary,charset);
            }

            @Override
            protected String generateContentType(
                    final String boundary,
                    final Charset charset) {
                StringBuilder buffer = new StringBuilder();
                buffer.append("multipart/form-data; boundary=");
                buffer.append(boundary);
    //          if (charset != null) {
    //              buffer.append("; charset=");
    //              buffer.append(charset.name());
    //          }
                return buffer.toString();
            }
        }

        /**
         * 上傳檔案介面
         * 
         * @param request
         * @param response
         * @return
         */

        public String uploadFileTest(MultipartFile file) {
            String strUtil = "";
            try {
                File uploadFile = this.mkFileTest(file);
                String fileDir = this.construFolderName();

                // 構造上傳檔案
                MultipartEntity mpEntity = new CustomMultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE,null,Charset.forName("utf-8"));
                ContentBody cbFile = new FileBody(uploadFile);
                mpEntity.addPart("userfile", cbFile);

                // 構造Http請求
                HttpClient client = new DefaultHttpClient();
                HttpPost post = new HttpPost(SystemPropertyHandler.getProperty("fileServerPath")
                        + fileDir);
                post.setEntity(mpEntity);
                // 執行請求
                HttpResponse responses = client.execute(post);

                // 接收請求返回值
                strUtil =EntityUtils.toString(responses.getEntity(), "utf-8");

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

        /**
         * 上傳檔案介面
         * 
         * @param request
         * @param response
         * @return
         */

        public String uploadFileDwj(HttpServletRequest request,
                HttpServletResponse response) {
            String strUtil = "";
            try {
                List<File> uploadFiles = this.mkFileDwj(request);
                String fileDir = this.construFolderName();

                for(File uploadFile : uploadFiles){
                    // 構造上傳檔案
                    MultipartEntity mpEntity = new CustomMultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE,null,Charset.forName("utf-8"));
                    ContentBody cbFile = new FileBody(uploadFile);
                    mpEntity.addPart("userfile", cbFile);

                    // 構造Http請求
                    HttpClient client = new DefaultHttpClient();
                    HttpPost post = new HttpPost(SystemPropertyHandler.getProperty("fileServerPath")
                            + fileDir);
                    post.setEntity(mpEntity);
                    // 執行請求
                    HttpResponse responses = client.execute(post);

                    // 接收請求返回值
                    strUtil =EntityUtils.toString(responses.getEntity(), "utf-8");
                }

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

        /**
         * 上傳檔案介面
         * 
         * @param request
         * @param response
         * @return
         */

        public String uploadFile(HttpServletRequest request,
                HttpServletResponse response) {
            String strUtil = "";
            try {
                File uploadFile = this.mkFile(request);
                String fileDir = this.construFolderName();

                // 構造上傳檔案
                MultipartEntity mpEntity = new CustomMultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE,null,Charset.forName("utf-8"));
                ContentBody cbFile = new FileBody(uploadFile);
                mpEntity.addPart("userfile", cbFile);

                // 構造Http請求
                HttpClient client = new DefaultHttpClient();
                HttpPost post = new HttpPost(SystemPropertyHandler.getProperty("fileServerPath")
                        + fileDir);
                post.setEntity(mpEntity);
                // 執行請求
                HttpResponse responses = client.execute(post);

                // 接收請求返回值
                strUtil =EntityUtils.toString(responses.getEntity(), "utf-8");

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

        public String uploadFile(String file) {
            String strUtil = "";
            try {
                File uploadFile = new File(file);
                String fileDir = this.construFolderName();

                // 構造上傳檔案
                MultipartEntity mpEntity = new CustomMultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE,null,Charset.forName("utf-8"));
                ContentBody cbFile = new FileBody(uploadFile);
                mpEntity.addPart("userfile", cbFile);

                // 構造Http請求
                HttpClient client = new DefaultHttpClient();
                HttpPost post = new HttpPost(SystemPropertyHandler.getProperty("fileServerPath")
                        + fileDir);
                post.setEntity(mpEntity);
                // 執行請求
                HttpResponse responses = client.execute(post);

                // 接收請求返回值
                strUtil =EntityUtils.toString(responses.getEntity(), "utf-8");

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

        /**
         * 刪除檔案介面
         * 
         * @param request
         * @param response
         * @author nlb
         * @return
         */

        public String delFile(HttpServletRequest request,
                HttpServletResponse response,String fileName) {
            String strUtil = "";
            try {
                request.setCharacterEncoding("UTF-8");
                // 構造Http請求
                HttpClient client = new DefaultHttpClient();
                HttpPost post = new HttpPost(SystemPropertyHandler.getProperty("fileDeleteServerPath")
                        + URLEncoder.encode(fileName,"utf-8"));
    //          post.setEntity(mpEntity);
                // 執行請求
                HttpResponse responses = client.execute(post);

                // 接收請求返回值
                strUtil =EntityUtils.toString(responses.getEntity(), "utf-8");

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

        /**
         * 生成檔案儲存路徑 生成規則 年-月
         * 
         * @author wul
         * @return
         */
        public static String construFolderName() {
            Calendar now = Calendar.getInstance();
            String fileDirStr = now.get(Calendar.YEAR) + "-"
                    + (now.get(Calendar.MONTH) + 1);
            return fileDirStr;
        }

        /**
         * 生成檔案介面
         * @param request
         * @param response
         * @return
         * @throws Exception 
         */
        public File mkFileTest(MultipartFile file) throws Exception {
            // 設定上傳檔案的大小,超過這個大小 將丟擲IOException異常,預設大小是10M。
            int inmaxPostSize = 10 * 1024 * 1024;
            long size= file.getSize();
            if(size > inmaxPostSize){
                throw new Exception("超出大小限制!");
            }
            // 獲取檔案在文件伺服器中的儲存路徑
            //String fileDirStr = this.construFolderName();
            System.out.println(file.getOriginalFilename());
            File result = new File("111.xml");
            file.transferTo(result);
            System.out.println(result.getAbsolutePath());
            return result;
        }

        /**
         * 生成檔案介面
         * 
         * @author wul
         * @param request
         * @param response
         * @return
         */
        public List<File> mkFileDwj(HttpServletRequest request) {
            // 獲取檔案在文件伺服器中的儲存路徑
            String fileDirStr = this.construFolderName();

            // 確定檔案的儲存位置
            File fileDir = new File(request.getServletContext().getRealPath(
                    "/FileDir/" + fileDirStr));
            if (!fileDir.exists()) {
                fileDir.mkdirs();
            }

            // 設定上傳檔案的大小,超過這個大小 將丟擲IOException異常,預設大小是10M。
            int inmaxPostSize = 10 * 1024 * 1024;
            MultipartRequest multirequest = null;

            try {
                // MultipartRequest()有8種建構函式!
                multirequest = new MultipartRequest(request,
                        fileDir.getAbsolutePath(), inmaxPostSize, "utf-8"); // GBK中文編碼模式上傳檔案

                Enumeration<String> filedFileNames = multirequest.getFileNames();
                String filedName = null;
                List<File> list = new ArrayList<File>();
                if (null != filedFileNames) {
                    while (filedFileNames.hasMoreElements()) {

                        filedName = filedFileNames.nextElement();// 檔案文字框的名稱
                        // 獲取該檔案框中上傳的檔案,即對應到上傳到伺服器中的檔案  
                        File uploadFile = multirequest.getFile(filedName);
                        list.add(uploadFile);
                    }
                }

                return list;

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

        /**
         * 生成檔案介面
         * 
         * @author wul
         * @param request
         * @param response
         * @return
         */
        public File mkFile(HttpServletRequest request) {
            // 獲取檔案在文件伺服器中的儲存路徑
            String fileDirStr = this.construFolderName();

            // 確定檔案的儲存位置
            File fileDir = new File(request.getServletContext().getRealPath(
                    "/FileDir/" + fileDirStr));
            if (!fileDir.exists()) {
                fileDir.mkdirs();
            }

            // 設定上傳檔案的大小,超過這個大小 將丟擲IOException異常,預設大小是10M。
            int inmaxPostSize = 10 * 1024 * 1024;
            MultipartRequest multirequest = null;

            try {
                // MultipartRequest()有8種建構函式!
                multirequest = new MultipartRequest(request,
                        fileDir.getAbsolutePath(), inmaxPostSize, "utf-8"); // GBK中文編碼模式上傳檔案

                Enumeration<String> filedFileNames = multirequest.getFileNames();
                String filedName = null;
                if (null != filedFileNames) {
                    while (filedFileNames.hasMoreElements()) {

                        filedName = filedFileNames.nextElement();// 檔案文字框的名稱
                        // 獲取該檔案框中上傳的檔案,即對應到上傳到伺服器中的檔案  
                        File uploadFile = multirequest.getFile(filedName);
                        return uploadFile;

                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
        /**
         * 生成檔案介面
         * 
         * @param request
         * @param response
         * @return
         */
        public File mkMaxFile(HttpServletRequest request) {
            // 獲取檔案在文件伺服器中的儲存路徑
            String fileDirStr = this.construFolderName();

            // 確定檔案的儲存位置
            File fileDir = new File(request.getServletContext().getRealPath(
                    "/FileDir/" + fileDirStr));
            if (!fileDir.exists()) {
                fileDir.mkdirs();
            }

            // 設定上傳檔案的大小
            int inmaxPostSize = 500 * 1024 * 1024;
            MultipartRequest multirequest = null;
            try {
                // MultipartRequest()有8種建構函式!
                multirequest = new MultipartRequest(request,
                        fileDir.getAbsolutePath(), inmaxPostSize, "utf-8"); // GBK中文編碼模式上傳檔案

                Enumeration<String> filedFileNames = multirequest.getFileNames();
                String filedName = null;
                if (null != filedFileNames) {
                    while (filedFileNames.hasMoreElements()) {

                        filedName = filedFileNames.nextElement();// 檔案文字框的名稱
                        // 獲取該檔案框中上傳的檔案,即對應到上傳到伺服器中的檔案  
                        File uploadFile = multirequest.getFile(filedName);
                        return uploadFile;

                    }
                }

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

3.伺服器端對上傳下載的處理
在上面的上傳和下載共通類中,使用了 SystemPropertyHandler 來讀取上傳和下載的 URL 請求,然後伺服器端對請求的URL進行處理,如這裡的上傳URL為:http://192.168.0.20/FileBank/FileUpload?fileDir=,下載地址為 http://192.168.0.20/FileBank/FileDir/,刪除地址為 http://192.168.0.20/FileBank/FileDelete?fileDir=。這裡伺服器端採用 Servlet 對請求的處理。下面就上傳、下載和刪除給出處理程式碼:
- 3.1 檔案上傳

import com.fable.filemanager.util.RenamePolicyCos;
import com.oreilly.servlet.MultipartRequest;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet({"/FileUpload"})
public class FileUpload extends HttpServlet
{
  private static final long serialVersionUID = 1L;

  protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
  {
    doPost(request, response);
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
  {
    String fileDirStr = request.getParameter("fileDir");
    File fileDir = new File(getServletContext().getRealPath("/FileDir/" + fileDirStr));

    if (!fileDir.exists()) {
      fileDir.mkdirs();
    }

    int inmaxPostSize = 10485760;
    MultipartRequest multirequest = null;

    RenamePolicyCos myRenamePolicyCos = new RenamePolicyCos();
    try
    {
      multirequest = new MultipartRequest(request, fileDir.getAbsolutePath(), inmaxPostSize, "utf-8", myRenamePolicyCos);

      Enumeration filedFileNames = multirequest.getFileNames();
      String filedName = null;
      if (null != filedFileNames)
        while (filedFileNames.hasMoreElements()) {
          filedName = (String)filedFileNames.nextElement();

          File uploadFile = multirequest.getFile(filedName);

          StringBuffer sbReturn = new StringBuffer();
          sbReturn.append("{");
          sbReturn.append("msg:\"{fileSize:'" + uploadFile.length() + "',fileName:'" + uploadFile.getName() + "',fileDir:'" + fileDirStr + "'}\"");

          sbReturn.append("}");
          response.setCharacterEncoding("utf-8");
          response.setContentType("text/html;charset=utf8");
          response.getWriter().write(sbReturn.toString());
        }
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }
}
  • 3.2 檔案下載
import com.oreilly.servlet.ServletUtils;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet({"/FileDownload"})
public class FileDownload extends HttpServlet
{
  private static final long serialVersionUID = 1L;

  protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
  {
    doPost(request, response);
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
  {
    String fileDir = request.getParameter("fileDir");

    String filePath = "//filedir" + fileDir;

    String Originalname = "test.gif";
    String isofilename = new String(Originalname.getBytes("gb2312"), "ISO8859-1");

    response.setContentType("application/octet-stream");
    response.setHeader("Content-Disposition", "attachment; filename=" + isofilename);

    ServletOutputStream out = null;
    try {
      out = response.getOutputStream();
      ServletUtils.returnFile(filePath, out);

      if (null != out)
        out.close();
    }
    catch (Exception e)
    {
      e.printStackTrace();

      if (null != out)
        out.close();
    }
    finally
    {
      if (null != out)
        out.close();
    }
  }
}
  • 3.3 檔案刪除
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet({"/FileDelete"})
public class FileDelete extends HttpServlet
{
  private static final long serialVersionUID = 1L;

  protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
  {
    doPost(request, response);
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
  {
    String fileDirStr = request.getParameter("fileDir");
    String filename = new String(fileDirStr.getBytes("ISO-8859-1"), "utf-8");
    File fileDir = new File(getServletContext().getRealPath("/FileDir/" + filename));
    StringBuffer sbReturn = new StringBuffer();
    try {
      if ((fileDir.isFile()) && (fileDir.exists())) {
        fileDir.delete();
        sbReturn.append("{msg:\"刪除成功\"}");
      } else {
        sbReturn.append("{msg:\"刪除失敗\"}");
      }
      response.setCharacterEncoding("utf-8");
      response.setContentType("text/html;charset=utf8");
      response.getWriter().write(sbReturn.toString());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

4.總結
上述就是簡單的上傳和下載的共通類實現。這裡只是給出瞭如何上傳檔案到伺服器上,如何從伺服器下下載檔案,以及刪除伺服器儲存檔案。在做檔案上傳和下載這類功能時,建表最好有檔名,伺服器路徑、大小等一些資訊。接下來會寫一篇使用springmvc框架,從控制層,服務層來具體實現如何進行檔案的上傳和下載等功能!