Struts2文件上传

来源:互联网 发布:b站直播间刷人气源码 编辑:程序博客网 时间:2024/06/06 03:01
文件上传是Web应用经常需要面对的问题,下面是我总结的Struts2的文件上传相关知识,以便自己以后查看使用。
表单元素的enctype属性
表单的enctype属性指定的是表单数据的编码方式,该属性有如下三个值
1、application/x-www-form-urlencoded这是默认的编码方式,它只处理表单域里的value属性值。采用这种编码方式的表单会将表单域的值处理成URL编码方式。
2、multipart/form-data这种编码方式会以二进制流的方式来处理表单数据。这种编码方式会把文件域指定文件的内容也封装到请求参数里。
3、text/plain当表单的action属性为matilto:URL的形式时使用这种编码方式比较方便,这种方式主要适用于直接通过表单发送邮件的情况。
Struts2的文件上传
Struts2并未提供自己的请求解析器,也就是说Struts2不会自己去处理multipart/form-data的请求,他需要调用其他上传组件来解析二进制请求数据。但Struts2在原有的上传解析器基础上做了进一步封装,进一步简化了文件上传。
Struts2默认使用的是Jakarta的Common-FileUpload文件上传框架,因此,如果需要使用Struts2的文件上传功能,则需要在Web应用中增加两个JAR文件,即commons-io-1.3.2.jarcommons-fileupload-1.2.1.jar
文件上传页面
<body><s:fielderror /><form action="uploadPro" method="post" enctype="multipart/form-data">文件标题:<input type="text" name="title" /><br /> 选择文件:<input type="file" name="upload" /><br /> <input type="submit" value="上传" /></form></body>
处理上传请求的Action类
package com.test.action;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.util.UUID;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;public class UploadAction extends ActionSupport{//封装文件标题请求参数的属性private String title;//封装上传文件域的属性private File upload;//封装上传文件名的属性private String uploadContentType;//封装上传文件名的属性private String uploadFileName;//直接在struts.xml文件中配置的属性private String savePath;public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public File getUpload() {return upload;}public void setUpload(File upload) {this.upload = upload;}public String getUploadContentType() {return uploadContentType;}public void setUploadContentType(String uploadContentType) {this.uploadContentType = uploadContentType;}public String getUploadFileName() {return uploadFileName;}public void setUploadFileName(String uploadFileName) {this.uploadFileName = uploadFileName;}//返回上传文件的保存位置public String getSavePath() {return ServletActionContext.getRequest().getRealPath(savePath);}//接受struts.xml文件配置的方法public void setSavePath(String savePath) {this.savePath = savePath;}@Overridepublic String execute() throws Exception {String newName=UUID.randomUUID()+uploadFileName.substring(uploadFileName.lastIndexOf("."));//以服务器的文件保存地址和随机文件名建立上传文件输出流FileOutputStream fos=new FileOutputStream(getSavePath()+"\\"+newName);FileInputStream fis=new FileInputStream(getUpload());byte[] buffer=new byte[1024];int len=0;while((len=fis.read(buffer))>0){fos.write(buffer, 0, len);}setUploadFileName(newName);return SUCCESS;}}
上面的Action除了与表单对应的upload和title两个属性外还包含了uploadFileName和uploadContentType两个属性,这两个属性分别用于封装上传文件的文件名、上传文件的文件类型。这是Struts2的独特之处,Action类通过File类型属性直接封装了上传文件的文件内容,但这个File属性无法获取上传文件的文件名和文件类型,所以Struts2直接将文件域中包含的上传文件名和文件类型的信息封装到uploadFileName和uploadContentType属性中。可以认为:如果表单包含一个name属性为XXX的文件域,则对应的Action需要使用三个属性类封装该文件域的信息。
1、类型为File的xxx属性封装了该文件域对应的文件内容
2、类型为String的xxxFileName属性封装了该文件域对应的文件的文件名
3、类型为String的xxxContentType属性封装了该文件域对应的文件的文件类型
通过上面的三个属性可以简单地实现文件上传,所以在execute方法中,可以直接通过调用getXXX()方法来获取上传文件的文件名、文件类型和文件内容。
上面的Action类还包含了一个savePath属性,该属性的值通过配置文件来动态设置,这是Struts2设计中一个典型的依赖注入。
配置文件上传的Action
<!-- 配置处理文件上传的Action --><action name="uploadPro" class="com.test.action.UploadAction">    <!-- 动态设置Action的属性值 -->    <param name="savePath">upload</param>    <!-- 配置上传成功的视图页面 -->    <result>succ.jsp</result></action>
上传成功页面
<body>上传成功!<br /><!-- 输出上传的表单里的文件标题属性 -->文件标题:<s:property value="+title" /><br /><!-- 根据上传文件的文件名,在页面上显示上传的图片 -->文件为:<img src='upload/<s:property value="uploadFileName"/>' /><br /></body>
调试运行前在WebRoot下新建一个upload文件夹,用于存放上传文件。
运行结果:

拦截器实现文件过滤
Struts2提供了一个文件上传的拦截器,通过配置该拦截器可以更轻松地实现文件过滤,Struts2中文件上传的拦截器是fileUpload,为了让该拦截器起作用,只需要在该Action中配置该拦截器引用即可。
配置fileUpload拦截器时,可以为其指定两个参数。
1、allowedTypes:该参数指定允许上传的文件类型,多个文件类型之间以英文逗号(,)隔开
2、maximunSize:该参数指定允许上传的文件的大小,单位是字节
通过配置fileUpload拦截器,可以更轻松地实现文件过滤,当文件过滤失败后,系统自动转入input逻辑视图,因此必须为该Action配置名为input的逻辑视图。除此之外,还必须显示地为该Action配置defaultStack的拦截器引用。
struts.xml配置
<!-- 配置处理文件上传的Action --><action name="uploadPro" class="com.test.action.UploadAction"><!-- 配置fileUpload拦截器 --><interceptor-ref name="fileUpload"><!-- 配置允许上传的文件类型 --><param name="allowedTypes">image/bmp,image/png,image/gif,image/jpeg,image/pjpeg</param><!-- 配置允许上传的文件大小 --><param name="maximunSize">2000</param></interceptor-ref><!-- 配置系统默认的拦截器 --><interceptor-ref name="defaultStack" /><!-- 动态设置Action的属性值 --><param name="savePath">/upload</param><!-- 配置上传成功的视图页面 --><result>succ.jsp</result><!-- 配置input逻辑视图对应的视图页面 --><result name="input">upload.jsp</result></action>
多文件上传
Struts2也可以很方便的实现多文件上传。
文件上传页面
<body><s:fielderror /><form action="uploadPro" method="post" enctype="multipart/form-data">文件标题:<input type="text" name="title" /><br /> 选择第一个文件:<input type="file" name="upload" /><br /> 选择第二个文件:<input type="file" name="upload" /><br /> 选择第三个文件:<input type="file" name="upload" /><br /><input type="submit" value="上传" /></form></body>
处理请求的Action类代码
package com.test.action;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.util.UUID;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;public class UploadAction extends ActionSupport{//封装文件标题请求参数的属性private String title;//使用字符串数组封装多个文件域对应的文件内容private File[] upload;//使用字符串数组封装多个文件域对应的文件类型private String[] uploadContentType;//使用字符串数组封装多个文件域对应的文件名private String[] uploadFileName;//接受依赖注入的属性private String savePath;public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public File[] getUpload() {return upload;}public void setUpload(File[] upload) {this.upload = upload;}public String[] getUploadContentType() {return uploadContentType;}public void setUploadContentType(String[] uploadContentType) {this.uploadContentType = uploadContentType;}public String[] getUploadFileName() {return uploadFileName;}public void setUploadFileName(String[] uploadFileName) {this.uploadFileName = uploadFileName;}//返回上传文件的保存位置public String getSavePath() {return ServletActionContext.getRequest().getRealPath(savePath);}//接受struts.xml文件配置的方法public void setSavePath(String savePath) {this.savePath = savePath;}@Overridepublic String execute() throws Exception {//取得需要上传的文件数组File[] files=getUpload();//遍历每个需要上传的文件for(int i=0;i<files.length;i++){String newName=UUID.randomUUID()+uploadFileName[i].substring(uploadFileName[i].lastIndexOf("."));//以服务器的文件保存地址和随机文件名建立上传文件输出流FileOutputStream fos=new FileOutputStream(getSavePath()+"\\"+newName);//以每个需要上传的文件建立文件输入流FileInputStream fis=new FileInputStream(files[i]);//将每个需要上传的文件写到服务器对应的文件中byte[] buffer=new byte[1024];int len=0;while((len=fis.read(buffer))>0){fos.write(buffer, 0, len);}fos.close();getUploadFileName()[i]=newName;}return SUCCESS;}}
上传成功视图页面
<body>上传成功!<br /><!-- 输出上传的表单里的文件标题属性 -->文件标题:<s:property value="title" /><br /><!-- 根据上传文件的文件名,在页面上显示上传的图片 -->文件为:<s:iterator value="uploadFileName" id="fileName"><img src='upload/<s:property value="fileName"/>'style="width:50px;height:50px" /></s:iterator><br /></body>
结果展示:

原创粉丝点击