1. 程式人生 > >檔案上傳的幾種方式

檔案上傳的幾種方式

一、springmvc中的檔案上傳

1.配置檔案

(1).pom檔案,檔案上傳主要需要如下幾個jar包

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.5</version>
    </dependency>
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.1</version>
    </dependency>

(2)mvc.xml

<?xml version="1.0" encoding="utf-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 開啟包掃描 -->
    <context:component-scan base-package="controller"/>
    <!-- 設定配置方案-->
    <mvc:annotation-driven/>
    <!-- 檢視解析器 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- 檔案上傳解析器:需要注意的是這個bean的id必須是multipartResolver才能被識別,否則會報沒有配置該解析器的錯誤 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="utf-8"></property>
        <property name="maxUploadSize" value="10240000"/>
    </bean>
</beans>

(3)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_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>uploadmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>uploadmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

2.編寫控制類UploadController.java

第一種,單檔案上傳,使用MultipartFile作為方法引數接收傳入的檔案。

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

/**
 * @author: **
 * @date:2018/9/18 16:01
 * @description:
 */
@Controller
@RequestMapping("/test")
public class UploadController {

    //檔案上傳
    @RequestMapping("/upload")
    public String uploadfile(@RequestParam("file") MultipartFile multipartFile) throws IOException {

        if(!multipartFile.isEmpty()){
            //拼接你想儲存的位置和檔名
            String path = "D:/test/"+multipartFile.getOriginalFilename();
            //獲得專案路徑即webapp所在路徑,可選
            //String pathRoot = request.getSession().getServletContext().getRealPath("");
            File tempFile = new File(path);
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }
            try {
                multipartFile.transferTo(tempFile);
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

//這裡除了transferTo方法,也可以用位元組流的方式上傳檔案,但是位元組流比較慢,所以還是建議用transferTo
//            try {
//                //獲取輸出流
//                OutputStream os=new FileOutputStream(path);
//                //獲取輸入流 CommonsMultipartFile 中可以直接得到檔案的流
//                InputStream is=multipartFile.getInputStream();
//                byte[] buffer= new byte[1024];
//                int len = is.read(buffer);
//                while(len!=-1){
//                    os.write(buffer, 0, len);
//                }
//                os.flush();
//                os.close();
//                is.close();
//            } catch (FileNotFoundException e) {
//                // TODO Auto-generated catch block
//                e.printStackTrace();
//            }

        }

        //可以用ModelMap或者request請求域來返回上傳路徑
        //modelMap.addAttribute("fileUrl", path); 
        //或者request.setAttribute("fileUrl",path);
        return "success";
    }

    //上傳成功頁面
    @RequestMapping("/uploadpage")
    public String uploadpage(){
        return  "upload";
    }
}

第二種,單檔案上傳,利用MultipartHttpServletRequest來解析request中的檔案

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;

/**
 * @author: ***
 * @date:2018/9/18 16:01
 * @description:
 */
@Controller
@RequestMapping("/test")
public class UploadController {

    @RequestMapping("/upload")
    public ModelMap upload(HttpServletRequest request, ModelMap model) {
        // 先例項化一個檔案解析器
        CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());

        // 判斷request請求中是否有檔案上傳
        if (commonsMultipartResolver.isMultipart(request)) {
            // 轉換request
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            // 獲得檔案
            MultipartFile file = multiRequest.getFile("file");
            if (!file.isEmpty()) {
                //上傳路徑
                String path = "D:/test/"+file.getOriginalFilename();
                // 建立檔案例項
                File tempFile = new File(path);
                if (!tempFile.exists()) {
                    tempFile.mkdir();
                }
                try {
                    //同樣可以用流檔案方式上傳檔案
                    file.transferTo(tempFile);
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //返回上傳路徑,方法一
                model.addAttribute("fileUrl", path);
                // 方法二:Request域屬性
                // request.setAttribute("fileUrl", path);
            }
        }
        return model;
    }
}

第三種是多檔案上傳,傳入引數是陣列或者request,多檔案只是需要將上傳的單個檔案從陣列或者request中遍歷出來,然後進行單檔案上傳操作。

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: ***
 * @date:2018/9/18 16:01
 * @description:
 */
@Controller
@RequestMapping("/test")
public class UploadController {

    /**
     * 多檔案上傳,方式一:利用MultipartFile[]作為方法的引數接收傳入的檔案
     *  用 transferTo方法來儲存圖片,儲存到本地磁碟。
     * @author chunlynn
     */
    @RequestMapping("/upload")
    public ModelMap upload3(@RequestParam("file") MultipartFile[] files, ModelMap model) {
        List<String> fileUrlList = new ArrayList<String>(); //用來儲存檔案路徑
        // 先判斷檔案files不為空
        if (files != null && files.length > 0) {
            for (MultipartFile file : files) { //迴圈遍歷取出單個檔案
                if (!file.isEmpty()) {
                    String fileName = file.getOriginalFilename();
                    String path = "D:/test/"+fileName;      //這裡D:/test/可以修改為自己的路徑,也可以對fileName進行修改。
                    // 建立檔案例項
                    File tempFile = new File(path);
                    //判斷父級資料夾是否存在
                    if (!tempFile.getParentFile().exists()) {
                        tempFile.getParentFile().mkdir();
                    }
                    if (!tempFile.exists()) {
                        tempFile.mkdir();
                    }
                    try {
                        //這裡也可以用流實現
                        file.transferTo(tempFile);
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    fileUrlList.add(path);
                }
            }
            // 方法一:model屬性儲存圖片路徑
            model.addAttribute("fileUrlList", fileUrlList);
            // 方法二:request域屬性儲存圖片路徑
            // request.setAttribute("fileUrlList", fileUrlList);
        }
        return model;
    }



    /**
     * 多檔案上傳,方式二:利用MultipartHttpServletRequest來解析Request中的檔案
     */
    @RequestMapping("/upload2")
    public ModelMap upload2(HttpServletRequest request,ModelMap model) {
        List<String> fileUrlList = new ArrayList<>(); //用來儲存檔案路徑
        // 先例項化一個檔案解析器
        CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        // 判斷request請求中是否有檔案上傳
        if (commonsMultipartResolver.isMultipart(request)) {
            // 轉換Request
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            // 獲得檔案,方式一
            List<MultipartFile> files = multiRequest.getFiles("file"); 
            for (MultipartFile file : files) { //迴圈遍歷取出單個檔案上傳
                if (!file.isEmpty()) {
                    // 獲得原始檔名,拼接需要上傳的位置得到路徑
                    String fileName = file.getOriginalFilename();
                    String path = "D:/test/"+fileName;

                    // 建立檔案例項
                    File tempFile = new File(path); //檔案儲存路徑為pathRoot + path
                    if (!tempFile.getParentFile().exists()) {
                        tempFile.getParentFile().mkdir();
                    }
                    if (!tempFile.exists()) {
                        tempFile.mkdir();
                    }
                    try {
                        //也可用流的方式上傳
                        file.transferTo(tempFile);
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    fileUrlList.add(path);
                }
            }
            model.addAttribute("fileUrlList", fileUrlList); 
            // 方法二:request域屬性儲存
            // request.setAttribute("fileUrlList", fileUrlList);
        }
        return model;
    }
}

檔案下載,在這裡我是寫死了檔案的下載路徑和下載檔名的,實際專案中,這兩個欄位下載路徑一般會配置在配置檔案中,下載檔案的名稱則是前臺通過request傳遞到後臺的,所以這個可以將這兩個欄位作為傳入引數,寫成介面。

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

/**
 * @author: ***
 * @date:2018/9/18 16:01
 * @description:
 */
@Controller
@RequestMapping("/test")
public class UploadController {

    /**
     * 檔案下載功能
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping("/down")
    public void down(HttpServletRequest request,HttpServletResponse response) throws Exception{
        String downloadpath = "D:/test/";       //這是你儲存你需要下載的檔案所在的位置的路徑
        //test.txt為需要下載的檔案的全檔名
        String fileName = "test.txt";
        String path = downloadpath+fileName;
        //獲取輸入流
        InputStream is = new BufferedInputStream(new FileInputStream(new File(path)));

        //這裡是下載檔案的時候,如果你對下載檔案重新命名的名字
        String filename = "下載檔案.txt";
        //轉碼,防止檔名中文亂碼
        filename = URLEncoder.encode(filename,"UTF-8");
        //設定檔案下載頭
        response.addHeader("Content-Disposition", "attachment;filename=" + filename);
        //1.設定檔案ContentType型別,這樣設定,會自動判斷下載檔案型別
        response.setContentType("multipart/form-data");
        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        int len = is.read();
        while((len!= -1){
            out.write(len);
            out.flush();
        }
        out.close();
    }

}

3.頁面

upload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>檔案上傳頁</title>
</head>
<body>
    <form action="/mvc/test/upload" method="post" enctype="multipart/form-data">
        <label>上傳檔案</label>
        <input type="file" name="file">
        <input type="submit" value="提交">
    </form>
</body>
</html>

注意,form表單裡,enctype="multipart/form-data",一定要配置。action是你方法的訪問路徑,由於我在tomcat中配置了專案訪問名稱是mvc,所以我這裡的路徑會是“/mvc/test/upload”,具體路徑由個人的配置而定。

還有個上傳成功的提示頁,自己寫一個就行,不貼程式碼了。