Struts2默认使用Jakarta的Common-FileUpload的文件上传解析器。见struts.properties配置文件中:

#指定使用COS的文件上传解析器
#struts.multipart.parser
= cos
#指定使用Pell的文件上传解析器
#struts.multipart.parser
= pell
#指定使用Common-FileUpload的文件上传解析器
struts.multipart.parser
= jakarta


   实际上,Struts2的文件上传功能只是在原有的文件上传项目上做了进一步的封装,取消了不同文件上传项目的编程差异而已。

import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;

import  com.opensymphony.xwork2.ActionSupport;

public   class  UploadAction  extends  ActionSupport  {

    
private static final long serialVersionUID = -3921956808689128362L;
    
//封装文件标题请求参数的属性
    private String title;
    
//封装上传文件域的属性
    private File upload;
    
//封装上传文件类型的属性
    private String uploadContentType;
    
//封装上传文件名的属性
    private String uploadFileName;
    
//直接在struts.xml文件中配置的属性
    private String savePath;
    
    
//文件标题的setter和getter方法
    public String getTitle() {
        
return title;
    }

    
public void setTitle(String title) {
        
this.title = title;
    }

    
//上传文件对应文件内容的setter和getter方法
    public File getUpload() {
        
return upload;
    }

    
public void setUpload(File upload) {
        
this.upload = upload;
    }

    
//上传文件的文件类型的setter和getter方法
    public String getUploadContentType() {
        
return uploadContentType;
    }

    
public void setUploadContentType(String uploadContentType) {
        
this.uploadContentType = uploadContentType;
    }

    
//上传文件的文件名的setter和getter方法
    public String getUploadFileName() {
        
return uploadFileName;
    }

    
public void setUploadFileName(String uploadFileName) {
        
this.uploadFileName = uploadFileName;
    }

    
//接收struts.xml文件配置值的方法
    public String getSavePath() {
        
return savePath;
    }

    
//返回上传文件保存位置
    public void setSavePath(String savePath) {
        
this.savePath = savePath;
    }

    
    @Override
    
public String execute() throws Exception {
        
//以服务器的文件保存地址和原有文件名建立上传文件输出流
        FileOutputStream fos = new FileOutputStream(getSavePath() + "\\" + getUploadFileName());
        FileInputStream fis 
= new FileInputStream(getUpload());
        
byte[] buffer = new byte[1024];
        
int len = 0;
        
while ((len = fis.read(buffer)) > 0{
            fos.write(buffer, 
0, len);
        }

        
return SUCCESS;
    }

    
}


    上面的Action和普通的Action没有任何区别。只是多了几个属性而已。如果表单中包含一个name属性为xxx的文件域,则对应的Action需要使用3个属性来封装该文件域的信息:类型为File的xxx属性封装了该文件的内容;类型为String的xxxFileName属性封装了该文件域对应的文件的文件名;类型为String的xxxContentType属性封装了该文件域对应的文件类型。除此之外,配置了savePath来依赖注入文件上传后的保存地址。具体的Action配置如下:

<? xml version="1.0" encoding="GBK" ?>
<! DOCTYPE struts PUBLIC
    "-//Apache Software Foundation/ /DTD Struts Configuration 2.1/ /EN"
    "http://struts.apache.org/dtds/struts-2.1.dtd"
>
< struts >
    
< package  name ="strutsqs"  extends ="struts-default" >
        
< action  name ="upload"  class ="com.struts.test.action.UploadAction" >
    
< param  name ="savePath" > /upload </ param >          < result > /succ.jsp </ result >
        
</ action >
    
</ package >
</ struts >


    一般我们上传文件都不是无限制地上传的,需要制定一些例如文件类型,文件大小等限制。我们可以通过配置Struts2中的拦截器进行文件过滤。Struts2中文件上传的拦截器是fileUpload。配置fileUpload拦截器,可以为其指定两个参数:

    allowedTypes:该参数指定允许上传文件的类型,多了文件类型之间以英文逗号隔开。

    maximuxSize:该参数指定允许上传文件大小,单位是字节。

    通过配置fileUpload拦截器,可以轻松地实现文件过滤,当文件过滤失败后,系统自动转入input视图。当然,我们必须显式地为该Action配置defaultStack的拦截器引用。

<? xml version="1.0" encoding="GBK" ?>
<! DOCTYPE struts PUBLIC
    "-//Apache Software Foundation/ /DTD Struts Configuration 2.1/ /EN"
    "http://struts.apache.org/dtds/struts-2.1.dtd"
>
< struts >
    
< package  name ="strutsqs"  extends ="struts-default" >
        
< action  name ="upload"  class ="com.struts.test.action.UploadAction" >
            
< interceptor-ref  name ="fileUpload" >
                            
< param  name ="allowedTypes" > image/bmp,image/png,image/gif,image/jpeg </ param >
                            
< param  name ="maximumSize" > 2000 </ param >
                        
</ interceptor-ref >
                        
< interceptor-ref  name ="defaultStack" />
                        
< param  name ="savePath" > /upload </ param >
            
< result  name ="input" > /upload.jsp </ result >
            
< result > /succ.jsp </ result >
        
</ action >
    
</ package >
</ struts >


    如果需要使用Pell上传, 需要使用插件struts2-pell-multipart-plutin-2.1.6.jar文件。此压缩包中有一个PellMultiPartRequest类。同时在struts-plugin.xml中有如下Bean配置:

         <bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="pell" class="org.apache.struts2.dispatcher.multipart.PellMultiPartRequest" />
   指明了解析接口的实现类。有了这个声明,我们只需在struts.xml中显式地声明一下sturts.multipart.parser的值为pell即可:

         <constant name="struts.multipart.parser" value="pell"/>

         说道此处,上传基本说完了。如果需要同时上传多了文件,只要将Action中涉及文件上传的属性声明为数组或List即可。

         Struts2的文件下载也和普通Action没有区别,只是返回的是InputStream流而已。

import  java.io.InputStream;

import  com.opensymphony.xwork2.ActionSupport;
import  org.apache.struts2.ServletActionContext;

public   class  FileDownloadAction  extends  ActionSupport  {

    
private static final long serialVersionUID = 7160810536224371999L;
    
//该属性是依赖注入的属性,可以在配置文件中动态指定该属性值
    private String inputPath;

    
public String getInputPath() {
        
return inputPath;
    }


    
public void setInputPath(String inputPath) {
        
this.inputPath = inputPath;
    }

    
    
    
public InputStream getTargetFile() throws Exception {
         
return ServletActionContext.getServletContext().getResourceAsStream(inputStream);
    }

}


    代码很简单,关键是需要配置stream类型的结果。配置stream类型的结果需要指定如下4个属性:

  • contentType:指定被下载文件的文件类型
  • inputName:指定被下载文件的入口流入流
  • contentDisposition:指定下载的文件名
  • bufferSize:指定下载文件时的缓冲大小

     

< action  name ="download"  class ="com.struts.test.action.DownloadAction" >
    
< param  name ="inputPath" > \images\t.jpg </ param >
    
< result  name ="success"  type ="stream" >
        
< param  name ="contentType" > image/jpg </ param >
        
<!--  指定getTargetFile()方法返回被下载文件的InputStream -->
        
< param  name ="inputName" > targetFile </ param >
        
< param  name ="contentDisposition" > filename="wjc_lgo.jpg" </ param >
        
< param  name ="bufferSize" > 4096 </ param >
    
</ result >
</ action >