commons fileupload是当前比较流行和实用的文件上传组件,借助它的帮助,可以轻而易举的实现页面表单文件上传。
一。加入commons fileupload组件依赖
<!-- commons-fileupload dependencies --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>1.3.2</version> </dependency>
二。定义一个上传文件属性文件 file.properties
#为上传文件开辟的临时文件夹,用于存放临时文件 file.temp_repository=F://jetty-distribution-7.4.5.v20110725//temp #上传文件到服务器时,存放上传文件的文件夹 file.upload_repository=F://jetty-distribution-7.4.5.v20110725//upload #存放上传文件时,如果上传文件的大小大于该数值时,就将上传文件以 #临时文件的形式先存放到临时文件夹下。当进行文件上传时,上传的文 #件并不是直接就写到磁盘上的,而是先存放于内存当中,如果上传文件 #过大,那么内存就会不够用,这时就可以启用临时文件存放的形式。 file.size_threshold=10240 #单次上传时,上传的文件大小的最大值 file.size_max=50000000 #单个文件大小的最大值 file.file_size_max=5000000 #自定义的单次上传文件的最大个数 file.max_file_items_per_request=5 #自定义的上传文件的内容类型 file.allowed_content_type=jpg,gif,txt,zip,jpeg,pdf
三。uploadfile.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:property-placeholder location="classpath:file.properties"/> <bean id="diskFileItemFactory" class="org.apache.commons.fileupload.disk.DiskFileItemFactory"> <property name="repository" value="${file.temp_repository}"/> <property name="sizeThreshold" value="${file.size_threshold}"/> </bean> <bean id="fileUpload" class="org.apache.commons.fileupload.servlet.ServletFileUpload"> <property name="fileItemFactory" ref="diskFileItemFactory"/> <property name="sizeMax" value="${file.size_max}"/> <property name="fileSizeMax" value="${file.file_size_max}"/> </bean> <bean id="fileUploadHelper" class="com.dream.utils.FileUploadHelper"> <property name="servletFileUpload" ref="fileUpload"/> <property name="destination" value="${file.upload_repository}"/> <property name="maxFileItemsPerRequest" value="${file.max_file_items_per_request}"/> </bean> </beans>
四。自定义扩展的FileUploadHelper
package com.dream.utils; import com.dream.exception.OverMaxFileItemsException; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.util.Iterator; import java.util.List; /** * Created by IntelliJ IDEA. * User: Zhong Gang * Date: 11-8-16 * Time: 下午11:09 */ public class FileUploadHelper { private static final Integer DEFAULT_FILEITEMS_MAX_NUMBER = 0; private Logger logger = LoggerFactory.getLogger(getClass()); private ServletFileUpload servletFileUpload; private File destination; private Integer maxFileItemsPerRequest = DEFAULT_FILEITEMS_MAX_NUMBER; public void upload(HttpServletRequest request) throws Exception { List<FileItem> fileItems = servletFileUpload.parseRequest(request); removeFormFields(request, fileItems); int size = fileItems.size(); if (size > DEFAULT_FILEITEMS_MAX_NUMBER && size > maxFileItemsPerRequest) { throw new OverMaxFileItemsException(); } for (FileItem fileItem : fileItems) { if (!destination.exists()) { destination.mkdir(); } String name = fileItem.getName(); File file = new File(destination, name); fileItem.write(file); } } private void removeFormFields(HttpServletRequest request, List<FileItem> fileItems) { Iterator<FileItem> iterator = fileItems.iterator(); while (iterator.hasNext()) { FileItem fileItem = iterator.next(); if (fileItem.isFormField()) { String fieldName = fileItem.getFieldName(); String fieldValue = fileItem.getString(); request.setAttribute(fieldName, fieldValue); iterator.remove(); } } } public void setServletFileUpload(ServletFileUpload servletFileUpload) { this.servletFileUpload = servletFileUpload; } public void setDestination(File destination) { this.destination = destination; } public void setMaxFileItemsPerRequest(Integer maxFileItemsPerRequest) { this.maxFileItemsPerRequest = maxFileItemsPerRequest; } }
五。上传文件表单
<%-- Created by IntelliJ IDEA. User: ZhongGang Date: 11-8-15 Time: 下午10:34 --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>Photo form</title> <link href="/resources/css/main.css" rel="stylesheet" type="text/css" media="screen"/> </head> <body> <div id="wrapper"> <jsp:include page="../decorator/header.jsp"/> <div id="page"> <div> <form:form commandName="photo" enctype="multipart/form-data"> <table> <tr> <td>Name :</td> <td> <form:input path="name"/> </td> </tr> <tr> <td> Upload file: </td> <td> <input type="file" name="file"/> </td> </tr> <tr> <td>Description :</td> <td> <form:input path="description"/> </td> </tr> <tr> <td colspan="2"> <input type="submit" value="Submit"/> </td> </tr> </table> </form:form> </div> </div> <jsp:include page="../decorator/footer.jsp"/> </div> </body> </html>
附:1.表单提交必须是post方法,并且要加上enctype="multipart/form-data"。
2.当parseRequest方法处理请求过后,会返回一个FileItem的List,不论是表单上的文件域还是非文件域,都 会封闭成一个FileItem,要想获得非文件域的名称和值,可以使用getFieldName和getString方法。在这里我发
现,如果使用Spring提供的页面标签来绑定元素,是不起作用的,发现 以multipart/form-data与application/x-www-form-urlencoded的数据组织形式不一样,造成Spring无 法绑定。
以application/x-www-form-urlencoded形式发送的post数据结构:
以multipart/form-data形式发送的post数据结构: