【SpringMVC學習08】SpringMVC中實現文件上傳


 

  之前有寫過一篇struts2實現的文件上傳,這一篇博文主要來總結下springmvc實現文件上傳的步驟。首先來看一下單個文件的上傳,然后再來總結下多個文件上傳。

 

1. 環境准備

 

  springmvc上傳文件的功能需要兩個jar包的支持http://download.csdn.net/detail/eson_15/9556808,如下 

 

jar包

 

2. 單個文件的上傳

 

2.1 前台頁面

 

  簡單的寫一下前台頁面,注意一點的是form表單中別忘了寫enctype="multipart/form-data"屬性:

 

<tr>
    <td>商品圖片</td>
    <td><c:if test="${itemsCustom.pic !=null}">
            <img src="/file/${itemsCustom.pic}" width=100 height=100 /><br />
        </c:if> 
        <input type="file" name="items_pic"/>
    </td>
</tr>

 

2.2 對多部件類型multipart解析

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

 

<!-- 文件上傳,需要配置MultipartResolver處理器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 設置船上文件的最大尺寸為5MB -->
    <property name="maxUploadSize" value="5242880"/>
    <property name="defaultEncoding" value="utf-8"/>   
</bean>

 

2.3 創建文件保存的虛擬目錄

  在上傳文件之前,首先要創建一個虛擬目錄來保存文件,這個虛擬目錄會對應磁盤上的一個實際的目錄,在實際中肯定會有一個服務器專門存儲資源的,在這里我們就用本地來保存文件,然后映射一個虛擬目錄,用來在程序中指定獲取文件的路徑(其實上面前台頁面中,那個src=”/file/${itemsCustom.pic}”中的/file就是虛擬目錄)。 
創建的方法有兩種:一是在Myeclipse中雙擊tomcat服務器,然后彈出下面的框框: 
虛擬目錄
  設置好后,保存即可,這樣上傳的文件都會保存到Document base指定的目錄中,相當於虛擬映射到path指定的目錄中,程序中獲取這個文件,要從path指定的虛擬目錄中獲取,即我上面的/file。 
  第二種方法就是在tomcat的配置文件中配置一下,其實剛剛在Myeclipse中的操作已經自動寫到這個配置文件中了,配置文件位置在tomcat目錄/conf/server.xml中,看一下里面會多了一行: 
配置 
  這就是剛剛我配置的,它自動寫到這個文件中了,所以我們也可以直接自己在文件中寫,就不需要在Myeclipse中配置了。

2.4 編寫后台Controller方法

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

 

    @RequestMapping("/editItemsSubmit")
    public String editItemsSubmit(Model model, HttpServletRequest request,
            Integer id,
            @Validated(value = { ValidGroup1.class }) ItemsCustom itemsCustom,
            BindingResult bindingResult, 
            @RequestParam MultipartFile[] items_pic)
            throws Exception {

        // 獲取校驗錯誤信息
        if (bindingResult.hasErrors()) {
            // 輸出錯誤信息
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            for (ObjectError objectError : allErrors) {
                // System.out.println(objectError.getDefaultMessage());
                // 原來是上面這句,但是由於properties文件默認無法輸入中文,所以我把properties文件改成了utf-8編碼,
                // 但是這樣的話讀取出來就是亂碼了,所以我先用iso打亂,再用utf-8生成,即可解決亂碼問題
                System.out.println(new String(objectError.getDefaultMessage()
                        .getBytes("ISO-8859-1"), "UTF-8"));
            }
            // 將錯誤信息傳到頁面

            model.addAttribute("allErrors", allErrors);
        }
      /*
        // 處理上傳的單個圖片
        // 原始名稱
        String originalFileName = items_pic.getOriginalFilename();
        // 上傳圖片
        if (items_pic != null && originalFileName != null && originalFileName.length() > 0) {
            // 存儲圖片的物理路徑
            String pic_path = "E:\\github\\develop\\upload\\temp\\";
            // 新的圖片名稱
            String newFileName = UUID.randomUUID()
                    + originalFileName.substring(originalFileName
                            .lastIndexOf("."));
            // 新圖片
            File newFile = new File(pic_path + newFileName);
            // 將內存中的數據寫入磁盤
            items_pic.transferTo(newFile);
            // 將新圖片名稱寫到itemsCustom中
            itemsCustom.setPic(newFileName);
        } else {
            //如果用戶沒有選擇圖片就上傳了,還用原來的圖片
            ItemsCustom temp = itemsService.findItemsById(itemsCustom.getId());
            itemsCustom.setPic(temp.getPic());
        }

        // 調用service更新商品信息,頁面需要將商品信息傳到此方法
        itemsService.updateItems(id, itemsCustom);
*/
        // return "redirect:queryItems.action";
        // return "forward:queryItems.action";

        return "/WEB-INF/jsp/success.jsp";
    }

 

首先來看一下形參,主要有ItemsCustom和MultipartFile類型的items_pic,我這里上傳一張圖片是ItemsCustom類的一個屬性,所以有了這個形參,是為了寫到該類中,另外前面的@Validated注解是我寫springmvc校驗的時候用的,跟這里文件上傳無關。springmvc文件上傳的類是MultipartFile,名items_pic必須和前台的name屬性一致才行。 
  上傳文件的邏輯是,首先判斷有沒有上傳文件,如果上傳了,那么對文件重新命名然后寫到磁盤中。如果沒有上傳文件,那么我應該還是用原來的文件(圖片),因為我寫的這個例子是更新商品信息,對文件上傳那里沒有做非空驗證,所以在這里寫了else。 
  這樣文件就上傳完了,這是單個文件的上傳。但是有點問題 會報錯,后來注釋掉使用 多文件上傳。

 

3. 多個文件的上傳

 

  多個文件上傳和單個文件上傳原理一樣的,不過在細節上會有點不同,待我一個個總結。首先在前台頁面上要注意的一點是name屬性必須一樣,即:

 

 

    @RequestMapping("/editItemsSubmit")
    public String editItemsSubmit(Model model, HttpServletRequest request,
            Integer id,
            @Validated(value = { ValidGroup1.class }) ItemsCustom itemsCustom,
            BindingResult bindingResult, 
            @RequestParam MultipartFile[] items_pic)
            throws Exception {

        // 獲取校驗錯誤信息
        if (bindingResult.hasErrors()) {
            // 輸出錯誤信息
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            for (ObjectError objectError : allErrors) {
                // System.out.println(objectError.getDefaultMessage());
                // 原來是上面這句,但是由於properties文件默認無法輸入中文,所以我把properties文件改成了utf-8編碼,
                // 但是這樣的話讀取出來就是亂碼了,所以我先用iso打亂,再用utf-8生成,即可解決亂碼問題
                System.out.println(new String(objectError.getDefaultMessage()
                        .getBytes("ISO-8859-1"), "UTF-8"));
            }
            // 將錯誤信息傳到頁面

            model.addAttribute("allErrors", allErrors);
        }
        //多個文件上傳  //多個圖片,不存數據庫了,在此打印一下即可
        for(MultipartFile myfile:items_pic){
            if(myfile.isEmpty()){
                System.out.println("文件未上傳");
            }else{
                
                System.out.println("文件長度: "+myfile.getSize());
                System.out.println("文件類型: "+myfile.getContentType());
                System.out.println("文件名稱: "+myfile.getName());
                System.out.println("文件原名: "+myfile.getOriginalFilename());
                System.out.println("========================");
                
                String originalFileName=myfile.getOriginalFilename();
                String pic_path="E:\\github\\develop\\upload\\temp\\";
                String newFileName=UUID.randomUUID()+originalFileName.substring(originalFileName.lastIndexOf("."));
                File newFile = new File(pic_path + newFileName);
        
                myfile.transferTo(newFile);
            }
        }
        
    
/*
        // 處理上傳的單個圖片
        // 原始名稱
        String originalFileName = items_pic.getOriginalFilename();
        // 上傳圖片
        if (items_pic != null && originalFileName != null && originalFileName.length() > 0) {
            // 存儲圖片的物理路徑
            String pic_path = "E:\\github\\develop\\upload\\temp\\";
            // 新的圖片名稱
            String newFileName = UUID.randomUUID()
                    + originalFileName.substring(originalFileName
                            .lastIndexOf("."));
            // 新圖片
            File newFile = new File(pic_path + newFileName);
            // 將內存中的數據寫入磁盤
            items_pic.transferTo(newFile);
            // 將新圖片名稱寫到itemsCustom中
            itemsCustom.setPic(newFileName);
        } else {
            //如果用戶沒有選擇圖片就上傳了,還用原來的圖片
            ItemsCustom temp = itemsService.findItemsById(itemsCustom.getId());
            itemsCustom.setPic(temp.getPic());
        }

        // 調用service更新商品信息,頁面需要將商品信息傳到此方法
        itemsService.updateItems(id, itemsCustom);
*/
        // return "redirect:queryItems.action";
        // return "forward:queryItems.action";

        return "/WEB-INF/jsp/success.jsp";
    }

 

如上,形參變成數組類型了,且前面要加上@RequestParam注解才行。然后獲取的話,就是遍歷這個數組,循環內部與上面的單個文件上傳就一模一樣了。看一下打印結果: 

http://localhost:8080/SpringMVC_Study/editItems.action?id=3

結果 
  可以看到,兩個文件都順利接收到,至此,多文件上傳成功。關於springmvc的文件上傳功能就總結到這吧。 

本篇遇到了些問題 一直提示 編碼 UTF-8 的不可映射字符 加上如下代碼也不起作用

<build>

<plugins>
<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <skip>true</skip>
                    <source>1.6</source>
                    <target>1.6</target>
                    <!-- <source>${java.compiler}</source>
                    <target>${java.compiler}</target> -->
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
</plugins>

  </build>
<properties>
<project.build.sourceEncoding>utf-8</project.build.sourceEncoding> 
</properties>

最后發現是 Java Compiler 版本已經Installed JRE版本問題


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM