Java上传图片文件到服务器,包括单文件、多文件,兼容IE8、9

关于项目:
    后端采用SpringMVC框架,前端用到jQuery-1.9.1-min.js、jquery.form.js,可以满足同时上传多个文本内容和多个文件,上传速度快,并且兼容IE8、9,Chrome等主流浏览器。

需求背景:
   需要上传多条商品记录,每条记录包含多个文本说明和一个图片文件。

前期思考
   上传图片到服务器有两种做法,
   一、是把图片转换为Base64字符串,与文本信息一同通过json形式传给后台,后台解析保存图片。
   二、利用MultipartFile实现多文件上传
   显而易见,转为Base64后图片体积会变大,当上传多张图片时,速度特别缓慢。因此此处讲述的是利用MultipartFile实现多文件上传。
   但不管是哪种方式上传图片,我们都是把图片保存入服务器的指定路径,最终存入数据库的只是图片文件的保存路径,而不是图片本身。

一、前端实现

1、用FormData上传(不兼容IE8)

<form id="uploadForm" method="post" enctype="multipart/form-data”>
<table>
<tr>
	    <input type="text" id="text1" name="text"/>
		<input type="file" id="file1" name="file"/>
	    <input type="text" id="text2" name="text"/>
		<input type="file" id="file2" name="file"/>
	    <input type="text" id="text3" name="text"/>
		<input type="file" id="file3" name="file"/> 
	  	<input type="button" id="submit" value="上传" onclick="uploadSubmit()">
</tr>
 </table>
</form>
<script>
	function uploadSubmit(){
    
    
  		var formData = new FormData(document.getElementById('uploadForm'));
  		$.ajax({
    
    
  			url:"uploadFiles",
  			type:"post",
  			data:formData,
  			dataType:"json",
  			processData:false,//必须要写
  			contentType:false,//必须要写
  			success:function(result){
    
    
  				console.log(result);
  			}
  		});
	}
</script>

    这里演示一个文本框对应一个图片文件的示例,可以根据实际需求改动。多文件时,建议name属性一致,后端可以根据相同的name属性获取文件列表

注意:
    1、new FormData(document.getElementById(‘uploadForm’) )不能写成new FormData($(“#uploadForm”)) ,jQuery和原生节点在这有所差别。
    2、ajax上传时:一定要设置processData:false ,contentType:false,否则会报错:Illegal invocation

2、用jquery.form.js的ajaxSubmit上传(可兼容IE8)

    由于FormData+ajax的方式并不兼容IE8,故此使用jquery.form方式。只需要引入jquery.form.js文件后,修改 uploadSubmit() 方法

function uploadSubmit(){
    
    
	$("#uploadForm").ajaxSubmit({
    
    
	  	url:"uploadFiles",
	  	type:"post",
	  	dataType:"json",
	  	async:false,
	  	success:function(result){
    
    
	  		console.info(result);
	  	}
	  });
 }

    但是当使用ajaxSubmit上传文件,后台返回json数据时,IE8会提示要下载json文件。
    解决办法:后端不返回’application/json’类型数据,而改返回’text/html’类型给前端。注意把ajax的’dataType:json’属性去掉。

二、后端实现

    后端使用到MultipartFile需要添加commons-io.jar、commons-fileupload.jar依赖,否则取值为null
    并在applicationContext.xml文件进行注册:

<!-- ======================注册文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<!-- 文件上传大小限制 -->
	<property name="maxUploadSize">
		<value>10485760</value>
	</property>
	<property name="defaultEncoding">
		<value>UTF-8</value>
	</property>
</bean>

1、单文件上传

@ResponseBody
@RequestMapping("/uploadFiles")
public String uploadFiles(MultipartFile file,String text,HttpServletRequest request){
    
    
	try {
    
    
		//图片保存路径:/tomcat/webapps/项目名/
		String 	sysPath=request.getSession().getServletContext().getRealPath("");
		if(file!=null){
    
    
				//此处是将文本+图片原文件名作为图片的新文件名
				String fileName=text+file.getOriginalFilename();
				File filePath=new File(sysPath,fileName);
				if(!filePath.getParentFile().exists()){
    
    
					filePath.getParentFile().mkdirs();
				}
				//System.out.println("文件名:"+fileName+" ----- "+filePath.getPath());
				BufferedOutputStream out=new BufferedOutputStream(new 	FileOutputStream(filePath));
				out.write(image.getBytes());
				out.flush();
				out.close();
		}else{
    
    
			return "no file";
		}
	} catch (FileNotFoundException e) {
    
    
		
	}catch(IOException e){
    
    
		
	}
	return "success";
}

2、多文件上传

@ResponseBody
@RequestMapping("/uploadFiles")
public String uploadFiles(MultipartFile[] file,String[] text,HttpServletRequest request){
    
    
	try {
    
    
		//图片保存路径:/tomcat/webapps/项目名/
		String 	sysPath=request.getSession().getServletContext().getRealPath("");
		if(file!=null&&file.length>0){
    
    
			for(int i=0;i<file.length;i++){
    
    
				MultipartFile image=file[i];
				//此处是将文本+图片原文件名作为图片的新文件名
				String fileName=text[i]+image.getOriginalFilename();
				File filePath=new File(sysPath,fileName);
				if(!filePath.getParentFile().exists()){
    
    
					filePath.getParentFile().mkdirs();
				}
				System.out.println("文件名:"+fileName+" ----- "+filePath.getPath());
				BufferedOutputStream out=new BufferedOutputStream(new 	FileOutputStream(filePath));
				out.write(image.getBytes());
				out.flush();
				out.close();
			}
		}else{
    
    
			return "failure";
		}
	} catch (FileNotFoundException e) {
    
    
		
	}catch(IOException e){
    
    
		
	}
	return "success";
}

注意:
    1、按照上述文件保存路径是:/tomcat/webapps/项目名/test.jsp ,那么当tomcat服务器重启后,图片将会被清除。因为tomcat重启会重新部署应用。因此建议换一个文件保存路径。
    2、当前端没选择文件时(也就是空文件),IE8、9后台接收数据和chrome、IE11等其他浏览器表现不同,会把空文件计入个数,其他浏览器则只会接受非空文件。
    因此,后台使用multipartFile.isEmpty( )判断文件是否为空。

    自此,文件上传的模块就结束啦。走过很多弯路,之前为了兼容IE8,考虑用base64上传文件,速度非常之慢。但也算是吃一堑长一智。具体用base64怎么上传图片,有空再贴出来吧~

猜你喜欢

转载自blog.csdn.net/qq_38118138/article/details/118088539