Struts2系列:(11)文件上传
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Struts2系列:(11)文件上传相关的知识,希望对你有一定的参考价值。
生活赋予我们一种巨大的和无限高贵的礼品,这就是青春:充满着力量,充满着期待,充满着求知,充满着希望。
Struts 2使用FileUpload 拦截器和 Commons FileUpload 组件实现文件上传.
FileUploadInterceptor 全名:org.apache.struts2.interceptor.FileUploadInterceptor Interceptor that is based off(基于) of MultiPartRequestWrapper, which is automatically applied for any request that includes a file. It adds the following parameters, where [File Name] is the name given to the file uploaded by the html form: [File Name] : File - the actual File [File Name]ContentType : String - the content type of the file [File Name]FileName : String - the actual name of the file uploaded (not the HTML name) You can get access to these files by merely providing setters in your action that correspond to any of the three patterns above, such as setDocument(File document), setDocumentContentType(String contentType), etc.
在JSP中使用 HTML 表单上传文件, 须把 HTML 表单的 enctype 属性设置为 multipart/form-data, method 属性设置为 post。HTML表单中包含<input type=“file”> 使用户能选择上传文件。
基本步骤:
1. Jsp 页面form里使用file控件. 如一次上传多个须使用多个file控件, 控件的name属性必须是相同
2. Action 中添加三个文件上传相关的属性。
上传单个文件属性格式
属性一:类型为File,名字为页面file控件名
属性二:类型为String,名字为页面file控件名+ContentType
属性三:类型为String,名字为页面file控件名+FileName
上传多个文件属性格式
只需把属性类型换成使用数组或 List即可。
1、单个文件上传
1.1、单个文件上传的步骤
a)添加jar包
b)构建页面
c)建立Action
d)配置 验证出错跳转页面 <result name="input">/upload/error.jsp</result>。
a)添加jar包
添加commons-fileupload.jar、commons-io.jar
b)构建页面singlefile.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>上传一个文件</title> </head> <body> <form action="${pageContext.request.contextPath }/rk/fileupload/singlefileupload.action" method="post" enctype="multipart/form-data"> 请选择上传文件:<input type="file" name="uploadFile"/> <input type="submit" value="提交"/> </form> </body> </html>
c)建立Action
package com.rk.strut.f_fileupload; import java.io.File; import org.apache.commons.io.FileUtils; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class SingleFileUpload extends ActionSupport { private File uploadFile; private String uploadFileContentType; private String uploadFileFileName; public void setUploadFile(File uploadFile) { this.uploadFile = uploadFile; } public void setUploadFileContentType(String uploadFileContentType) { this.uploadFileContentType = uploadFileContentType; } public void setUploadFileFileName(String uploadFileFileName) { this.uploadFileFileName = uploadFileFileName; } @Override public String execute() throws Exception { System.out.println(uploadFileContentType); String realPath = ServletActionContext.getServletContext().getRealPath("/uploadfiles"); File folder = new File(realPath); if(folder.exists() == false) { folder.mkdirs(); } File destFile = new File(folder,uploadFileFileName); FileUtils.copyFile(uploadFile, destFile); return "success"; } }
d)配置 验证出错跳转页面 <result name="input">/upload/error.jsp</result>。
struts.xml中的配置
<package name="fileuploadPackage" namespace="/rk/fileupload" extends="struts-default"> <action name="singlefileupload" class="com.rk.strut.f_fileupload.SingleFileUpload"> <result name="success">/fileupload/success.jsp</result> <result name="input">/fileupload/error.jsp</result> </action> </package>
error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="/struts-tags" prefix="s" %> <!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>文件上传出错啦!</title> </head> <body> <s:fielderror/> </body> </html>
1.2、上传过程中可能出现的错误
a)当上传的文件超过2MB时,在MyEclipse的Console中会出现如下错误信息:
警告: Request exceeded size limit! org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (4411489) exceeds the configured maximum (2097152)
在文章最开头的时候 ,讲到“Struts 2使用FileUpload 拦截器和 Commons FileUpload 组件实现文件上传”,其过程是这样的:
第1步,文件借助Commons fileupload组件将文件上传到服务器的临时文件夹中,
第2步,在临时文件夹中上传成功的文件再由FileUpload拦截器进行过滤,如果符合FileUpload拦截器的条件,才正式保存到磁盘上。
这相当于两道门,只有通过这两道门,才能算是上传成功!
刚才的错误是commons fileupload组件这道门造成的,在struts2-core-2.jar的org/apache/struts2文件夹下有一个default.properties文件,里面定义了一个常量:(2097152 = 2*1024*1024,下面2097152的计算单位是byte,正好是2MB。)
struts.multipart.maxSize=2097152
这个值限定了commons fileupload组件上传文件的大小。
解决的方法是在struts.xml文件中,修改这一常量值:(52428800 = 50*1024*1024,50MB)
<constant name="struts.multipart.maxSize" value="52428800"/>
1.3、用FileUpload拦截器限制文件上传的大小和类型
FileUpload 拦截器负责处理文件上传操作, 是默认的 defaultStack 拦截器栈的一员.
FileUpload 拦截器有 3 个属性可以设置.
maximumSize: 上传文件的最大长度(以字节为单位), 默认值为 2 MB
allowedTypes: 允许上传文件的类型, 各类型之间以逗号分隔
allowedExtensions: 允许上传文件扩展名, 各扩展名之间以逗号分隔
Interceptor parameters:
maximumSize (optional) - the maximum size (in bytes) that the interceptor will allow a file reference to be set on the action. Note, this is not related to the various properties found in struts.properties. Default to approximately 2MB.
allowedTypes (optional) - a comma separated list of content types (ie: text/html) that the interceptor will allow a file reference to be set on the action. If none is specified allow all types to be uploaded.
allowedExtensions (optional) - a comma separated list of file extensions (ie: .html) that the interceptor will allow a file reference to be set on the action. If none is specified allow all extensions to be uploaded.
在action中配置FileUpload拦截器:
<action .....> <interceptor-ref name="defaultStack"> <param name="fileUpload.maximumSize">4097152</param> <param name="fileUpload.allowedTypes">application/msword,application/vnd.ms-excel</param> <param name="fileUpload.allowedExtensions">.doc,.docx,.xls,.pdf</param> </interceptor-ref> ..... </action>
在这里要比较一下两个参数:struts.multipart.maxSize和fileUpload.maximuSize
在1.2节中,我们谈到在Struts2中上传文件要经过两道门:commons fileupload组件和FileUpload拦截器。commons fileupload组件是第一道门,它对应的参数是struts.multipart.maxSize;FileUpload拦截器是第二道门,它对应的参数是fileUpload.maximuSize。fileUpload.maximuSize应该小于struts.multipart.maxSize才是合理的。
为什么要设置两个值呢?
这样做有一个好处就是:struts.multipart.maxSize可以做一个总的文件大小控制,而每一个Action的拦截器可以设置自己控制文件的大小。例如,上传附件的时候,可以限制文件小于10MB,上传照片的时候,可以限制图片小于1MB。
1.4、FileUpload拦截器的allowedTypes和allowedExtensions的进一步说明
有人遇到了文件类型过滤的问题,当allowedTypes和allowedExtensions都设置时,可能会出现某种类型的文件不能上传。
在网上有人进行了如下解释:
使用”文件类型“和”文件后缀名“两者中的一个来控制上传文件的类型/后缀名。但是,allowedTypes的优先级别高于allowedExtensions。
如果配置了allowedTypes则allowedExtensions将不再生效。
利用allowedExtensions参数来控制上传文件的后缀名,则不能配置allowedTypes参数。
否则,如果allowedTypes参数有配置,那么allowedExtensions参数将不会再起效。
建立只使用allowedExtensions参数
1.5、上传文件出错的处理
上面都是讲 文件如何上传、如何配置FileUpload拦截器限制文件大小和类型。
但是,当上传的文件不符合FileUpload拦截器限制的文件大小和类型时,就会出错误,我们应该把这些信息显示给用户,因此我们在struts.xml的action标签中配置了
<result name="input">/upload/error.jsp</result>
当出现错误的时候,跳转到error.jsp页面,而在error.jsp需要引入标签库
<%@taglib uri="/struts-tags" prefix="s" %>
页面中通过<s:fielderror/>就可以显示错误信息了。
出错情形:
文件大小超长
文件类型不符合allowedTypes, allowedExtensions 参数要求
方式一:直接使用struts-messages.properties 文件
struts-messages.properties 文件(在( struts2-core-2.x.x.x中的org.apache.struts2包下))预定义错误信息.
struts.messages.error.uploading=Error uploading: {0} struts.messages.error.file.too.large=File too large: {0} "{1}" "{2}" {3} struts.messages.error.content.type.not.allowed=Content-Type not allowed: {0} "{1}" "{2}" {3} struts.messages.error.file.extension.not.allowed=File extension not allowed: {0} "{1}" "{2}" {3}
{0}:上传控件名称(file控件名称)
{1}:上传文件名称
{2}:上传临时目录名称
{3}:上传文件类型(如果是struts.messages.error.file.too.large,则是上传文件的大小)
This interceptor will add several field errors, assuming that the action implements ValidationAware. These error messages are based on several i18n values stored in struts-messages.properties, a default i18n file processed for all i18n requests. You can override the text of these messages by providing text for the following keys:
struts.messages.error.uploading - a general error that occurs when the file could not be uploaded
struts.messages.error.file.too.large - occurs when the uploaded file is too large
struts.messages.error.content.type.not.allowed - occurs when the uploaded file does not match the expected content types specified
struts.messages.error.file.extension.not.allowed - occurs when the uploaded file does not match the expected file extensions specified
方式二:定义属性文件
第一步:创建资源文件,放在src下,并添加相关信息
例如:fileuploadresource.properties
struts.messages.error.uploading=\u6587\u4EF6\u4E0A\u4F20\u9519\u8BEF: {0} struts.messages.error.file.too.large=\u6587\u4EF6\u592A\u5927: {0} "{1}" "{2}" {3} struts.messages.error.content.type.not.allowed=Content-Type\u4E0D\u5141\u8BB8: {0} "{1}" "{2}" {3} struts.messages.error.file.extension.not.allowed=\u6269\u5C55\u540D\u4E0D\u5141\u8BB8\: {0} "{1}"
第二步:在struts.xml文件加载该资源文件
<constant name="struts.custom.i18n.resources" value="fileuploadresource"/>
2、多个文件上传
multifile.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>多个文件上传</title> </head> <body> <form action="${pageContext.request.contextPath }/rk/fileupload/multifileupload" method="post" enctype="multipart/form-data"> 请选择文件:<br/> <input type="file" name="uploadFile"/><br/> <input type="file" name="uploadFile"/><br/> <input type="file" name="uploadFile"/><br/> <input type="submit" value="提交"/> </form> </body> </html>
MultiFileUpload.java
package com.rk.strut.f_fileupload; import java.io.File; import org.apache.commons.io.FileUtils; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class MultiFileUpload extends ActionSupport { private File[] uploadFile; private String[] uploadFileContentType; private String[] uploadFileFileName; public void setUploadFile(File[] uploadFile) { this.uploadFile = uploadFile; } public void setUploadFileContentType(String[] uploadFileContentType) { this.uploadFileContentType = uploadFileContentType; } public void setUploadFileFileName(String[] uploadFileFileName) { this.uploadFileFileName = uploadFileFileName; } @Override public String execute() throws Exception { String basePath = ServletActionContext.getServletContext().getRealPath("/uploadfiles"); File folder = new File(basePath); if(folder.exists() == false) { folder.mkdirs(); } if(uploadFile != null && uploadFile.length>0) { for(int i=0;i<uploadFile.length;i++) { File destFile = new File(folder,uploadFileFileName[i]); FileUtils.copyFile(uploadFile[i], destFile); } } return "success"; } }
以上是关于Struts2系列:(11)文件上传的主要内容,如果未能解决你的问题,请参考以下文章