spring实现文件上传(图片解析)详解编程语言

合抱之木,生于毫末,千里之行,始于足下,要想了解spring的文件上传功能,首先要知道spring是通过流的方式将文件进行解析,然后上传。那么是不是所有需要用的文件上传的地方都要写一遍文件解析器呢?

放心,spring这个大管家已经为我们做好了一切!

我们只需要在spring的配置文件中加入下面代码:

 <!-- 文件上传解析器 --> 
    <bean id="multipartResolver" 
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver" 
        p:maxUploadSize="152400"  
        p:defaultEncoding="utf-8"> 
        <!-- <property name="defaultEncoding" value="utf-8"></property> --> 
    </bean> 
     
    <!-- SpringMVC在超出上传文件限制时,会抛出org.springframework.web.multipart.MaxUploadSizeExceededException -->   
    <!-- 该异常是SpringMVC在检查上传的文件信息时抛出来的,而且此时还没有进入到Controller方法中 -->   
    <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">   
        <property name="exceptionMappings">   
            <props>   
                <!-- 遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/jsp/error_fileupload.jsp页面 -->   
                <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">error_fileupload</prop>   
            </props>   
        </property>   
    </bean>

我们就不用再去在文件的解析上绞尽脑汁了,只需要专注于业务层面的逻辑就好了,是不是很简单?

接下来我们看一个小例子:

html前端代码:

<%@ page language="java" contentType="text/html; charset=UTF-8" 
    pageEncoding="UTF-8"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>Insert title here</title> 
</head> 
<body> 
 
<form action="<%=request.getContextPath()%>/user/add" method="post" enctype="multipart/form-data"> 
     
     
    <h1>新增用户</h1> 
     
    <table> 
        <tr> 
            <td>用户名:</td> 
            <td> 
                <input type="text" name="userName" value="${user.userName }" /> 
            </td> 
        </tr> 
        <tr> 
            <td>密码:</td> 
            <td> 
                <input type="text" name="password" value="${user.userPass }" /> 
            </td> 
        </tr> 
        <tr> 
            <td>头像:</td> 
            <td> 
                <input type="file" name="photo" /> 
            </td> 
        </tr> 
        <tr> 
            <td></td> 
            <td> 
                <input type="submit" value="上传" /> 
            </td> 
        </tr> 
    </table> 
</form> 
 
</body> 
</html>

大家有没有注意到以上代码的form表头中有一行代码:

enctype="multipart/form-data"

没错,想要上传二进制文件,该表头属性必不可少。
controller控制层代码:
package com.wskj.springmvc.controller; 
import java.io.File; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 
import javax.servlet.http.HttpServletRequest; 
import org.springframework.stereotype.Controller; 
import org.springframework.ui.Model; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.multipart.MultipartFile; 
import com.wskj.springmvc.pojo.UserInfo; 
@Controller 
@RequestMapping("/user") 
public class UserController { 
@RequestMapping(value="/add", method=RequestMethod.GET) 
public String addUser(){ 
return "user/add"; 
} 
@RequestMapping(value="/add", method=RequestMethod.POST) 
public String addUser(Model model, UserInfo user, @RequestParam(name="photo", required=false) MultipartFile photo, HttpServletRequest request) throws IOException{ 
//对文件进行处理 
//判断用户是否上传了文件 
//MultipartFile.getSize() : 获取文件的大小(字节:byte)  1024byte = 1kb   1024kb=1mb   GB  TB  PB 
if(photo.isEmpty() == false && photo.getSize() > 0){ 
//获取文件的名称 
String name = photo.getName();//photo 
String fileName = photo.getOriginalFilename();//mydata.jpg 
//获取文件扩展名 
String extension = fileName.substring(fileName.lastIndexOf(".")); 
byte[] data = photo.getBytes();//字节数组 
String contentType = photo.getContentType(); 
/** 
* 扩展名      Content-Type 
* .txt     text/plain 
* .jpg  image/jpeg 
* .mp3     audio/mp3 
* .mp4     video/mpeg4 
*/ 
photo.getInputStream();//获取文件输入流 
//保存到磁盘 
//保存的路径 
//不是 -》 F:/java/workspace/spring/springmvc_fileupload_20170401/WebContent/files 
//是 -》 x:/apache tomcat-7/webapps/appName/files 
String savedPath = request.getServletContext().getRealPath("files");//获取files目录的绝对路径 
String filePath = savedPath + "/" + fileName; 
//将文件写入磁盘 
photo.transferTo(new File(filePath)); 
//设置UserInfo.headerPhoto 
user.setHeaderPhotoUrl("files/"+fileName); 
model.addAttribute("headerUrl", user.getHeaderPhotoUrl()); 
} 
model.addAttribute("user", user); 
return "user/success"; 
} 
@RequestMapping(value="/add2", method=RequestMethod.GET) 
public String addUser2(){ 
return "user/add2"; 
} 
@RequestMapping(value="/add2", method=RequestMethod.POST) 
public String addUser2(Model model, UserInfo user, @RequestParam(name="photos", required=false) MultipartFile[] photos, HttpServletRequest request) throws IOException{ 
//对文件进行处理 
if(photos != null && photos.length>0){ 
List<String> photoUrls = new ArrayList<String>(); 
for(MultipartFile photo : photos){ 
//判断用户是否上传了文件 
//MultipartFile.getSize() : 获取文件的大小(字节:byte)  1024byte = 1kb   1024kb=1mb   GB  TB  PB 
if(photo.isEmpty() == false && photo.getSize() > 0){ 
//获取文件的名称 
String name = photo.getName();//photo 
String fileName = photo.getOriginalFilename();//mydata.jpg 
//获取文件扩展名 
String extension = fileName.substring(fileName.lastIndexOf(".")); 
byte[] data = photo.getBytes();//字节数组 
String contentType = photo.getContentType(); 
/** 
* 扩展名      Content-Type 
* .txt     text/plain 
* .jpg  image/jpeg 
* .mp3     audio/mp3 
* .mp4     video/mpeg4 
*/ 
photo.getInputStream();//获取文件输入流 
//保存到磁盘 
//保存的路径 
//不是 -》 F:/java/workspace/spring/springmvc_fileupload_20170401/WebContent/files 
//是 -》 x:/apache tomcat-7/webapps/appName/files 
String savedPath = request.getServletContext().getRealPath("files");//获取files目录的绝对路径 
String filePath = savedPath + "/" + fileName; 
//将文件写入磁盘 
photo.transferTo(new File(filePath)); 
//设置UserInfo.headerPhoto 
                     
photoUrls.add("files/"+fileName); 
} 
} 
model.addAttribute("headerUrl", photoUrls); 
} 
model.addAttribute("user", user); 
return "user/success2"; 
} 
}

后台根据前段的name属性接收参数,二进制文件类型为

MultipartFile,如果需要接收多个文件,只需要设置成集合然后遍历即可。
接下来是上传成功前段回显的jsp代码:
<%@ page language="java" contentType="text/html; charset=UTF-8" 
pageEncoding="UTF-8"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>Insert title here</title> 
</head> 
<body> 
<dl> 
<dt>用户名:</dt> 
<dd>${user.userName }</dd> 
<dt>头像:</dt> 
<dd> 
<img style="max-width:300px;max-height:200px;" src="<%=request.getContextPath() %>/${headerUrl}" /> 
</dd> 
</dl> 
</body> 
</html>

至此,最基础的文件上传测试成功。

spring实现文件上传(图片解析)详解编程语言

 

spring实现文件上传(图片解析)详解编程语言

 

但是,在实际项目中,我们可能只是需要启用一个div来进行文件的异步上传,这时我们可以使用html5的新特性formdata实现ajax的提交。

具体代码如下:

jsp前端代码:

<%@ page language="java" contentType="text/html; charset=UTF-8" 
pageEncoding="UTF-8"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>Insert title here</title> 
<script type="text/javascript" src="<%= request.getContextPath()%>/static/jquery-1.10.2.js"></script> 
<script type="text/javascript"> 
$(function(){ 
$("#btnupload").click(function(){ 
var formdata = new FormData(document.getElementById("form1"));//可以上传文件 
//var formdata = $("#form1").serializeArray();//无法上传文件的 
        alert(formdata); 
var url ="<%= request.getContextPath()%>/upload/demo1"; 
$.ajax({ 
url:url, 
data:formdata, //name=zhangsan&age=50   {} 
            contentType: false,//默认: "application/x-www-form-urlencoded" 
            processData: false,//设置 processData 选项为 false,防止自动转换数据格式 
            type:"post", 
dataType:"json", 
success:function(data){ 
alert(data); 
}, 
error:function(er){ 
alert(er.responseText); 
} 
}); 
}); 
}); 
</script> 
</head> 
<body> 
<h1>使用Html5提供的FormData实现ajax提交</h1> 
<h3>浏览器必须支持html5,如果是IE6 - IE8,那就洗洗睡吧...</h3> 
<form id="form1"> 
文件名:<input type="text" name="fileName" /> 
文件:<input type="file" name="myfile" /> 
<input id="btnupload" type="button" value="ajax上传文件" /> 
</form> 
</body> 
</html>

我们可以看见,只需要给要提交的form表单指定一个唯一标识id即可,是不是很方便?

后台controller接收代码:

package com.wskj.uploadfile.controller; 
import java.io.File; 
import java.io.IOException; 
import javax.servlet.http.HttpServletRequest; 
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; 
@Controller 
@RequestMapping("/upload") 
public class AjaxController { 
@RequestMapping(value="/demo1", method=RequestMethod.GET) 
public String demo1(){ 
return "upload/demo1"; 
} 
@RequestMapping(value="/demo1", method=RequestMethod.POST) 
@ResponseBody 
public boolean demo1(String fileName, MultipartFile myfile, HttpServletRequest request) throws IllegalStateException, IOException{ 
String path = request.getServletContext().getRealPath("files"); 
path += "/" + myfile.getOriginalFilename(); 
File file = new File(path); 
myfile.transferTo(file); 
System.out.println(fileName+" - 上传成功"); 
return true; 
} 
}

另外还可以使用jquery.form.js实现ajax的上传:

前段jsp代码:

<%@ page language="java" contentType="text/html; charset=UTF-8" 
pageEncoding="UTF-8"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>Insert title here</title> 
<script type="text/javascript" src="<%= request.getContextPath()%>/static/jquery-1.10.2.js"></script> 
<script type="text/javascript" src="<%= request.getContextPath()%>/static/jquery.form.js"></script> 
<script type="text/javascript"> 
$(function(){ 
$("#btnupload").click(function(){ 
var url ="<%= request.getContextPath()%>/upload/demo2"; 
$("#form1").ajaxSubmit({   
type:'post',   
url:url,   
clearForm:true,//清空所有表单元素的值 
            resetForm:true,//重置所有表单元素的值 
            success:function(data){   
alert(data);   
},   
error:function(XmlHttpRequest,textStatus,errorThrown){   
alert("上传失败了"); 
}   
});   
}); 
}); 
</script> 
</head> 
<body> 
<h1>使用jquery.form.js实现ajax文件上传</h1> 
<h3>对浏览器没有限制,尽情使用吧骚年们...</h3> 
<form id="form1"> 
文件名:<input type="text" name="fileName" value="我的头像" /> 
文件:<input type="file" name="myfile" /> 
<input id="btnupload" type="button" value="ajax上传文件" /> 
</form> 
</body> 
</html>

 

后台controller接收代码:

package com.wskj.uploadfile.controller; 
import java.io.File; 
import java.io.IOException; 
import javax.servlet.http.HttpServletRequest; 
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; 
@Controller 
@RequestMapping("/upload") 
public class AjaxController { 
 
@RequestMapping(value="/demo2", method=RequestMethod.GET) 
public String demo2(){ 
return "upload/demo2"; 
} 
@RequestMapping(value="/demo2", method=RequestMethod.POST) 
@ResponseBody 
public boolean demo2(String fileName, MultipartFile myfile, HttpServletRequest request) throws IllegalStateException, IOException{ 
String path = request.getServletContext().getRealPath("files"); 
path += "/" + myfile.getOriginalFilename(); 
File file = new File(path); 
myfile.transferTo(file); 
System.out.println(fileName+" - 上传成功"); 
return true; 
} 
}

当然,使用这两种方法也必须在spring中配置文件上传解析器,这个是上传二进制文件的前提。

 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/11487.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论