struts2---文件上传

本文详细介绍了Struts2框架中的文件上传机制,包括上传单个文件和多个文件的方法,以及如何通过拦截器对上传文件进行过滤。重点阐述了在servlet3.0之后,如何简化文件上传过程,使得通过request对象可以直接获取文件上传信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


传统文件上传主要步骤:
1.将form的enctype设置为multipart/form-data(这个时候不能通过request.getParameter来获取请求参数。
2.利用文件上传组件(common-fileupload)来获取请求参数,上传文件利用IO流来读取和写文件

在servlet3.0以后,只要增加一个@MultipartConfig来修饰servlet
就可以通过request.getParameter来获取请求参数
通过request.getPart来获取上传的文件


Struts2文件上传分三步:
1.需要导入commons-fileupload,commons-io包
2.form表单标签的enctype设置为"multipart/form-data
<s:form action="upload" enctype="multipart/form-data">
<s:textfield name="picName" label="图片名"></s:textfield>
<s:file name="pic" label="选择图片"/>	<br />
<s:submit value="上传"/>
</s:form>

3.action类中必须定义三个属性:
private File pic; //名称与上传文件域名name同名的,类型为File的field
private String picFileName; //名称为上传与名+FileName,类型为String的field
private String picContentType; //名称为上传名+ContentType,类型为String的field

之所以这样,是因为在文件上传拦截器中,代码中直接写死了:FileUploadInterceptor
public String intercept(ActionInvocation invocation) throws Exception {
...


// bind allowed Files
Enumeration fileParameterNames = multiWrapper.getFileParameterNames();
while (fileParameterNames != null && fileParameterNames.hasMoreElements()) {
// get the value of this input tag
String inputName = (String) fileParameterNames.nextElement();

// get the content type
String[] contentType = multiWrapper.getContentTypes(inputName);

if (isNonEmpty(contentType)) {
// get the name of the file from the input tag
String[] fileName = multiWrapper.getFileNames(inputName);

if (isNonEmpty(fileName)) {
// get a File object for the uploaded File
File[] files = multiWrapper.getFiles(inputName);
if (files != null && files.length > 0) {
List<File> acceptedFiles = new ArrayList<File>(files.length);
List<String> acceptedContentTypes = new ArrayList<String>(files.length);
List<String> acceptedFileNames = new ArrayList<String>(files.length);
String contentTypeName = inputName + "ContentType"; //picContentType
String fileNameName = inputName + "FileName";

...

if (!acceptedFiles.isEmpty()) {
Map<String, Object> params = ac.getParameters();
//添加三个属性,这三个属性必须在处理fileUpload的action中有定义,且有getter和setter方法
params.put(inputName, acceptedFiles.toArray(new File[acceptedFiles.size()]));
params.put(contentTypeName, acceptedContentTypes.toArray(new String[acceptedContentTypes.size()]));
params.put(fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()]));
}
}
} else {
...
} else {
...
}
}

// invoke action
return invocation.invoke();
}
上面是上传单个文件,上传多个文件比较类似:
也分成三步:
第一步:在WEB-INF/lib下加入commons-fileupload-1.2.1.jar、commons-io-1.3.2.jar。这两个文件可以从http://commons.apache.org/下载。
第二步:把form表的enctype设置为:“multipart/form-data“,如下:
<form enctype="multipart/form-data" action="${pageContext.request.contextPath}/xxx.action" method="post">
 			<input  type="file" name="uploadImages">
  			<input  type="file" name="uploadImages">  
		</form>


值得注意的是,多个file标签的name属性必须相同
第三步:在Action类中添加以下属性,属性红色部分对应于表单中文件字段的名称:
public class HelloWorldAction{
  		private File[] uploadImages;//得到上传的文件
 		 private String[] uploadImagesContentType;//得到文件的类型
 		 private String[] uploadImagesFileName;//得到文件的名称
  		//这里略省了属性的getter/setter方法
  		public String upload() throws Exception{
			String realpath = ServletActionContext.getServletContext().getRealPath("/images");
			File file = new File(realpath);
			if(!file.exists()) file.mkdirs();
			for(int i=0 ;i<uploadImages.length; i++){ File uploadImage = uploadImages[i];
    				FileUtils.copyFile(uploadImage, new File(file, uploadImagesFileName[i]));
			}
			return "success";
 		 }}



struts2文件上传拦截器

可对上传文件进行过滤,主要包括一次上传文件的总大小,上传文件的类型,上传文件后缀名限制等。
FileUploadInterceptor拦截器源码中定义的三个属性:
protected Long maximumSize;  //文件大小
    		protected Set<String> allowedTypesSet = Collections.emptySet(); //相对于allowedTypes
    		protected Set<String> allowedExtensionsSet = Collections.emptySet(); //相对于allowedExtensions


利用这三个属性,可以再struts.xml中配置fileUpload拦截器。因此为上传文件指定拦截器步骤如下:
1.在struts.xml中配置拦截器

源码中实现校验的部分:
	/**
     * Override for added functionality. Checks if the proposed file is acceptable based on contentType and size.
     *
     * @param action      - uploading action for message retrieval.
     * @param file        - proposed upload file.
     * @param contentType - contentType of the file.
     * @param inputName   - inputName of the file.
     * @param validation  - Non-null ValidationAware if the action implements ValidationAware, allowing for better
     *                    logging.
     * @return true if the proposed file is acceptable by contentType and size.
     */
    protected boolean acceptFile(Object action, File file, String filename, String contentType, String inputName, ValidationAware validation) {
        boolean fileIsAcceptable = false;

        // If it's null the upload failed
        if (file == null) {
            String errMsg = getTextMessage(action, "struts.messages.error.uploading", new String[]{inputName});
            if (validation != null) {
                validation.addFieldError(inputName, errMsg);
            }

            if (LOG.isWarnEnabled()) {
                LOG.warn(errMsg);
            }
        } else if (maximumSize != null && maximumSize < file.length()) {
            String errMsg = getTextMessage(action, "struts.messages.error.file.too.large", new String[]{inputName, filename, file.getName(), "" + file.length()});
            if (validation != null) {
                validation.addFieldError(inputName, errMsg);
            }

            if (LOG.isWarnEnabled()) {
                LOG.warn(errMsg);
            }
        } else if ((!allowedTypesSet.isEmpty()) && (!containsItem(allowedTypesSet, contentType))) {
            String errMsg = getTextMessage(action, "struts.messages.error.content.type.not.allowed", new String[]{inputName, filename, file.getName(), contentType});
            if (validation != null) {
                validation.addFieldError(inputName, errMsg);
            }

            if (LOG.isWarnEnabled()) {
                LOG.warn(errMsg);
            }
        } else if ((!allowedExtensionsSet.isEmpty()) && (!hasAllowedExtension(allowedExtensionsSet, filename))) {
            String errMsg = getTextMessage(action, "struts.messages.error.file.extension.not.allowed", new String[]{inputName, filename, file.getName(), contentType});
            if (validation != null) {
                validation.addFieldError(inputName, errMsg);
            }

            if (LOG.isWarnEnabled()) {
                LOG.warn(errMsg);
            }
        } else {
            fileIsAcceptable = true;
        }

        return fileIsAcceptable;
    }


2.拦截器拦截后,将返回一个input视图名,因此需要为此action配置一个result名为input的视图。
<result name="input">/jsp/result.jsp</result>
3.由于从上面的源码可以看出,拦截器将会先后对文件大小,文件类型,文件后缀类型进行校验。要是有错误,将会以addFieldError方式记录错误。filedName为上传文件域名
validation.addFieldError(inputName, errMsg);
其中的errMsg,可以从国际化资源属性文件获取,也可以使用默认错误提示信息。
国际化资源属性文件使用的属性名为:
struts.messages.error.file.too.large ----> maximumSize
struts.messages.error.content.type.not.allowed ----> allowedTypes
struts.messages.error.file.extension.not.allowed ----> allowedExtensions

因此可以使用国际化来自定义错误提示消息。

为了让strut2的web 应用自动加载国际化资源文件,需要在struts.xml中配置一个常量:
<constant name="struts.custom.i18n.resources" value="mess" /> <!-- value指定的内容为国际化属性名的baseName -->

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值