1. 程式人生 > >SpringMVC學習(九)——SpringMVC中實現文件上傳

SpringMVC學習(九)——SpringMVC中實現文件上傳

enc 一個人 ast max fonts common clas c學習 本地磁盤

這一篇博文主要來總結下SpringMVC中實現文件上傳的步驟。但這裏我只講單個文件的上傳。

環境準備

SpringMVC上傳文件的功能需要兩個jar包的支持,如下:
技術分享圖片
工程中肯定要導入以上兩個jar包,主要是CommonsMultipartResolver解析器依賴commons-fileupload和commons-io這兩個jar包。

單個文件的上傳

前臺頁面

我們要改造editItem.jsp頁面,主要是在form表單中添加商品圖片一欄,效果我截圖如下:
技術分享圖片
註意一點的是form表單中別忘了寫enctype="multipart/form-data"屬性。

對多部件類型multipart解析

意思就是說針對上面的enctype=”multipart/form-data”類型,SpringMVC需要對multipart類型的數據進行解析,在springmvc.xml中配置multipart類型解析器即可。如下:

<!-- 配置多媒體文件解析器 -->
<!-- 文件上傳 -->
<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 設置上傳文件的最大尺寸為5MB -->
    <property name="maxUploadSize">
        <value>5242880</value>
    </property>
</bean>

創建文件保存的虛擬目錄

在上傳文件之前,首先要創建一個虛擬目錄來保存文件,這個虛擬目錄會對應磁盤上的一個實際的目錄,在實際開發中肯定會有一個服務器專門存儲資源的,在這裏我們就用本地磁盤來保存文件,然後映射一個虛擬目錄,用來在程序中指定獲取文件的路徑(其實上面前臺頁面editItem.jsp中,那個src=”/pic/${item.pic}”中的/pic就是虛擬目錄)。
創建的方法有兩種:一是在Eclipse中雙擊tomcat服務器,就會彈出下面的框框:
技術分享圖片
選擇Modules,然後點擊【Add External Web Module…】,在彈出的對話框中進行如下操作,都在圖裏面了。
技術分享圖片
設置好後,保存即可,這樣上傳的文件都會保存到Document base指定的目錄中,相當於虛擬映射到Path指定的目錄中,程序中獲取這個文件,要從Path指定的虛擬目錄中獲取,即我上面的/pic。我可舉一個例子,將一個圖片(例如,0d318effd664668f555d43966b3294a6_b.jpg)拷貝到Document base指定的目錄中,即F:\temp\images目錄中,然後啟動tomcat服務器,在瀏覽器地址欄中輸入url訪問地址——http://localhost:8080/pic/0d318effd664668f555d43966b3294a6_b.jpg

即可訪問到該圖片。
第二種方法就是在tomcat的配置文件中配置一下,其實剛剛在Eclipse中的操作已經自動寫到這個配置文件中了,配置文件位置在tomcat目錄/conf/server.xml中,看一下裏面會多了一行:
技術分享圖片
這就是剛剛我配置的,它自動寫到這個文件中了,所以我們也可以直接自己在該配置文件中寫,就不需要在Eclipse中配置了。

編寫後臺Controller方法

接下來就是重點了,前臺傳過來的文件,我們在ItemController類中需要進行處理,然後保存到磁盤中,同時也就映射到了我們配置的虛擬路徑中了,那麽如何接收呢?看下面的代碼:

@RequestMapping(value="/updateitem",method={RequestMethod.POST,RequestMethod.GET})
public String updateItems(Items items, MultipartFile picture) throws Exception {
    // 把圖片保存到圖片目錄下
    // 保存圖片,這個圖片有的時候文件名可能會重復,你保存多了會把原來的圖片給覆蓋掉,這就不太合適了。
    // 所以為每個文件生成一個新的文件名
    String picName = UUID.randomUUID().toString();
    // 截取文件的擴展名(如.jpg)
    String oriName = picture.getOriginalFilename();
    String extName = oriName.substring(oriName.lastIndexOf("."));
    // 保存文件
    picture.transferTo(new File("F:\\temp\\images\\" + picName + extName));

    // 把文件名保存到數據庫
    items.setPic(picName + extName);
    itemService.updateItem(items);
    return "forward:/item/itemEdit.action";
}

註意:考慮實際情況,保存圖片時一般不只你一個人保存圖片,那麽這個圖片有的時候文件名可能會重復,你保存多了會把原來的圖片給覆蓋掉,這就不太合適了,所以需要使用UUID算法為每個文件生成一個新的文件名。
首先來看一下形參,主要有Items和MultipartFile類型的picture,我這裏上傳一張圖片是ItemsCustom類的一個屬性,所以有了這個形參,是為了寫到該類中,SpringMVC文件上傳的類是MultipartFile,參數名稱picture必須和前臺editItem.jsp頁面的name屬性一致才行。上傳圖片之後的效果類似於:
技術分享圖片
並且圖片的文件名也保存到了數據庫表中,如下:
技術分享圖片
最後總結一下,我上傳文件的邏輯可能判斷不嚴謹,如果說要更加嚴謹一點的話, 上傳文件的邏輯就應是:首先判斷有沒有上傳文件,如果上傳了,那麽對文件重新命名然後寫到磁盤中。如果沒有上傳文件,那麽我應該還是用原來的文件(圖片)。讀者如果有興趣可以參考下面代碼:

@RequestMapping(value="/updateitem",method={RequestMethod.POST,RequestMethod.GET})
public String updateItems(Items items, MultipartFile picture) throws Exception {

    // 處理上傳的單個圖片    
    String originalFileName = picture.getOriginalFilename();// 原始名稱
    // 上傳圖片
    if (picture != null && originalFileName != null && originalFileName.length() > 0) {
        // 存儲圖片的物理路徑,實際中是要寫到配置文件中的,不能在這寫死
        String pic_path = "F:\\temp\\images\\";
        // 新的圖片名稱
        String newFileName = UUID.randomUUID()
                + originalFileName.substring(originalFileName
                        .lastIndexOf("."));     
        File newFile = new File(pic_path + newFileName);//新圖片   
        picture.transferTo(newFile);// 將內存中的數據寫入磁盤
        items.setPic(newFileName);// 將新圖片名稱寫到itemsCustom中
    } else {
        //如果用戶沒有選擇圖片就上傳了,還用原來的圖片
        Items temp = itemsService.findItemsById(items.getId());
        items.setPic(temp.getPic());
    }

    // 調用service更新商品信息,頁面需要將商品信息傳到此方法
    itemService.updateItem(items);
    return "forward:/item/itemEdit.action";
}

到這裏,單個文件的上傳我就已總結完了。

SpringMVC學習(九)——SpringMVC中實現文件上傳