文件上传概述
- 要想使用 HTML 表单上传一个或多个文件, 必须把 HTML 表单的 enctype 属性设置为
multipart/form-data, 把它的 method 属性设置为 post - 为了让用户能够选择一个文件进行上传, 程序员必须提供一个
<input type=“file”>
字段.
Struts 对文件上传的支持
- 在 Struts 应用程序里, FileUpload 拦截器和 Jakarta Commons FileUpload
组件可以完成文件的上传. - 步骤:
- 在 Jsp 页面的文件上传表单里使用 file 标签. 如果需要一次上传多个文件, 就必须使用多个 file 标签,
但它们的名字必须是相同的 - 在 Action 中新添加 3 个和文件上传相关的属性. 这 3 个属性的名字必须是以下格式
- 在 Jsp 页面的文件上传表单里使用 file 标签. 如果需要一次上传多个文件, 就必须使用多个 file 标签,
private File uploadImage; //上传的文件
private String uploadImageContentType; //上传的文件的类型
private String uploadImageFileName; //上传文件的名称
-
uploadImage 是 jsp 页面上的 file 标签的名字.
上传文件:`<input type="file" name="uploadImage">`
- 如果是上传单个文件, uploadImage属性的类型就是 java.io.File, 它代表被上传的文件, 第二个和第三个属性的类型是
String, 它们分别代表上传文件的文件名和文件类型
定义方式是分别是jsp页面file组件的名称+ContentType,
jsp页面file组件的名称+FileName - 如果上上传多个文件, 可以使用数组或 List
单文件上传代码如下
第一步:在WEB-INF/lib下加入commons-fileupload-1.2.1.jar、commons-io-1.3.2.jar。这两个文件可以从http://commons.apache.org/下载。
第二步:把form表的enctype设置为:“multipart/form-data“,如下:
<%@ page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/upload/uploadAction_saveFile.action"
name="form1" method="post" enctype="multipart/form-data" >
上传文件名称:<input type="file" name="uploadImage">
<input type="submit" value="上传">
</form>
</body>
</html>
第三步:在Action类中添加以下属性,属性对应于表单中文件字段的名称:
package cn.itcast.upload;
import java.io.File;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class UploadAction extends ActionSupport {
/*
* 上传文件的存储的临时文件:
*
*/
private File uploadImage;
//上传文件的类型:text/plain
private String uploadImageContentType;
//上传文件的真是名称
private String uploadImageFileName;
public File getUploadImage() {
return uploadImage;
}
public void setUploadImage(File uploadImage) {
this.uploadImage = uploadImage;
}
public String getUploadImageContentType() {
return uploadImageContentType;
}
public void setUploadImageContentType(String uploadImageContentType) {
this.uploadImageContentType = uploadImageContentType;
}
public String getUploadImageFileName() {
return uploadImageFileName;
}
public void setUploadImageFileName(String uploadImageFileName) {
this.uploadImageFileName = uploadImageFileName;
}
public String saveFile(){
System.out.println("UploadAction *********** saveFile()");
ServletContext sc = ServletActionContext.getServletContext();
String path = sc.getRealPath("/fileupload");
File file = new File(path, uploadImageFileName);
try {
FileUtils.copyFile(uploadImage, file);
} catch (IOException e) {
e.printStackTrace();
}
uploadImage.delete();
return "success";
}
}
第四步:在struts_upload.xml文件中增加如下配置
<package name="upload" namespace="/upload" extends="struts-default" >
<!-- 单文件上传 -->
<action name="uploadAction_saveFile" class="cn.itcast.upload.UploadAction" method="saveFile">
<result name="success">/upload/success.jsp</result>
<!-- 定义验证出错要转向的页面 -->
<result name="input">/upload/error.jsp</result>
</action>
<package>
第五步:strtus.xml引入自定义配置文件
<include file="cn/itcast/upload/struts_upload.xml"></include>
测试上传.txt文件
File Upload 拦截器
- FileUpload 拦截器负责处理文件的上传操作, 它是默认的 defaultStack 拦截器栈的一员.
- FileUpload 拦截器有 3 个属性可以设置.
- maximumSize: 上传文件的最大长度(以字节为单位), 默认值为 2 MB
- allowedTypes: 允许上传文件的类型, 各类型之间以逗号分隔
- allowedExtensions: 允许上传文件扩展名, 各扩展名之间以逗号分隔
- 可以在 struts.xml 文件中覆盖这 3 个属性
- 若用户上传的文件大小大于给定的最大长度或其内容类型没有被列在 allowedTypes, allowedExtensions 参数里,
将会显示一条出错消息. 与文件上传有关的出错消息在
struts-messages.properties 文件里预定义. (org.apache.struts2包下) - 可以在文件上传 Action 相对应的资源文件中重新定义错误消息, 但需要在 struts.xml 文件中配置使用 action 的消息:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="upload" namespace="/upload" extends="struts-default">
<action name="uploadAction_saveFile" class="cn.itcast.upload.UploadAction" method="saveFile">
<result name="success">/upload/success.jsp</result>
<result name="input">/upload/error.jsp</result>
<!-- 配置拦截器的参数,这里是文件上传拦截器 -->
<interceptor-ref name="defaultStack">
<!--
配置文件上传拦截器的参数
* 与定义参数的顺序无关
* 允许的类型(allowedTypes)和允许的扩展名(allowedExtensions)必须保持一致
-->
<!--
* 配置上传文件的大小
* struts.xml文件中配置的是上传文件的总大小
* 这里配置的是上传文件的单个大小
-->
<param name="fileUpload.maximumSize">20971520</param>
<!-- 配置上传文件允许的类型,如果配置多个值的话,用","隔开 -->
<param name="fileUpload.allowedTypes">text/plain,application/octet-stream</param>
<!-- 配置上传文件的扩展名,如果配置多个值的话,用","隔开 -->
<param name="fileUpload.allowedExtensions">.txt,.rar</param>
</interceptor-ref>
</action>
<action name="uploadsAction_saveFiles" class="cn.itcast.upload.UploadsAction" method="saveFiles">
<result name="success">/upload/success.jsp</result>
<result name="input">/upload/error.jsp</result>
</action>
</package>
</struts>
在jsp页面显示错误信息
在struts.xml文件中根据
<result name=“input”>/upload/error.jsp</result>中所指向的error.jsp页面可以使用
<s:fielderror/>显示错误信息
查看struts-messages.properties文件
配置如下:
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}:<input type=“file” name=“uploadImage”>
中name属性的值
{1}:上传文件的名称
{2}:上传文件保存到临时目录的名称
{3}:上传文件的类型(对struts.messages.error.file.too.large是上传文件的大小)
修改显示错误的资源文件的信息
第一步:创建新的资源文件 例如fileuploadmessage.properties,放置在src下
在该资源文件中增加如下信息
第二步:在struts.xml文件加载该资源文件
<!-- 设置comonfileupload上传组件允许的文件大小 才能测试出上传文件过大出现的错误信息 -->
<constant name="struts.multipart.maxSize" value="86170804"/>
<!-- 配置上传文件的出错信息的资源文件 -->
<constant name="struts.custom.i18n.resources" value="fileuploadmessage“/>
测试上次不符合类型的文件:
测试过大的文件:
多文件上传代码
第一步:在WEB-INF/lib下加入commons-fileupload-1.2.1.jar、commons-io-1.3.2.jar。这两个文件可以从http://commons.apache.org/下载。
第二步:把form表的enctype设置为:“multipart/form-data“,如下:
<%@ page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/upload/uploadsAction_saveFiles.action"
name="form1" method="post" enctype="multipart/form-data" >
上传文件名称:<input type="file" name="uploadImages"><br>
上传文件名称:<input type="file" name="uploadImages"><br>
上传文件名称:<input type="file" name="uploadImages"><br>
<input type="submit" value="上传">
</form>
</body>
</html>
第三步:在Action类中添加以下属性,属性对应于表单中文件字段的名称:
package cn.itcast.upload;
import java.io.File;
import java.io.IOException;
import javax.servlet.ServletContext;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class UploadsAction extends ActionSupport {
private File [] uploadImages;
private String [] uploadImagesContentType;
private String [] uploadImagesFileName;
public String saveFiles(){
System.out.println("UploadsAction ******** saveFiles()");
ServletContext sc = ServletActionContext.getServletContext();
String path = sc.getRealPath("/fileupload");
for(int i=0;i<uploadImages.length;i++){
File file = new File(path, uploadImagesFileName[i]);
try {
FileUtils.copyFile(uploadImages[i], file);
} catch (IOException e) {
e.printStackTrace();
}
uploadImages[i].delete();
}
return "success";
}
public File[] getUploadImages() {
return uploadImages;
}
public void setUploadImages(File[] uploadImages) {
this.uploadImages = uploadImages;
}
public String[] getUploadImagesContentType() {
return uploadImagesContentType;
}
public void setUploadImagesContentType(String[] uploadImagesContentType) {
this.uploadImagesContentType = uploadImagesContentType;
}
public String[] getUploadImagesFileName() {
return uploadImagesFileName;
}
public void setUploadImagesFileName(String[] uploadImagesFileName) {
this.uploadImagesFileName = uploadImagesFileName;
}
}
测试:
总结
struts2框架的文件上传:
* 单文件上传:
* 在动作类action中声明相关属性:
* 在动作类action中,要声明与页面中表单name属性同名的属性,同名的属性的类型时File类型;
* 在动作类action中,要声明[同名的属性]ContentType,类型时String类型;
* 在动作类action中,要声明[同名的属性]FileName,类型时String类型
* 给所有属性提供get和set方法
* 在业务方法中,处理文件上传:
* 获取要上传文件的路径,保存的位置
* 在目标文件夹内,创建一个与上传文件同名的文件
* 通过FileUtils工具类提供copyFile()方法,将临时文件内容拷贝到目标文件夹下的那个同名的文件
* 设置上传文件的总大小
* 在struts.xml文件中,<constant name="struts.multipart.maxSize" value="2097152000"></constant>
* 设置上传文件的大小、类型和扩展名:
* 在自定义的配置文件中,在action标签下:
<!-- 配置拦截器的参数,这里是文件上传拦截器 -->
<interceptor-ref name="defaultStack">
<!--
配置文件上传拦截器的参数
* 与定义参数的顺序无关
* 允许的类型(allowedTypes)和允许的扩展名(allowedExtensions)必须保持一致
-->
<!--
* 配置上传文件的大小
* struts.xml文件中配置的是上传文件的总大小
* 这里配置的是上传文件的单个大小
-->
<param name="fileUpload.maximumSize">20971520</param>
<!-- 配置上传文件允许的类型,如果配置多个值的话,用","隔开 -->
<param name="fileUpload.allowedTypes">text/plain,application/msword</param>
<!-- 配置上传文件的扩展名,如果配置多个值的话,用","隔开 -->
<param name="fileUpload.allowedExtensions">.txt</param>
</interceptor-ref>
* 自定义上传文件的错误提示信息:
* 在动作类action同目录下,创建一个名为fileuploadmessage.properties资源文件(名为自定义)
* 改资源文件配置如下:
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}
* 多文件上传:
* 所有流程于配置都与单文件上传一致。
* 需要注意的是:
* 在页面中,虽然是多文件上传,但是页面中表单的name属性的值必须保持一致;
* 在动作类action中声明的相关属性,类型改成数组;
* 在业务方法中,相关处理流程改成单文件上传的循环。