文件上传下载之文件上传

13.1 文件上传13.1.1概述

在开发基于Web的应用的时候,经常会碰到需要实现文件上传、下载的功能,比如编辑某个商品,需要给它上传一个图片等等。

不使用Struts2的话,可以有很多种方式来实现文件上传,比如使用Apache的Common-FileUpload等。但是这些传统的方式,实现起来非常麻烦,需要写很多代码来进行控制。

现在使用Struts2来实现文件上传的功能,会更加简单和方便,事实上,Struts2的文件上传功能,默认就是基于Common-FileUpload来实现的,只不过比直接使用Common-FileUpload来得更简单。

13.1.2使用Struts2实现文件上传

1:fileUpload拦截器

使用Struts2来实现文件上传,需要使用Struts2预定义的fileUpload拦截器。简要的看看在struts-default.xml中的配置,示例如下:

java代码:

上面列出了struts-default.xml中跟fileUpload拦截器有关的部分。首先,Struts2有一个预定义拦截器叫fileUpload;然后,defaultStack拦截器栈引用了fileUpload拦截器;最后,struts-default包又将defaultStack拦截器声明为自己的默认拦截器引用。

因此,如果我们的包继承了struts-default包,而我们的Action类又没有声明自己的拦截器引用的话,使用的就是defaultStack拦截器栈,从而引用了fileUpload拦截器。

2:实现上传页面

如果一个表单中,包含了文件上传的表单域,则一定要把整个表单enctype属性设置为multipart/form-data。形如:

java代码:

在这个文件里,指定了<form>元素的enctype属性为multipart/form-data,还用了一个type为file的输入域,它会在页面上生成一个文件选择框。整个页面运行如下:

图13.1 文件上传页面

在这个页面上文件域里面,在输入框后面多了一个“浏览”按钮,点击这个浏览按钮,就会弹出文件选择框。

3:实现文件上传Action

这个Action和其他的Action没有太多特殊之处,使用一个String属性fileName来准备接收前一个页面的fileName文本框的值,然后使用一个File属性myFile来准备接收前一个页面的myFile文件框传过来的文件的值。

在execute方法中,我们可以随意存储上传的文件,本例只是把它放到了e盘的temp目录下,并以传入的fileName作为保存的文件名。

示例代码如下:

java代码:

注意:如何操作上传的文件,完全是I/O的知识,为了保持实例的简单,只是采用了最简单的方式,把内容存放在一个绝对路径表示的文件里面,当然还可以将上传的文件存储在web服务器上,甚至数据库中。

4:映射这个Action

在struts.xml中对这个Action进行配置,可以看到没有任何特异之处,只是指出了Action名称和对应的实现类,以及上传之后要跳转到的页面。

java代码:

5:上传之后的页面

由于上传的文件在Action中已经被正确处理了,所以这个上传之后的页面没有任何特殊的作用,只是显示一下,表示上传成功了,示例代码如下:

java代码:

运行测试一下,在文件上传页面选择要上传的文件,然后点击提交按钮,会发现文件会上传,并以我们指定的文件名称保存到我们指定的文件夹下去了。

13.1.3获取文件的更多信息

Struts2支持用更多的属性来获取有关上传文件的真实文件名和文件类型。

比如:表单中包含了一个叫xyz的文件域,也就是类似于<input type=”file” name=”xyz”,那么可以用三个属性来获取上传文件的信息:

将处理上传文件的Action类修改一下,添加两个属性:myFileFileName和myFileContentType,以及他们对应的getter/setter方法,来尝试获得文件的真实文件名和文件类型。

另外,保存文件的时候,也使用文件的真实名称,示例代码如下:

java代码:

运行测试一下,后台输出为:

java代码:

注意其中“这个文件的文件名是什么?”,代码写的是输出myFile这个File对象的名字,由于myFile对象封装了上传文件的内容,因而某些朋友就认为这个文件就是我们上传的文件,从而认为它的getName方法就是返回的上传的这个文件的名字。

这是错误的,这个myFile文件是Struts2在上传过程中生成的临时文件,它的内容与上传文件相同,但是名字并不相同,它的名字是由Struts2临时生成的,形如“upload__5ab75acc_12c5f17ac7a__8000_00000001.tmp”这样的。

13.1.4限制文件的大小及类型

在文件上传的时候,有可能需要对文件的大小和类型做出限制。Struts2支持直接在fileUpload拦截器上设置参数来进行限制。

在引用fileUpload拦截器的时候,可以指定三个参数(指定<param>子元素):

如果上传的文件不满足以上的参数指定的条件,则会跳转到一个叫input的<result>上,一般input都会指回到提交之前的页面,也就是文件上传页面。

参数非常简单,但是配置比较怪异,fileUpload拦截器虽然在defaultStack拦截器栈上已经引用了,但是还可以在defaultStack拦截器栈之前再引用一次,然后在这次引用上指定参数,示例代码如下:

java代码:

观察以上的<action>元素,要额外注意两点:

这个Action应该先引用fileUpload拦截器,然后引用defaultStack拦截器栈。这个Action中还要有一个叫input的<result>,以备上传不成功时,Struts2跳转到提交前的页面。

还要稍微修改一下login.jsp,来显示不满足限制条件时的错误信息。只需要在合适的地方加上<s:fielderror/>来显示错误信息即可。形如:

java代码:

运行修改之后的文件上传功能,如果上传非txt文件,运行结果如下:

图13.2 fileUpload拦截器限制文件上传类型

如果上传大于1000字节的txt文件,运行结果如下:

图13.3 fileUpload拦截器限制文件上传大小

13.1.5上传超大的文件人生不如意十之八-九,与其诅咒黑暗,倒不如在生命中点燃一盏灯

文件上传下载之文件上传

相关文章:

你感兴趣的文章:

标签云: