java servlet使用uploadfile實現文件上傳的功能

comons包導入IDEA失敗?文件上傳後在工程中相應的文件夾下找不到上傳的文件?

近期想要基於hadoop分佈式系統開發一個雲盤項目。前些時候已經給IDEA配置好了tomcat的環境,配置好了java servlet的運行環境。這兩天自己摸索着實現了一個簡單的文件上傳功能。在這個過程遇到了一些坑,在這裏記錄一下。

一、資源準備

需要下載下面兩個jar包。

comons-fileupload.jar下載地址:http://commons.apache.org/proper/commons-fileupload/download_fileupload.cgi

commons-io.jar下載地址http://commons.apache.org/proper/commons-io/download_io.cgi

選擇.zip壓縮包下載,下載完成後進行解壓縮。不能直接把zip包導進去!!!

文件夾裏面的commons-fileupload-1.3.3.jar和commons-io-2.5.jar纔是我們真正需要的jar包

注意:因爲之前一直以爲jar包本質上就是一個壓縮包,所以我在下載完兩個.zip文件後直接把它給導入工程,發現不行。又把.zip的後綴改成了jar,導入工程,還是不行。後面摸索着才發現,這真特麼就是個壓縮包,裏面包含很多說明文檔。。。

二、建工程

javaweb工程的創建,詳情參考:《如何用intellij idea新建一個java web+Servlet項目》

1、把文件上傳需要的兩個jar包導入lib文件夾下

2、在src文件夾下右擊創建一個java文件

代碼內容如下:

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class UploadServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //得到上傳文件的保存目錄,將上傳的文件存放於WEB-INF目錄下,不允許外界直接訪問,保證上傳文件的安全
        String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
        System.out.println(this.getServletContext().getRealPath("/WEB-INF/upload"));
        File file = new File(savePath);
        //判斷上傳文件的保存目錄是否存在
        if (!file.exists() && !file.isDirectory()) {
            System.out.println(savePath+"目錄不存在,需要創建");
            //創建目錄
            file.mkdir();
        }
        //消息提示
        String message = "";
        try{
            //使用Apache文件上傳組件處理文件上傳步驟:
            //1、創建一個DiskFileItemFactory工廠
            DiskFileItemFactory factory = new DiskFileItemFactory();
            //2、創建一個文件上傳解析器
            ServletFileUpload upload = new ServletFileUpload(factory);
            //解決上傳文件名的中文亂碼
            upload.setHeaderEncoding("UTF-8");
            //3、判斷提交上來的數據是否是上傳表單的數據
            if(!ServletFileUpload.isMultipartContent(request)){
                //按照傳統方式獲取數據
                return;
            }
            //4、使用ServletFileUpload解析器解析上傳數據,解析結果返回的是一個List<FileItem>集合,每一個FileItem對應一個Form表單的輸入項
            List<FileItem> list = upload.parseRequest(request);
            for(FileItem item : list){
                //如果fileitem中封裝的是普通輸入項的數據
                if(item.isFormField()){
                    String name = item.getFieldName();
                    //解決普通輸入項的數據的中文亂碼問題
                    String value = item.getString("UTF-8");
                    //value = new String(value.getBytes("iso8859-1"),"UTF-8");
                    System.out.println(name + "=" + value);
                }else{//如果fileitem中封裝的是上傳文件
                    //得到上傳的文件名稱,
                    String filename = item.getName();
                    System.out.println(filename);
                    if(filename==null || filename.trim().equals("")){
                        continue;
                    }
                    //注意:不同的瀏覽器提交的文件名是不一樣的,有些瀏覽器提交上來的文件名是帶有路徑的,如:  c:\a\b\1.txt,而有些只是單純的文件名,如:1.txt
                    //處理獲取到的上傳文件的文件名的路徑部分,只保留文件名部分
                    filename = filename.substring(filename.lastIndexOf("\\")+1);
                    //獲取item中的上傳文件的輸入流
                    InputStream in = item.getInputStream();
                    //創建一個文件輸出流
                    FileOutputStream out = new FileOutputStream(savePath + "\\" + filename);
                    //創建一個緩衝區
                    byte buffer[] = new byte[1024];
                    //判斷輸入流中的數據是否已經讀完的標識
                    int len = 0;
                    //循環將輸入流讀入到緩衝區當中,(len=in.read(buffer))>0就表示in裏面還有數據
                    while((len=in.read(buffer))>0){
                        //使用FileOutputStream輸出流將緩衝區的數據寫入到指定的目錄(savePath + "\\" + filename)當中
                        out.write(buffer, 0, len);
                    }
                    //關閉輸入流
                    in.close();
                    //關閉輸出流
                    out.close();
                    //刪除處理文件上傳時生成的臨時文件
                    item.delete();
                    message = "文件上傳成功!";
                }
            }
        }catch (Exception e) {
            message= "文件上傳失敗!";
            e.printStackTrace();

        }
        request.setAttribute("message",message);
        request.getRequestDispatcher("/message.jsp").forward(request, response);
    }

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

        doGet(request, response);
    }
}

3、修改index.jsp的代碼

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
  <title>文件上傳</title>
</head>

<body>
<form action="UploadServlet" enctype="multipart/form-data" method="post">
  上傳用戶:<input type="text" name="username"><br/>
  上傳文件1:<input type="file" name="file1"><br/>
  上傳文件2:<input type="file" name="file2"><br/>
  <input type="submit" value="提交">
</form>
</body>
</html>

4、在相同的位置再新建一個message.jsp

代碼如下:

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
    <title>消息提示</title>
</head>

<body>
${message}
</body>
</html>

5、修改web.xml的內容

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>UploadServlet</servlet-name>
        <servlet-class>UploadServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>UploadServlet</servlet-name>
        <url-pattern>/UploadServlet</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

三、運行調試

1、文件下載位置

由於我剛開始並沒有在項目中的WEB-INF下創建upload文件夾,它會自動幫我創建,但是工程裏面看不到。導致我一直以爲我的程序有問題,文件沒有上傳成功。後面我輸出了這個文件存儲的真實路徑。到真實路徑中去看了,發現文件已經被上傳了。

2、頁面如下

3、IDEA中的交互界面

我們發現工程中還是沒有upload這個文件夾。

不要急,我們去真實路徑下找看看

會發現文件已經上傳成功。

 

四、總結

我之前以爲上傳的文件無法在工程裏面看到是因爲我沒有在工程中先創建相應的文件夾(比如:upload)。但是後面我新建了一個工程,先建好了upload文件夾。然而上傳的文件依然無法在工程中看到,目前還不是很清楚原因。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章