第十三章 文件上传下载.docx
《第十三章 文件上传下载.docx》由会员分享,可在线阅读,更多相关《第十三章 文件上传下载.docx(33页珍藏版)》请在冰豆网上搜索。
第十三章文件上传下载
《研磨struts2》第十三章文件上传下载
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代码:
查看复制到剪贴板打印
1.
2. …
3.
4. …
5. 6.class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
7. …
8.
9. …
10.
11. …
12.
13.
14.
15.
16.
…
…
class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
…
…
…
上面列出了struts-default.xml中跟fileUpload拦截器有关的部分。
首先,Struts2有一个预定义拦截器叫fileUpload;然后,defaultStack拦截器栈引用了fileUpload拦截器;最后,struts-default包又将defaultStack拦截器声明为自己的默认拦截器引用。
因此,如果我们的包继承了struts-default包,而我们的Action类又没有声明自己的拦截器引用的话,使用的就是defaultStack拦截器栈,从而引用了fileUpload拦截器。
2:
实现上传页面
如果一个表单中,包含了文件上传的表单域,则一定要把整个表单enctype属性设置为multipart/form-data。
形如:
java代码:
查看复制到剪贴板打印
1.<%@ page language="java" contentType="text/html; charset=gb2312"
2. pageEncoding="gb2312"%>
3.
DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
4. "http:
//www.w3.org/TR/html4/loose.dtd">
5.
6.
7.
8.
Insert title here
9.
10.
11.
17.
18.
<%@pagelanguage="java"contentType="text/html;charset=gb2312"
pageEncoding="gb2312"%>
DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"
"http:
//www.w3.org/TR/html4/loose.dtd">
Inserttitlehereenctype="multipart/form-data">
文件名称:
文件:
在这个文件里,指定了
整个页面运行如下:
图13.1文件上传页面
在这个页面上文件域里面,在输入框后面多了一个“浏览”按钮,点击这个浏览按钮,就会弹出文件选择框。
3:
实现文件上传Action
这个Action和其他的Action没有太多特殊之处,使用一个String属性fileName来准备接收前一个页面的fileName文本框的值,然后使用一个File属性myFile来准备接收前一个页面的myFile文件框传过来的文件的值。
在execute方法中,我们可以随意存储上传的文件,本例只是把它放到了e盘的temp目录下,并以传入的fileName作为保存的文件名。
示例代码如下:
java代码:
查看复制到剪贴板打印
1.public class UploadAction extends ActionSupport{
2. private String fileName;
3. private File myFile;
4.
5. public String getFileName() {
6. return fileName;
7. }
8. public void setFileName(String fileName) {
9. this.fileName = fileName;
10. }
11. public File getMyFile() {
12. return myFile;
13. }
14. public void setMyFile(File myFile) {
15. this.myFile = myFile;
16. }
17.
18. public String execute()throws Exception{
19. //先把上传过来的文件存放到e盘temp目录下,以传入的fileName为名字
20. OutputStream output = null;
21. InputStream input = null;
22. try{
23. output = new FileOutputStream("e:
/temp/"+fileName);
24. //建立一个1k大小的缓冲区
25. byte[] bs = new byte[1024];
26.
27. //将上传过来的文件输出到output中
28. input = new FileInputStream(myFile);
29. int length = 0;
30. //length=input.read(bs)这句话中,length=-1代表了读到文件结尾
31. while ((length=input.read(bs))>0){
32. output.write(bs, 0, length);
33. }
34. }finally{
35. input.close();
36. output.close();
37. }
38. return SUCCESS;
39. }
40.}
publicclassUploadActionextendsActionSupport{
privateStringfileName;
privateFilemyFile;
publicStringgetFileName(){
returnfileName;
}
publicvoidsetFileName(StringfileName){
this.fileName=fileName;
}
publicFilegetMyFile(){
returnmyFile;
}
publicvoidsetMyFile(FilemyFile){
this.myFile=myFile;
}
publicStringexecute()throwsException{
//先把上传过来的文件存放到e盘temp目录下,以传入的fileName为名字
OutputStreamoutput=null;
InputStreaminput=null;
try{
output=newFileOutputStream("e:
/temp/"+fileName);
//建立一个1k大小的缓冲区
byte[]bs=newbyte[1024];
//将上传过来的文件输出到output中
input=newFileInputStream(myFile);
intlength=0;
//length=input.read(bs)这句话中,length=-1代表了读到文件结尾
while((length=input.read(bs))>0){
output.write(bs,0,length);
}
}finally{
input.close();
output.close();
}
returnSUCCESS;
}
}
注意:
如何操作上传的文件,完全是I/O的知识,为了保持实例的简单,只是采用了最简单的方式,把内容存放在一个绝对路径表示的文件里面,当然还可以将上传的文件存储在web服务器上,甚至数据库中。
4:
映射这个Action
在struts.xml中对这个Action进行配置,可以看到没有任何特异之处,只是指出了Action名称和对应的实现类,以及上传之后要跳转到的页面。
java代码:
查看复制到剪贴板打印
1.
2.
3. /fileupload/success.jsp
4.
5.
/fileupload/success.jsp
5:
上传之后的页面
由于上传的文件在Action中已经被正确处理了,所以这个上传之后的页面没有任何特殊的作用,只是显示一下,表示上传成功了,示例代码如下:
java代码:
查看复制到剪贴板打印
1.<%@ page language="java" contentType="text/html; charset=gb2312"
2. pageEncoding="gb2312"%>
3.<%@taglib prefix="s" uri="/struts-tags" %>
4.
DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
5. "http:
//www.w3.org/TR/html4/loose.dtd">
6.
7.
8.
9.
Insert title here 10.
11.
12. 成功上传文件property value="fileName"/>
13.
14.
<%@pagelanguage="java"contentType="text/html;charset=gb2312"
pageEncoding="gb2312"%>
<%@taglibprefix="s"uri="/struts-tags"%>
DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"
"http:
//www.w3.org/TR/html4/loose.dtd">
Inserttitlehere成功上传文件propertyvalue="fileName"/>
运行测试一下,在文件上传页面选择要上传的文件,然后点击提交按钮,会发现文件会上传,并以我们指定的文件名称保存到我们指定的文件夹下去了。
13.1.3获取文件的更多信息
Struts2支持用更多的属性来获取有关上传文件的真实文件名和文件类型。
比如:
表单中包含了一个叫xyz的文件域,也就是类似于∙File类型的属性xyz用来获取文件内容。
∙String类型的属性xyzFileName用来获取文件的真实文件名。
∙String类型的属性xyzContentType属性用来获取文件的类型。
将处理上传文件的Action类修改一下,添加两个属性:
myFileFileName和myFileContentType,以及他们对应的getter/setter方法,来尝试获得文件的真实文件名和文件类型。
另外,保存文件的时候,也使用文件的真实名称,示例代码如下:
java代码:
查看复制到剪贴板打印
1.public class UploadAction extends ActionSupport{
2. private String fileName;
3. private File myFile;
4. private String myFileFileName;
5. private String myFileContentType;
6. public String getMyFileFileName() {
7. return myFileFileName;
8. }
9. public void setMyFileFileName(String myFileFileName) {
10. this.myFileFileName = myFileFileName;
11. }
12. public String getMyFileContentType() {
13. return myFileContentType;
14. }
15. public void setMyFileContentType(String myFileContentType) {
16. this.myFileContentType = myFileContentType;
17. }
18. public String getFileName() {
19. return fileName;
20. }
21. public void setFileName(String fileName) {
22. this.fileName = fileName;
23. }
24. public File getMyFile() {
25. return myFile;
26. }
27. public void setMyFile(File myFile) {
28. this.myFile = myFile;
29. }
30.
31. public String execute()throws Exception{
32. System.out.println("用户传入的文件名:
"+fileName);
33. System.out.println("上传文件的真实文件名:
"+myFileFileName);
34. System.out.println("上传文件的类型:
"+myFileContentType);
35. System.out.println("这个文件的文件名是什么?
"+myFile.getName());
36.
37. //把上传过来的文件存放到e盘temp目录下,以真实的文件名作为名字
38. OutputStream output = null;
39. InputStream input = null;
40. try{
41. output = new FileOutputStream("e:
/temp/"+myFileFileName);
42. //建立一个1k大小的缓冲区
43. byte[] bs = new byte[1024];
44.
45. //将上传过来的文件输出到output中
46. input = new FileInputStream(myFile);
47. int length = 0;
48. //length=input.read(bs)这句话中,length=-1代表了读到文件结尾
49. while ((leng