Spring MVC----文件上傳

前端配置

  普通的form表單圖片上傳

  僅支持post請求javascript

    <form action="/website/realAuthUpload.do" enctype="multipart/form-data" method="post">
        <input type="file" name="file">
        <input type="submit">
    </form>

 

  使用dropzone框架

  dropzone CDN   https://www.bootcdn.cn/dropzone/css

<link href="https://cdn.bootcss.com/dropzone/5.5.1/min/basic.min.css" rel="stylesheet">
<link href="https://cdn.bootcss.com/dropzone/5.5.1/min/dropzone.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/dropzone/5.5.1/min/dropzone.min.js"></script>

或者去官網下載(dist文件)html

  介紹

  它是輕量級的,不依賴於任何其餘庫(如jQuery),而且是高度可定製的前端

  使用Dropzone

  只須要一個 div 元素,用 JavaScript 代碼啓用便可java

  html結構web

<div id="dropz" class="dropzone"></div> 

  JavaScript 啓用代碼以下:spring

var myDropzone = new Dropzone("#dropz", {
    url: "/upload",
    dictDefaultMessage: '拖動文件至此或者點擊上傳', // 設置默認的提示語句
    paramName: "dropzFile", // 傳到後臺的參數名稱
    init: function () {
        this.on("success", function (file, data) {
            // 上傳成功觸發的事件,若是須要獲取data數據,後端必須返回一個標準的json數據。
        });
    }
});

  其中 url 是必須的值,指明文件上傳提交到哪一個頁面。其餘的值都是可選的,若是使用默認值的話能夠省略json

  詳細配置 Dropzone

    功能選項

  • url:最重要的參數,指明瞭文件提交到哪一個頁面
  • method:默認爲 post,若是須要,能夠改成 put
  • paramName:至關於 <input> 元素的 name 屬性,默認爲 file
  • maxFilesize:最大文件大小,單位是 MB
  • maxFiles:默認爲 null,能夠指定爲一個數值,限制最多文件數量
  • addRemoveLinks:默認 false。若是設爲 true,則會給文件添加一個刪除連接
  • acceptedFiles:指明容許上傳的文件類型,格式是逗號分隔的 MIME type 或者擴展名。例如:image/*, application/pdf, .psd, .obj
  • uploadMultiple:指明是否容許 Dropzone 一次提交多個文件。默認爲 false。若是設爲 true,則至關於 HTML 表單添加 multiple 屬性
  • headers:若是設定,則會做爲額外的 header 信息發送到服務器。例如:{"custom-header": "value"}
  • init:一個函數,在 Dropzone 初始化的時候調用,能夠用來添加本身的事件監聽器
  • forceFallback:Fallback 是一種機制,當瀏覽器不支持此插件時,提供一個備選方案。默認爲 false。若是設爲 true,則強制 fallback
  • fallback:一個函數,若是瀏覽器不支持此插件則調用

    翻譯選項

  • dictDefaultMessage:沒有任何文件被添加的時候的提示文本
  • dictFallbackMessage:Fallback 狀況下的提示文本
  • dictInvalidInputType:文件類型被拒絕時的提示文本
  • dictFileTooBig:文件大小過大時的提示文本
  • dictCancelUpload:取消上傳連接的文本
  • dictCancelUploadConfirmation:取消上傳確認信息的文本
  • dictRemoveFile:移除文件連接的文本
  • dictMaxFilesExceeded:超過最大文件數量的提示文本

    經常使用事件

      如下事件接收 file 爲第一個參數

  • addedfile:添加了一個文件時發生
  • removedfile:一個文件被移除時發生。你能夠監聽這個事件並手動從服務器刪除這個文件
  • uploadprogress:上傳時按必定間隔發生這個事件。第二個參數爲一個整數,表示進度,從 0 到 100。第三個參數是一個整數,表示發送到服務器的字節數。當一個上傳結束時,Dropzone 保證會把進度設爲 100。注意:這個函數可能被以同一個進度調用屢次
  • success:文件成功上傳以後發生,第二個參數爲服務器響應
  • complete:當文件上傳成功或失敗以後發生
  • canceled:當文件在上傳時被取消的時候發生
  • maxfilesreached:當文件數量達到最大時發生
  • maxfilesexceeded:當文件數量超過限制時發生

      如下事件接收一個 file list 做爲第一個參數(僅當 uploadMultiple 被設爲 true 時纔會發生)

  • successmultiple
  • completemultiple
  • cancelmultiple

      特殊事件

  • totaluploadprogress:第一個參數爲總上傳進度,第二個參數爲總字節數,第三個參數爲總上傳字節數。

    使用案例

var myDropzone = new Dropzone("#dropz", {
    url: "/upload", // 文件提交地址
    method: "post",  // 也可用put
    paramName: "file", // 默認爲file
    maxFiles: 1,// 一次性上傳的文件數量上限
    maxFilesize: 2, // 文件大小,單位:MB
    acceptedFiles: ".jpg,.gif,.png,.jpeg", // 上傳的類型
    addRemoveLinks: true,
    parallelUploads: 1,// 一次上傳的文件數量
    //previewsContainer:"#preview", // 上傳圖片的預覽窗口
    dictDefaultMessage: '拖動文件至此或者點擊上傳',
    dictMaxFilesExceeded: "您最多隻能上傳1個文件!",
    dictResponseError: '文件上傳失敗!',
    dictInvalidFileType: "文件類型只能是*.jpg,*.gif,*.png,*.jpeg。",
    dictFallbackMessage: "瀏覽器不受支持",
    dictFileTooBig: "文件過大上傳文件最大支持.",
    dictRemoveLinks: "刪除",
    dictCancelUpload: "取消",
    init: function () {
        this.on("addedfile", function (file) {
            // 上傳文件時觸發的事件
        });
        this.on("success", function (file, data) {
            // 上傳成功觸發的事件
        });
        this.on("error", function (file, data) {
            // 上傳失敗觸發的事件
        });
        this.on("removedfile", function (file) {
            // 刪除文件時觸發的方法
        });
    }
});

  

  使用uploadify框架

  說明

    http://www.uploadify.com/bootstrap

    Flash Version:須要瀏覽器安裝flash插件後端

    Html5 Version:須要收費

 

 

  Options

    auto:是否當圖片選中後,直接上傳(默認是ture)

    buttonClass:按鈕的樣式(能夠本身直接設置)

    buttonCursor:鼠標放到按鈕上的樣式

    buttonImage :按鈕的圖片,能夠將按鈕的樣式變成一個圖片

    buttonText:按鈕的文字

    debug:flash是不經過瀏覽器進行請求的,因此須要dubug須要單獨的建立窗口debug

    fileObjName :至關於<input type="file" name="xxx">中的xxx

    fileSizeLimit:控制文件上傳大小

    fileTypeDesc:文件類型提示描述;

    fileTypeExts:控制文件類型

    formData:額外的上傳的數據

    height:按鈕高度

    width:寬度

    multi:能夠上傳多個文件(默認是false)

    overrideEvents:表示我須要覆蓋你的那些事件,或者我不須要你的那些事件

    swf:指向 uploadify 的文件

    uploader 後臺處理請求的url

 

  基本使用

<div>
	<div>
		<a href="javascript:;" id="uploadBtn1" >上傳正面</a>
	</div>
<!--爲了圖片回顯 src是服務器圖片的路徑地址-->
	<img alt="" src="" class="uploadImg" id="uploadImg1"/>
<!--爲了顯示圖片的地址-->
	<input type="hidden" name="image1" id="uploadImage1"/>
</div>

  一、回顯圖片的目的是讓用戶能夠在頁面上能夠看到本身上傳的圖片

  二、頁面上隱藏一個地址,是爲了在提交表單,Controller處理表單能夠拿到用戶上傳的圖片的服務器地址。

        //把上傳身份證正面的a標籤變成一個uploadify的組件
        $("#uploadBtn1").uploadify({
            buttonText: "身份證正面",
            fileObjName: "file",
            fileTypeDesc: "身份證正面圖片",
            fileTypeExts: "*.gif; *.jpg; *.png",
            multi: false,
            swf: "static/js/plugins/uploadify/uploadify.swf",
            uploader: "/realAuthUpload.do",
            overrideEvents: ["onUploadSuccess", "onSelect"],
            onUploadSuccess: function (file, data) {
                $("#uploadImg1").attr("src", data);  //上傳圖片成功後顯示圖片
                $("#uploadImage1").val(data);        //上傳圖片成功後將圖片地址放到form表單中,等待和表單一塊兒提交
            }
        });  

 

 

後端配置

  POM

  咱們可使用commons-fileupload:commons-fileupload包中的FileUtils來加快咱們處理上傳文件

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.2</version>
</dependency>

  配置 spring-mvc.xml

  須要 Spring 注入 multipartResolver 實例,spring-mvc.xml 增長以下配置:

<!-- 上傳文件攔截,設置最大上傳文件大小 10M = 10*1024*1024(B) = 10485760 bytes -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="10485760"/>
</bean>

  控制器關鍵代碼(示例)

package com.funtl.my.shop.web.admin.web.controller;

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

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 文件上傳控制器
 * <p>Title: UploadController</p>
 * <p>Description: </p>
 *
 * @author Lusifer
 * @version 1.0.0
 * @date 2018/6/27 0:42
 */
@Controller
public class UploadController {

    @ResponseBody
    @RequestMapping(value = "upload", method = RequestMethod.POST)
    public Map<String, Object> upload(MultipartFile dropzFile, HttpServletRequest request) {
        Map<String, Object> result = new HashMap<>();

        // 獲取上傳的原始文件名
        String fileName = dropzFile.getOriginalFilename();
        // 設置文件上傳路徑
        String filePath = request.getSession().getServletContext().getRealPath("/static/upload");
        // 獲取文件後綴
        String fileSuffix = fileName.substring(fileName.lastIndexOf("."), fileName.length());

        // 判斷並建立上傳用的文件夾
        File file = new File(filePath);
        if (!file.exists()) {
            file.mkdir();
        }
        // 從新設置文件名爲 UUID,以確保惟一
        file = new File(filePath, UUID.randomUUID() + fileSuffix);

        try {
            // 寫入文件
            dropzFile.transferTo(file);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 返回 JSON 數據,這裏只帶入了文件名
        result.put("fileName", file.getName());

        return result;
    }
}

  下面是實際開發中使用的代碼

    @Autowired
    private ServletContext servletContext;
	/**
	 * 千萬不要加requiredLogin
	 */
    @ResponseBody
	@PostMapping("realAuthUpload")
	public String realAuthUpload(MultipartFile file) {
		// 先獲得basepath
		String basePath = servletContext.getRealPath("/upload");
		String fileName = UploadUtil.upload(file, basePath);
		return "/upload/" + fileName;
	}
  UploadUtil
/**
 * 上傳工具
 *
 * @author Administrator
 */
public class UploadUtil {
    /**
     * 處理文件上傳
     *
     * @param basePath 存放文件的目錄的絕對路徑 servletContext.getRealPath("/upload")
     */
    public static String upload(MultipartFile file, String basePath) {
        String orgFileName = file.getOriginalFilename();
        //FilenameUtils.getExtension(orgFileName)獲得文件的擴展名字
        String fileName = UUID.randomUUID().toString() + "."
                + FilenameUtils.getExtension(orgFileName);
        try {
            File targetFile = new File(basePath, fileName);
            FileUtils.writeByteArrayToFile(targetFile, file.getBytes());

            //把文件同步到公共文件夾
            //File publicFile=new File(BidConst.PUBLIC_IMG_SHARE_PATH,fileName);
            //FileUtils.writeByteArrayToFile(publicFile, file.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileName;
    }
}

  若是不使用FileUtils

    @RequestMapping(value = "/fileupload",method = RequestMethod.POST)
    public String fileupload(MultipartFile file,HttpServletRequest httpServletRequest) throws IOException {
        //獲取文件的名字
        String originalFilename = file.getOriginalFilename();
        InputStream inputStream = file.getInputStream();
        String path = httpServletRequest.getSession().getServletContext().getRealPath("/")+originalFilename;
        FileOutputStream fileOutputStream = new FileOutputStream(path,true);
        int len=-1;
        byte[] bytes = new byte[1024];
        while ((inputStream.read(bytes))!=-1){
            fileOutputStream.write(bytes);
        }
        fileOutputStream.close();
        inputStream.close();
        return "login";
    }
相關文章
相關標籤/搜索