使用Struts1实现文件上传(一)
完成文件上传功能大致需要以下几个步骤:
(1)创建用于文件上传的JSP页面;
(2)创建用于承载数据的ActionForm;
(3)创建用于处理上传的Action;
(4)配置文件上传大小;
(5)配置从web.xml文件中读取文件存放路径;
步骤一:创建用于文件上传的JSP页面
Java代码
[java]
<html:form enctype="multipart/form-data" action="/fileUpload" method="post">
<html:file property="uploadFile"></html:file>
<html:submit>Upload File</html:submit>
</html:form>
步骤二:创建用于承载数据的ActionForm
在项目中新建一个ActionForm的子类,如命名为:FileUploadForm.java,在其中新增一个FormFile类型的属性uploadFile,并设置getter、setter方法。
Java代码
[java]
import org.apache.struts.upload.FormFile;
private FormFile uploadFile;
public FormFile getUploadFile() {
return uploadFile;
}
public void setUploadFile(FormFile uploadFile) {
this.uploadFile = uploadFile;
}
在Struts中,一个FormFile类型的对象对应Form表单中创送的一个文件,Struts将上传的文件信息封装金FormFile中,通过FormFile提供的方法可以方便的进行文件的操作。其实FormFile是一个接口,位于 org.apache.struts.upload.FormFile 中,它定义了操作上传文件的基本方法。
FormFile接口定义的常用方法:
(1) getFileName()/setFileName() //用于获取或设置文件名;
(2) getFileSize() / setFileSize() //用于获取或设置文件字节数;
(3) getFileData() //用于获取文件的字节数组,用于小的文件;
(4) getInputStream() //用于获取文件的输入流,用于较大的文件;
(5) destory() //销毁FromFile;
步骤三:创建用于处理上传的Action
在项目中新建一个Action的子类,如命名为:FileUploadAction.java,在其execute方法中添加处理代码。
Java代码
[java]
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
FileUploadForm fileUploadForm = (FileUploadForm) form;
FormFile uploadFile = fileUploadForm.getUploadFile();
try {
FileOutputStream outer = new FileOutputStream("d:\\"+uploadFile.getFileName());
byte[] buffer = uploadFile.getFileData();
outer.write(buffer);
outer.close();
uploadFile.destroy();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
在代码中可以看到,我们从FileUploadForm中找到了FormFile类型的属性,通过其提供的方法得到文件的信息,并将其存入服务器的磁盘中。在保存的过程中需要用到文件流的一些基本操作。
到此为止,文件的上传已经基本成功,剩下的两步为配置文件上传大小和从web.xml文件中读取文件存放路径,可以选择学习。
步骤四:配置文件上传大小
在Struts中可以配置上传文件的大小,以避免服务器的硬盘消化不良。
打开项目中WebRoot\WEB-INF\struts-config.xml ,切换至源码视图,在其中添加如下节点信息,便可以控制上传文件的大小了。
Xml代码
[xml]
<controller maxFileSize="8K"></controller>
其中maxFileSize属性的单位可以是K,也可以是M或G;Struts在写 FormFile类时借助的是fileupload中的API,设置的默认大小为250M
注意:操作struts-config.xml文件时应当特别注意各个节点间的顺序,因为Struts要求配置文件的各个元素顺序有一定的要求,顺序一旦被打乱,也就意味着web容器即将进入瘫痪状态,因此在添加<controler>节点时,要将此节点添加在<action-mapping>和<message-resources>节点之间。
附:Struts-config.xml配置文件各元素的顺序列表。
Xml代码
[xml]
The content of element type "struts-config" must match "(display-name?,description?,form-beans?,global-exceptions?,global-forwards?,action-mappings?,controller?,message-resources*,plug-in*)".
步骤五:配置从web.xml文件中读取文件存放路径
在步骤三中的代码中我们已经看到,在保存文件时,我写的是一个固定的存放路径,有没有什么办法让它动态改变呢?答案是肯定的,Struts提供了一些方法可以读取web.xml中读取数据,那么我们可以把存放的路径存放在web.xml文件中,存储文件时再将路径读取出来。这样做的好处是,如果存放路径发生改变,我们只需要修改配置文件,而不需要改动代码。
打开项目WebRoot\WEB-INF\web.xml , 找到一个servlet,在该servlet的节点下添加如下代码:
Xml代码
[xml]
<init-param>
<param-name>path</param-name>
<param-value>d:\uploadFolder\</param-value>
</init-param>
要想读取此节点的信息,在处理上传文件的Action代码中加入如下代码:
Java代码
[java]
//以下两行代码任选其一;
String path = this.getServlet().getInitParameter("uploadpath");
String path = this.getServlet().getServletConfig().getInitParameter("uploadpath")
到此基于Struts的文件上传操作已经基本完成。
使用Struts1实现文件上传(二)
在使用Struts1实现文件上传(一)中,我将文件保存在服务器端的硬盘里,有没有办法将其保存在Oracle10g数据库中呢?答案是肯定的,只需要对程序稍加改造就可以实现将文件保存在数据库中。用到时再将文件从数据库中还原出来供用户下载。
在数据库中保存文件的方法和保存其他基本数据类型相差不多,只是要存入即可,但是其对应的数据类型比较特殊,一般选择二进制的数据类型。Oracle10g中提供了RAW和Long RAW数据类型,这两中数据类型用于保存二进制的数据;二进制类型的好处在于当数据在不同系统之间传输时,可以不做任何数据类型的转换,方便了系统之间的操作。RAW类型的最大宽度为2000字节,而Long RAW类型的最大宽度可以达到2GB,非常适合保存图像、声音、视频等数据量较大的数据。
因此,要想将文件保存在数据库中用到时在取出来,就要完成三个步骤:
(1)新建Oracle10g数据表,在表中添加Long RAW类型的字段;
(2)在程序中将上传的文件以流的形式保存到数据库中;
(3)将文件从数据库中还原出来。
一、新建Oracle10g数据表
在Oracle10g中新建一张数据表,如命名为UploadFiles,在表中添加相应的字段;
Sql代码
[sql]
create table UploadFiles
(
fileId number not null,
fileName varchar2(100) not null,
fileContent long raw not null,
filePubDate date not null
)
其中FileContent便是用来存放文件的Long RAW二进制数据类型。
二、将上传文件保存在数据库
剩下的工作便是在程序中编写代码将用户上传的文件保存在数据库中了,主要的代码已经在文章“使用Struts1实现文件上传(一)”中实现,现在只需要将原来保存在文件中的部分代码替换为保存在数据库的代码即可。
Java代码
[java]
UploadForm uploadForm = (UploadForm) form;
FormFile uploadFile = uploadForm.getUploadFile();
Connection conn = null;
PreparedStatement ps = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:DataBaseName","username","password");
String sql = "insert into pic (fileName,fileContent,filePubDate) values (?,?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1, uploadFile.getFileName());
ps.setBinaryStream(2, uploadFile.getInputStream(), uploadFile.getFileSize());
ps.setDate(3, new Date());
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
当用户点击上传后就可以将文件存储在数据库中了。
三、将文件从数据库中还原出来
当用户需要用到文件时,就需要从数据中将文件查询出来,方法也很简单,看代码:
Java代码
[java]
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
<strong>InputStream input = null;</strong>
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:DataBaseName","username","password");
String sql = "select * from UpLoadFiles where id = 3";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
if(rs.next()){
<strong>input = rs.getBinaryStream("pic");</strong>
}
//根据需要操作InputStream对象的代码;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rs.close();
ps.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
将文件从数据库中读取出来后得到的将是一个InputStream类型的对象,可以根据需要操作这个对象还原文件。