Fork me on GitHub

SpringMVC文件上传功能

FormData上传

通过获取元素把文件放在虚拟化表单FormData中,然后用ajax提交表单.

前端

   $(function(){
      //文件上传控件,空间里类型不重要,重要的是控件要有onChange事件,这样才能实现文件上传获取图片web路径功能
      $('#file_upload').filebox({
          buttonText: '选择文件',   //按钮文本
          buttonAlign: 'right',   //按钮对齐
          //multiple: true,       //是否多文件
          accept: "image/gif,image/bmp,image/jpeg,image/jpg,image/png", //文件类型
          /*只要控件的图片改变,就自动上传图片,然后返回图片的web路径*/
          onChange: function (e) {
              
              //获取上传控件value,用于判断是否存在
              var value = $("#file_upload").filebox('getValue');
              //获取上传控件的file参数
              var files = $("#file_upload").next().find('input[type=file]')[0].files;
              //如果存在文件
              if (value && files[0]){
                //构造表单
                var formData = new FormData();
                //formData.enctype="multipart/form-data";
                //添加字符串参数
                formData.append("pathfolder",'img');
                //添加文件参数
                formData.append('file', files[0]);
              }
              
              //ajax上传文件文件form表单
              $.ajax({
                  url: '/${appName}/uploadController/upload', //单文件上传
                  type: 'POST',
                  //不序列化数据,直接使用data;发送 DOMDocument或不需要转换成查询字符串的数据,将此选项设置为false。
                  //默认:true,以对象形式上传的数据时将被转换为字符串来匹配contentType的默认值application/x-www-form-urlencoded,
                  processData: false,
                  //类型:Boolean或者String; 默认:'application/x-www-form-urlencoded;charset=UTF-8'
                  //只能设置为false,如果设为multipart/form-data,那么请求头contentType后面会缺少boundary=----部分
                  contentType: false,
                  data: formData,
                  success: function (json) {         
                    //转义JSON为对象
                    var data = $.parseJSON(json);
                    //将图片的web路径放到表单的隐藏input中
                    $('#logo_add').val(data.path);
                    //预览图片,每次更换都可预览
                    $("#img_preview").attr('src','/${appName}/'+decodeURIComponent(data.path));
                    //console.info(data);
                  },
                  error: function (xhr, status, error) {
                      $.messager.alert("提示", "操作失败"); //xhr.responseText
                  }
              });
          }
      });
   });

后端接口

package com.autumn.base.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jboss.logging.Param;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;


@Controller
@RequestMapping(value = "/uploadController", method = { RequestMethod.GET,RequestMethod.POST })
public class UploadController {
	
	/**
	 * 图片上传
	 * TODO
	 * @param file
	 * @param pathfolder
	 * @param req
	 * @param resp
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/upload", method = {RequestMethod.POST })
	public String Upload(@Param MultipartFile file,@Param String pathfolder,HttpServletRequest req, HttpServletResponse resp)throws Exception{
		req.setCharacterEncoding("utf-8");
		
                /*@Param参数无法引入,即jboss-logging-3.1.0.GA.jar没有引入时用原生request和org.springframework.web-3.1.1.RELEASE.jar中的MultipartHttpServletRequest获取两个参数
                List<MultipartFile> files = ((MultipartHttpServletRequest) req).getFiles("file");
                MultipartFile file = files.get(0);
                String pathfolder = req.getParameter("pathfolder");
                */

		if (file.isEmpty()) {
			String json = "{\"success\":false,\"message\":\"file is empty!\"}";
			resp.getOutputStream().write(json.getBytes("utf-8"));
		} else {
			Date time =new Date();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); 
			String dateNowStr = sdf.format(time);  
			//得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
			String folderPath = File.separator+"upload"+File.separator+pathfolder+File.separator+dateNowStr;
	        String savePath = req.getSession().getServletContext().getRealPath(folderPath);
	        File fileFolder = new File(savePath);
	        //判断上传文件的保存目录是否存在
	        if (!fileFolder.exists() && !fileFolder.isDirectory()) {
	            //创建目录
	            fileFolder.mkdirs();
	        }
	        //文件保存目录
	        String filesavepath = savePath+File.separator+file.getOriginalFilename();
	        
	        //IO流写入
			OutputStream outputStream=new FileOutputStream(filesavepath);
			InputStream inputStream = file.getInputStream();
		    //FileUtil.copyStream(inputStream, outputStream);
			byte[] bytes = new byte[1024];
			int len = 0;
			while((len = inputStream.read(bytes))!=-1){    //读取到文件末尾的话可以读到-1
				outputStream.write(bytes,0,len);
			}
			//flush输出流
		    outputStream.flush();
		    //关闭流文件
            inputStream.close();
            outputStream.close();
            
            //图片存储路径(web用)
			String webPath = folderPath+File.separator+file.getOriginalFilename();
			//因为URLEncoder.encode会把空格改为+号,要手动把加号改为%20
			webPath = URLEncoder.encode(webPath,"utf-8").replace("+", "%20");
			String json = "{\"success\":true,\"message\":\"文件上传成功!\",\"path\":\""+ webPath +"\"}";

			resp.resetBuffer();
			resp.setContentType("text/html;charset=UTF-8");
			resp.getOutputStream().write(json.getBytes("utf-8"));
			resp.getOutputStream().flush();
		}
		return null;
	}
}
posted @ 2020-09-08 14:49  秋夜雨巷  阅读(258)  评论(0编辑  收藏  举报