Struts2文件上传功能开发
技术要点
本节代码详细说明文件上传功能的开发流程,介绍知识点如下:
文件上传页面和显示上传成功页面代码内容。
UploadAction类中实现上传功能方法和上传文件属性介绍。
struts.xml中UploadAction配置,以及字符编码、文件临时存放路径配置。
上传后所处路径和最终上传成功后效果展示。
演示代码
上传文件页面,这里笔者定义的是多个文件上传。
- <!---------------------文件名:upload.jsp----------------->
-
<%@taglib prefix="s" uri="/struts-tags"%>
- <html>
- <head>
-
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
- <title>上传文件</title>
- </head>
- <body>
- <!-- 上传文件表单定义 -->
-
<s:form action="upload" method="post" enctype="multipart/form-data">
- <tr>
- <!-- 上传文件标签定义 -->
-
<td>上传文件:<s:file name="file"></s:file></td>
- </tr>
- <tr>
-
<td>再次上传文件:<s:file name="file"></s:file></td>
- </tr>
- <tr>
-
<td align="left"><s:submit name="submit" value="提交"></s:submit></td>
- </tr>
- </s:form>
- </body>
- </html>
<!---------------------文件名:upload.jsp----------------->
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>上传文件</title>
</head>
<body>
<!-- 上传文件表单定义 -->
<s:form action="upload" method="post" enctype="multipart/form-data">
<tr>
<!-- 上传文件标签定义 -->
<td>上传文件:<s:file name="file"></s:file></td>
</tr>
<tr>
<td>再次上传文件:<s:file name="file"></s:file></td>
</tr>
<tr>
<td align="left"><s:submit name="submit" value="提交"></s:submit></td>
</tr>
</s:form>
</body>
</html>
上传文件成功后结果页面
- <!-------------------文件名:result.jsp ----------------->
-
<%@taglib prefix="s" uri="/struts-tags"%>
- <html>
- <head>
-
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
- <title>上传结果</title>
- </head>
- <body>
- 上传文件:
- <!-- 显示上传成功文件名 -->
-
<s:property value="fileFileName" />
- </body>
- </html>
<!-------------------文件名:result.jsp ----------------->
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>上传结果</title>
</head>
<body>
上传文件:
<!-- 显示上传成功文件名 -->
<s:property value="fileFileName" />
</body>
</html>
UploadAction类代码
- <!------------------文件名:UploadAction.java ------------------>
-
import java.io.File;
-
import java.io.FileInputStream;
-
import java.io.FileNotFoundException;
-
import java.io.FileOutputStream;
-
import java.io.IOException;
-
import java.io.InputStream;
-
import java.io.OutputStream;
-
import java.util.List;
-
-
import org.apache.struts2.ServletActionContext;
-
import com.opensymphony.xwork2.ActionSupport;
-
-
-
public class UploadAction extends ActionSupport {
-
-
private final static String UPLOADDIR = "/upload";
-
-
private List<File> file;
-
-
private List<String> fileFileName;
-
-
private List<String> fileContentType;
-
-
public List<File> getFile() {
-
return file;
- }
-
-
public void setFile(List<File> file) {
-
this.file = file;
- }
-
-
public List<String> getFileFileName() {
-
return fileFileName;
- }
-
-
public void setFileFileName(List<String> fileFileName) {
-
this.fileFileName = fileFileName;
- }
-
-
public List<String> getFileContentType() {
-
return fileContentType;
- }
-
-
public void setFileContentType(List<String> fileContentType) {
-
this.fileContentType = fileContentType;
- }
-
-
public String execute() throws Exception {
-
for (int i = 0; i < file.size(); i++) {
-
- uploadFile(i);
- }
-
return "success";
- }
-
-
-
private void uploadFile(int i) throws FileNotFoundException, IOException {
-
try {
-
InputStream in = new FileInputStream(file.get(i));
- String dir = ServletActionContext.getRequest().getRealPath(UPLOADDIR);
-
File uploadFile = new File(dir, this.getFileFileName().get(i));
-
OutputStream out = new FileOutputStream(uploadFile);
-
byte[] buffer = new byte[1024 * 1024];
-
int length;
-
while ((length = in.read(buffer)) > 0) {
-
out.write(buffer, 0, length);
- }
-
- in.close();
- out.close();
-
} catch (FileNotFoundException ex) {
- ex.printStackTrace();
-
} catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- }
<!------------------文件名:UploadAction.java ------------------>
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
//文件上传Action
public class UploadAction extends ActionSupport {
//上传文件存放路径
private final static String UPLOADDIR = "/upload";
//上传文件集合
private List<File> file;
//上传文件名集合
private List<String> fileFileName;
//上传文件内容类型集合
private List<String> fileContentType;
public List<File> getFile() {
return file;
}
public void setFile(List<File> file) {
this.file = file;
}
public List<String> getFileFileName() {
return fileFileName;
}
public void setFileFileName(List<String> fileFileName) {
this.fileFileName = fileFileName;
}
public List<String> getFileContentType() {
return fileContentType;
}
public void setFileContentType(List<String> fileContentType) {
this.fileContentType = fileContentType;
}
public String execute() throws Exception {
for (int i = 0; i < file.size(); i++) {
//循环上传每个文件
uploadFile(i);
}
return "success";
}
//执行上传功能
private void uploadFile(int i) throws FileNotFoundException, IOException {
try {
InputStream in = new FileInputStream(file.get(i));
String dir = ServletActionContext.getRequest().getRealPath(UPLOADDIR);
File uploadFile = new File(dir, this.getFileFileName().get(i));
OutputStream out = new FileOutputStream(uploadFile);
byte[] buffer = new byte[1024 * 1024];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.close();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
struts.xml配置文件中有关文件上传的配置:
- <!--------------------文件名:struts.xml------------------->
- <struts>
- <!-- 系统常量定义,定义上传文件字符集编码 -->
-
<constant name="struts.i18n.encoding" value="gb2312"></constant>
- <!-- 系统常量定义,定义上传文件临时存放路径 -->
-
<constant name="struts.multipart.saveDir" value="c:\"></constant>
- <!-- Action所在包定义 -->
-
<package name="C04.4" extends="struts-default">
- <!-- Action名字,类以及导航页面定义 -->
- <!-- 通过Action类处理才导航的的Action定义 -->
-
<action name="upload" class="action.UploadAction">
-
<result name="input">/jsp/upload.jsp</result>
-
<result name="success">/jsp/result.jsp</result>
- </action>
-
</package>
- </struts>
<!--------------------文件名:struts.xml------------------->
<struts>
<!-- 系统常量定义,定义上传文件字符集编码 -->
<constant name="struts.i18n.encoding" value="gb2312"></constant>
<!-- 系统常量定义,定义上传文件临时存放路径 -->
<constant name="struts.multipart.saveDir" value="c:\"></constant>
<!-- Action所在包定义 -->
<package name="C04.4" extends="struts-default">
<!-- Action名字,类以及导航页面定义 -->
<!-- 通过Action类处理才导航的的Action定义 -->
<action name="upload" class="action.UploadAction">
<result name="input">/jsp/upload.jsp</result>
<result name="success">/jsp/result.jsp</result>
</action>
</package>
</struts>
(1):文件上传页面如图4.8所示。
图4.8 文件上传
(2):选择文件如图4.9所示。
图4.9 选择上传的文件
(3):单击“提交”按钮后文件上传成功页面,并显示上传文件名,如图4.10所示。
图4.10 上传文件成功后效果
(4):两个被上传文件最终在服务器上存放路径效果如图4.11所示。
图4.11 上传文件存放路径图
代码解释
(1)在upload.jsp中通过Form标签和File标签定义了两个上传文件。Struts2标签笔者会在之后章节里具体介绍,这里只是让读者知道是如何使用标签显示图4.8显示的内容。如果上传成功,笔者在result.jsp中“[”和“]”之间显示上传文件的文件名,如果是多个文件,以“,”相隔。这些显示格式都是用Property标签定义的。
注意:如果上传文件,在JSP的Form中一定要定义如upload.jsp文件中黑体表示的部分。method和enctype属性都必须要如代码中所示。这样Form中上传文件才会起作用。
(2)UploadAction文件中先定义了常量UPLOADDIR,它是上传文件上传后存放的文件夹名字。比如笔者使用的是JBoss(附录中有安装和在MyEclipse中部署的操作说明),则在它的已部署Web项目下的upload文件夹中,会有所有上传成功的文件。如图4.11读者也可以看见它的上传文件最终存放路径。
注意:在MyEclipse中开发的“WebRoot”目录下也要新建一个upload文件夹,否则部署后在JBoss的已部署Web项目下将没有upload文件夹。因为部署的时候会将所有“WebRoot”目录下的文件夹和文件都部署到JBoss的已部署Web项目下。
定义好UPLOADDIR后,在定义上传文件的属性变量。也许其中的“fileFileName”和“fileContentType”读者看了有点别扭,尤其是“fileFileName”感觉不符合Java命名规范,但是这两个属性变量是4.1小节中介绍的“fileUpload”拦截器类中的类公有变量名字,只有这样定义,UploadAction执行时候会把在页面上选择的上传文件的属性值放在这两个变量里面,否则调试UploadAction时候会发现这两个变量都会是“null”即空值。不相信的读者可以自行改变这两个变量名再执行上传文件功能进行调试看一下这两个变量得到的值。
注意:因为这里笔者是进行多个文件上传功能开发,因此“file”、“fileFileName”、“fileFileName”属性变量都设定为List类型,其实还可以设定为数组类型。个人觉得没有啥大区别。完全凭个人喜好而定。还有如果读者自己开发单个文件上传,就没必要把它们设定为List类型或数组类型。直接把“file”定义为Java的IO包中的File类型,“fileFileName”、“fileFileName”定义为普通的String类型即字符串类型。
之后在execute方法中,写一个循环,对所有页面中选择的上传文件一个个进行上传。这里笔者运用了重构中的“抽取方法”的方式,将上传文件的功能封装成一个私有方法,名字为“uploadFile”。其中运用了Java的IO包中很多API方法。有对重构和Java的IO功能不了解的读者可以去查阅相关资料去理解掌握,这里不是本书以及本节重点,因此不再具体记述。
(3)struts.xml中定义了<constant>标签,主要定义了文件名和文件内容显示的字符编码集以及这些被上传文件临时存放路径。
先说明一下<constant>标签,顾名思义这是定义整个Web项目的一些常量属性值,如果不定义则在Struts2自带的default.properties(读者们可到自己安装Struts2的文件路径src\core\src\main\resources\org\apache\struts2\下找到)文件中有这些常量的定义,比如在本节struts.xml文件中的“struts.i18n.encoding”和“struts.multipart.saveDir”在default.properties定义代码如下:
- <!--------------------文件名:default.properties---------------->
-
### This can be used to set your default locale and encoding scheme
- # struts.locale=en_US
-
struts.i18n.encoding=UTF-8
-
- ### Parser to handle HTTP POST requests, encoded using the MIME-type multipart/form-data
- # struts.multipart.parser=cos
- # struts.multipart.parser=pell
- struts.multipart.parser=jakarta
-
# uses javax.servlet.context.tempdir by default
- struts.multipart.saveDir=
<!--------------------文件名:default.properties---------------->
### This can be used to set your default locale and encoding scheme
# struts.locale=en_US
struts.i18n.encoding=UTF-8
### Parser to handle HTTP POST requests, encoded using the MIME-type multipart/form-data
# struts.multipart.parser=cos
# struts.multipart.parser=pell
struts.multipart.parser=jakarta
# uses javax.servlet.context.tempdir by default
struts.multipart.saveDir=
如果不在struts.xml文件中定义,则Web项目会缺省使用default.properties文件中这两个常量属性的定义。一个将使字符编码集变为“UTF-8”,另一个干脆没有任何文件路径指定。而笔者开发的该Web项目缺省支持的字符编码集是“gb2312”,而且需要指定临时上传文件存放路径。(当然如果读者开发的Web项目缺省编码集就是“UTF-8”,而且也并不需要指定临时路径时候,就没必要在struts.xml中定义这两个<constant>),因此有必要定义这两个属性符合项目开发要求。
注意:也可以如第3章那样,把这两个属性定义在自定义的struts.properties文件中,具体代码可以如下:
- <!------------------------文件名:struts.properties------------------>
- struts.i18n.encoding =gb2312
- struts.multipart.saveDir= c:\
<!------------------------文件名:struts.properties------------------>
struts.i18n.encoding =gb2312
struts.multipart.saveDir= c:\
笔者个人认为比在struts.xml中定义更加好,毕竟Struts2自己也是定义在properties属性文件中,而不是定义在自己的xml配置文件中。(Struts2自带的xml配置文件为struts-default.xml,在4.1小节中已记述)。这里是为了让读者知道struts.xml配置文件也可以配置这些属性,因此写在struts.xml配置文件中。从3.2小节笔者说明struts.xml配置文件时并没有介绍<constant>标签这点也可以知道笔者个人其实是不赞同这样的配置手段即在struts.xml中配置<constant>标签。
在<Action>标签中配置“result”,和第3章类似,将这两个JSP文件的导航流程配置好即可。
(4)开始进行文件上传功能展示,按照如上记述的步骤执行即可。笔者在桌面上新建了两个文本文件,将它们上传到JBoss已部署的Web项目中展示文件上传的upload文件夹下。如图4.11所示。
其实还可以指定上传文件的格式,让它只上传特定类型的文件。比如只能上传文本和xml文件,则在struts.xml需要显示配置“uploadFile”拦截器。如下代码:
- <!-----------------------文件名:struts.xml------------------>
- <struts>
- <!-- Action所在包定义 -->
-
<package name="C04.4" extends="struts-default">
- <!-- Action名字,类以及导航页面定义 -->
- <!-- 通过Action类处理才导航的的Action定义 -->
-
<action name="upload" class="action.UploadAction">
-
<result name="input">/jsp/upload.jsp</result>
-
<result name="success">/jsp/result.jsp</result>
- </action>
- <!—显示配置文件上传拦截器 -->
- <interceptor-ref name=”fileUpload”>
- <!—指定特定类型的上传文件 -->
- <param name =”allowedTypes”>text/plain,application/xml</param>
- </ interceptor-ref >
- <interceptor-ref name=”defaultStack”></ interceptor-ref >
-
</package>
- </struts>
<!-----------------------文件名:struts.xml------------------>
<struts>
<!-- Action所在包定义 -->
<package name="C04.4" extends="struts-default">
<!-- Action名字,类以及导航页面定义 -->
<!-- 通过Action类处理才导航的的Action定义 -->
<action name="upload" class="action.UploadAction">
<result name="input">/jsp/upload.jsp</result>
<result name="success">/jsp/result.jsp</result>
</action>
<!—显示配置文件上传拦截器 -->
<interceptor-ref name=”fileUpload”>
<!—指定特定类型的上传文件 -->
<param name =”allowedTypes”>text/plain,application/xml</param>
</ interceptor-ref >
<interceptor-ref name=”defaultStack”></ interceptor-ref >
</package>
</struts>
定义了一个名为“allowedTypes”的参数,其中在<param></param>之间的是文件类型,也可以用“,”间隔,表示允许上传多个文件类型。这里允许上传文件类型为txt、xml格式的文件。如果读者不知道各个文件类型的定义,可在自己的JBoss安装目录中的server\default\deploy\jboss-web.deployer\conf\下的web.xml文件中找到(搜索<mime-mapping>即可)。
注意:如果显示配置Struts2自己的缺省拦截器一定要写在“defaultStack”前,否则“fileUpload”拦截器不会执行拦截。因为Struts2中如果某个拦截器执行拦截时候发现自己已经执行过,第二个乃至之后同名的拦截器都不会执行。这里因为“defaultStack”拦截器栈中包含了“fileUpload”拦截器,而“fileUpload”拦截器已经执行拦截了,则不会再执行拦截。如果把“defaultStack”拦截器栈放在“fileUpload”拦截器前配置,则只执行“defaultStack”拦截器栈中的“fileUpload”拦截器,这里是没有定义“allowedTypes”的,Struts2缺省默认的是支持所有文件类型。因此它会支持所有文件类型的文件上传。因此再设定“allowedTypes”就没有任何意义了。
分享到:
相关推荐
### Struts2讲义知识点概览 #### 一、Struts2的历史与发展 - **Struts框架的发展历程**: - Struts最初版本发布于2000年,是Java Web开发领域的一个重要里程碑。 - 随着时间的发展和技术的进步,Struts逐渐暴露...
### Struts2框架入门知识点详解 #### 一、Struts2框架概述 ##### 1.1 Struts2简介 Struts2是一个基于MVC(Model-View-Controller)设计模式的Web应用框架,用于简化Java Web应用程序的开发过程。与传统的Java Web...
struts2讲义struts2讲义struts2讲义struts2讲义struts2讲义struts2讲义struts2讲义struts2讲义struts2讲义struts2讲义struts2讲义
本讲义将详细介绍Struts2的核心概念、工作原理以及如何在实际项目中应用。 一、Struts2简介 Struts2是Apache软件基金会的开源项目,它是Struts1的升级版,旨在解决Struts1在可扩展性和灵活性上的不足。Struts2提供...
在本讲义中,我们将深入探讨Struts2的基本概念、依赖的库、启动配置以及配置文件。 首先,开发Struts2应用需要依赖一些核心的JAR文件。这些文件包括: 1. `struts2-core-2.x.x.jar`:这是Struts2框架的核心库,...
### Struts2框架详解 #### 一、Struts2框架介绍与概述 ##### 1.1 Struts2框架概述 Struts2是一个基于MVC(Model-View-Controller)模式的开源Java Web应用框架,它提供了强大的功能来帮助开发者构建灵活、可扩展...
Web基础技术简介第3章 Struts2核心技术第4章 另一Struts2核心技术:拦截器第5章 Struts2标签库第6章 Struts2非JSP视图技术第7章 Struts2类型转换技术第8章 Struts2输入校验第9章 Struts2国际化第10章 Struts2页面...
10. **Ajax支持**:Struts2提供了一套简单的API和标签库,使开发者能够方便地集成Ajax功能,实现部分页面的异步更新。 以上只是Struts2教程讲义中可能涵盖的部分关键知识点。通过深入学习并实践这些内容,开发者...
总的来说,"Struts2讲义"这份文档是学习和理解Struts2框架的宝贵资源,涵盖了从入门到进阶的全部知识点,对提升Java web开发技能大有裨益。通过详细阅读并实践其中的示例,开发者能够迅速掌握Struts2框架,并将其...
### Struts2讲义知识点概览 #### 一、Struts2的历史与发展 - **Struts框架的演变**:从Struts1到Struts2,框架经历了从MVC(Model-View-Controller)架构的经典实践到更为灵活、强大的迭代升级。 - **Struts2的...
这个“struts2讲义”显然提供了一个全面的教程,旨在帮助学习者理解和掌握Struts2的核心概念和技术。以下是Struts2的一些关键知识点: 1. **MVC模式**:Struts2基于Model-View-Controller(MVC)设计模式,它将应用...
Struts2讲义1 Struts2是一款基于MVC(Model-View-Controller)设计模式的Java Web开发框架,由Apache软件基金会维护。它继承了Struts1的优点,并结合了WebWork框架的功能,提供了更强大的控制层解决方案。Struts2的...
Struts2讲义 作者:吴峻申 目录 第1章 Struts过时了吗? 10 1.1 Struts历史发展过程 10 1.2 Struts2的“简历” 13 1.2.1 标签库介绍 13 1.2.2 拦截器应用目的 14 1.2.3 FilterDispatcher和Action概述 14 1.2.4 ...
西安野马计算机培训学校的STRUTS2讲义,可能涵盖了这一框架的基础知识和高级特性,帮助学员理解和掌握Struts2的核心概念。 首先,Struts2的基础部分可能包括以下几个方面: 1. **架构原理**:讲解Struts2的MVC设计...
Struts2是Apache软件基金会...总的来说,黑暗浪子的这本Struts2讲义涵盖了Struts2的各个方面,无论对于初学者还是有经验的开发者,都是一个宝贵的参考资料,能帮助读者深入理解和熟练运用Struts2框架,提高开发效率。