简单记录之struts2的文件上传和下载 ------------------------------多个文件上传------------------------------

-----------------------------单个文件上传-------------------------------

(1)上传页面:testFileUpload2.jsp

<form action="actions/upload2" method="post" enctype="multipart/form-data">
    上传文件:<input type="file" name="myfile" ><br>
    <input type="submit" value="ok">
</form>

注意form属性要加上enctype="multipart/form-data"

上传成功页面:uploadOK.jsp(以下均相同):

上传成功!

(2)提交的Action: UploadAction2 

package action;

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

import com.opensymphony.xwork2.ActionSupport;

public class UploadAction2 extends ActionSupport {

    private File myfile;////上传的文件
    private String myfileFileName;//上传的文件名
    private String myfileContentType;//上传的文件类型
     
  //省略getter、setter
@Override public String execute() throws Exception { System.out.println("上传的文件:"+myfile); System.out.println("上传的真实文件名: "+myfileFileName); System.out.println("文件类型:"+myfileContentType); InputStream is = null; OutputStream os = null; //假如要把上传的文件放到e:/temp File file = new File("e:/temp"); //如果e盘下不存在temp就创建目录 if(!file.exists()) { file.mkdirs(); } //以文件的真实名称保存 file = new File(file,myfileFileName); try { //读取上传的文件 is = new FileInputStream(myfile); //建立一个1k大小的缓冲区 byte[] b = new byte[1024]; //把上传的文件输出到os中 os = new FileOutputStream(file); int len = 0; //len=-1表示读到文件结尾 while((len = is.read(b))>0) { os.write(b, 0, len); } } catch (Exception e) { e.printStackTrace(); }finally{ is.close(); os.close(); } return super.execute(); } }

(3)struts.xml的配置

<package name="test" namespace="/actions" extends="struts-default">
<action name="upload2" class="action.UploadAction2">
            <interceptor-ref name="fileUpload">
                <param name="allowedTypes">text/plain</param>
                <param name="maximumSize">10000</param>
            </interceptor-ref>
            <interceptor-ref name="defaultStack"></interceptor-ref>
            <result name="input">/testFileUpload2.jsp</result>
            <result>/uploadOK.jsp</result>
        </action>
</package>

在文件上传的时候,有可能需要对文件的大小和类型做出限制。Struts2支持直接在fileUpload拦截器上设置参数来进行限制。

在引用fileUpload拦截器的时候,可以指定三个参数(指定<param>子元素):

 allowedTypes:指定允许上传的文件的类型,如果存在多种类型,以逗号隔开。如果不知道某种文件的ContentType可以先上传一下试试,在后台输出ContentType来。

 maximumSize:指定允许上传的文件的最大字节数。

 allowedExtensions:指定允许上传的文件的扩展名。

如果上传的文件不满足以上的参数指定的条件,则会跳转到一个叫input的<result>上,一般input都会指回到提交之前的页面,也就是文件上传页面。

可以在提交页面的合适的地方加上<s:fielderror/>来显示错误信息,经本人测试,struts上传文件时是先检查文件大小再检查文件类型,所以如过上传的非txt类型文件(比如*.html)超过1000字节的话是”报文件太大”的错误,只需要把最大字节数改大超过html文件,报告上传类型错误便可解决。

(4)运行结果

简单记录之struts2的文件上传和下载
------------------------------多个文件上传------------------------------

简单记录之struts2的文件上传和下载
------------------------------多个文件上传------------------------------

注意上传时文件要确保存在!

Struts2在实现文件上传的时候,还有一个小问题,那就是默认上传文件的大小是不能超过2097152字节的。注意:上传的文件首先要存在,否则会抛异常。

解决办法之一:在struts.xml加入如下的常量定义:

<constant name="struts.multipart.maxSize" value="10000000" />

这里设置上传文件的最大值为大约10M。

当上传的时候,控制台上出现:Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir时,可以在struts.xml中添加如下配置解决:

<constant name="struts.multipart.saveDir" value="/tmp"/>

只需要在提交页面上添加同名的多个文件输入域,然后在Action中对应使用File类型的数组去接收这些参数即可

(1)上传页面:testMutiFileUpload.jsp

<form action="actions/mutiupload" method="post" enctype="multipart/form-data">
    上传文件:<input type="file" name="myFile"><br>
    上传文件:<input type="file" name="myFile"><br>
    上传文件:<input type="file" name="myFile"><br>
    <input type="submit" value="ok">
</form>

注意name属性值是一样的

(2)提交的action:MutiUploadAction

package action;

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

import com.opensymphony.xwork2.ActionSupport;

public class MutiUploadAction extends ActionSupport {

    File[] myFile;//上传的文件
    String[] myFileFileName;//上传的文件名
    String[] myFileContentType;//上传的文件类型
    
    //省略getter、setterpublic void setMyFileContentType(String[] myFileContentType) {
        this.myFileContentType = myFileContentType;
    }

    @Override
    public String execute() throws Exception {
        InputStream is = null;
        OutputStream os =null;
        
        //afile存放上传的文件名,注意初始化数组
        File[] afile = new File[myFileFileName.length];
        File file = new File("e:/temp");
        if(!file.exists()) {
            file.mkdirs();
        }
        
        for(int i=0;i<myFileFileName.length;i++) {
            //依次输出上传的文件类型
            System.out.println("上传文件的类型:"+myFileContentType[i]);
            
            try {
                //把上传的文件名依次存到aFile数组
                afile[i] = new File(file,myFileFileName[i]);
                ////将上传过来的文件输出到os中,以真实的文件名作为名字
                os = new FileOutputStream(afile[i]);
                //依次读取上传的文件
                is = new FileInputStream(myFile[i]);                
                byte[] b = new byte[1024];
                int len = 0;
                while((len=is.read(b))>0)
                {
                    os.write(b, 0, len);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                is.close();
                os.close();        
            }
        }
        return super.execute();
    }
}

(3)struts.xml的配置

<package name="test" namespace="/actions" extends="struts-default">
<action name="mutiupload" class="action.MutiUploadAction">        
            <result>
                /uploadOK.jsp
            </result>            
        </action>
</package>

(4)运行结果

简单记录之struts2的文件上传和下载
------------------------------多个文件上传------------------------------

简单记录之struts2的文件上传和下载
------------------------------多个文件上传------------------------------

后台打印:

简单记录之struts2的文件上传和下载
------------------------------多个文件上传------------------------------


------------------------------文件下载
 ---------------------------------------

会用到struts的stream类型的Result, Result会返回一个InputStream,只需要让这个InputStream能读到用户想要下载的文件即可。

(1)文件下载jsp页面:testFileDownload.jsp

<h2><a href="actions/download">文件下载</a></h2>

(2)实现下载的action

package action;

import java.io.File;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import com.opensymphony.xwork2.ActionSupport;

public class DownloadAction extends ActionSupport {
    
    public String getDownloadFileName() {
        String name = "";
        try {         
            name = new String("测试".getBytes(),"ISO8859-1");
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        return name+".txt";
    }

    public InputStream getInputStream() throws FileNotFoundException {
        File file = new File("e:/temp/test.txt");
        return new FileInputStream(file);
    }
}

注意:E:/temp下要存在test.txt,否则会抛异常。

动态地设置默认的下载名时,如果是英文的文件名就不需要做上面的编码转换,可直接返回字符串。

(3)struts.xml的配置

<package name="test" namespace="/actions" extends="struts-default">
<action name="download" class="action.DownloadAction">
            <result type="stream">
                <param name="contentDisposition">attachment;filename=${downloadFileName}</param>
            </result>    
        </action>
</package>

  contentType:下载文件的类型。stream类型的结果共可以指定7个参数:

   contentLength:下载文件的长度,用于浏览器的进度条显示。

  contentDisposition:指定文件下载的默认名字,如果不指定则使用Action名.action。

  inputName:Action中用于返回InputStream的get方法的名字,默认为inputStream,因此,我们的Action中定义了getInputStream的方法。

  bufferSize:缓冲区大小,默认为1k。

  allowCaching:是否允许浏览器进行缓存。

  contentCharSet:HTTP响应头信息中的编码方式。

在以上7个参数中,最常用的是使用contentDisposition来指定默认的文件下载名,其他的使用默认即可

(4)运行结果

简单记录之struts2的文件上传和下载
------------------------------多个文件上传------------------------------

简单记录之struts2的文件上传和下载
------------------------------多个文件上传------------------------------