Struts 2是通过Commons FileUpload文件上传。Commons FileUpload通过将HTTP的数据保存到临时文件夹,然后Struts使用fileUpload拦截器将文件绑定到Action的实例中。从而我们就能够以本地文件方式的操作浏览器上传的文件。
注意事项
1.form表单必须如下
<s:form action="" enctype ="multipart/form-data"> 注意enctype这个属性,如果不设置它的话那么MIME的默认值为application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据,进行下面的操作.
如果不设置enctype这个属性struts2会报出这样的错误 invalid field error for "" 提示类型转换错误,多说一点,出现类型转换错误也可能是由于没有导入struts2-convention-plugin.jar
2.你果你的struts2文件上传标签里面的属性如下<s:file name="image" label="图片"></s:file>,那么相应的action中必须拥有如下三个属性
private File image;//上传的文件
private String imageFileName;//文件的名字
private String imageContentType;//文件的类型
并且创建相应的get,set方法。
如果处理流程到了action内,那么说明action 里的image 已经指向的你所上传的文件了,接下来就是需要在execute方法里面对文件进行相应的处理了。
我们通常把所上传的文件的路径保存到数据库中,而把文件上传到服务器的一个目录里面,接下来我就对这个需求的实现写一些代码供大家参考。
private void uploadImage() {
String url = ServletActionContext.getRequest().getRealPath("/Images/questions/" + this.imageFileName);
//可以将这个url存储到数据库中,但是最好存储文件名到数据库,因为这个路径存储到数据库后其格式是存储路径的格式而非url的格式,如D:\programs\image.jpeg,不便于取出后在html页面显示
InputStream is = null;
OutputStream os = null;
try{
is = new FileInputStream(this.image);
File destFile = new File(url);
os = new FileOutputStream(destFile);
byte[] buffer = new byte[400];
int length = 0;
while(-1 != (length = is.read(buffer))){
os.write(buffer, 0, length);
}
}catch (IOException e) {
System.out.println("文件上传失败");
}finally{
try {
if(null != is)
is.close();
if(null != os)
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public String exexute() throws Exception {
if(null != this.image)//需要上 传图片时调用uploadImage();方法
this.uploadImage();
return SUCCESS;
}
介绍一个以年-月-日-时-分-秒 格式对上传的文件重命名的方法
/*
* 制作文件名,根据当前日期
*/
private String makeFileName(String fileName) {
SimpleDateFormat sDateFormat = new SimpleDateFormat(
"yyyy-MM-dd-hh-mm-ss");
String newName = sDateFormat.format(new Date().getTime())
+ this.getExtention(fileName);
return newName;
}
/*
* 截取出文件的扩展名
*/
private String getExtention(String fileName) {
int index = fileName.lastIndexOf(".");
return fileName.substring(index);
}
通过上面的两个方法就可以对上传的文件重新命名啦
最后关于文件上传这块一定要设计好测试用例,这个地方很容易出现BUG的,比如删除服务器上的文件时同时要删除数据库里的信息,更新服务器上的图片时一定要同时更新数据库里所存储的url
多文件上传只要把
private Fileimage;//上传的文件
private String imageFileName;//文件的名字
private String imageContentType;//文件的类型
更改为
private List<File> image;//上传的文件
private List<String> imageFileName;//文件的名字
private List<String> imageContentType;//文件的类型
execute方法中循环遍历它们就可以了。
另外form表单name属性名一定要相同,如下,struts2会为我们自动处理的
<s:file name="image" label="图片"></s:file>
<s:file name="image" label="图片"></s:file>
<s:file name="image" label="图片"></s:file>