struts2文件上传下载详解

     struts2没有提供自己的请求解析器,也就是说,struts2不会自己去处理multipart/form-data的请求,它需要调用其他请求解析器,将HTTP请求中的表单域解析出来,但struts2在原有的上传解析器上作了进一步封装,更进一步简化了文件上传,Struts2的struts.properties配置文件中,配置struts2的上传文件解析器struts.multipart.parser=jakarta(srtuts2默认),也可以设置为常用的cos,pell等。

       struts2实现上传下载所必须的2个jar包commons-fileupload-xxx.jarcommons-io-xxx.jar

一、文件上传

  1.  单文件上传

(1)单文件上传表单视图:

  <body>
   <form action="/test/upload.action" enctype="multipart/form-data" method="post">
       <input name="uploadfile" type="file">
       <input type="submit" value="上传">
   </form>
  </body>

注意:表单必须设置enctype="multipart/form-data"method="post"属性,否则上传会出错。

2. 单文件上传Action类

/**
 * 文件上传类
 * @author Ye
 *
 */  
 public class UploadAction extends ActionSupport{

        <!--获取上传文件,名称必须和表单file控件名相同-->     
         private File uploadfile;

         <!--获取上传文件名,命名格式:表单file控件名+FileName(固定)-->    
         private String uploadfileFileName;

         //获取上传文件类型,命名格式:表单file控件名+ContentType(固定) 
         private String uploadfileContentType;     

         ...//省略属性的getter、setter方法
      
         //方法一:使用FileUtils的copyFile来实现文件上传
         public String upload() throws IOException
         {
                 //设置上传文件目录  
                 String realpath = ServletActionContext.getServletContext().getRealPath("/image");

                 //判断上传文件是否为空    
                 if(uploadfile!=null)
                 {
                         //设置目标文件(根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例)
                         File savefile = new File(realpath,uploadfileFileName);

                         // 判断上传目录是否存在          
                         if(!savefile.getParentFile().exists())
                               savefile.getParentFile().mkdirs();

                         //把文件uploadfile 拷贝到 savefile 里,FileUtils类需要commons-io-x.x.x.jar包支持
                         FileUtils.copyFile(uploadfile,savefile);

                         //设置request对象值     
                         ActionContext.getContext().put("message", "上传成功!");
                 }
                 return "success";
          }

          //方法二:使用文件流来实现文件上传
          public String upload() throws IOException
          {
                FileOutputStream fos = new FileOutputStream("D:\\"+uploadfileFileName);
        
                FileInputStream fis = new FileInputStream(uploadfile);
        
                byte[] buffer = new byte[1024];
        
                int len = 0;
        
                while((len=fis.read(buffer))>0)
                {
                   fos.write(buffer,0,len);
                }
                return "success";
           }

 }

注意:记得Action类要继承ActionSupport

3.  配置struts.xml文件

<package name="hello" namespace="/test" extends="struts-default">
    <action name="upload" class="action.UploadAction" method="upload">  
   
        <!-- 在struts.xml文件中使用constant元素指定在全局的struts.properties文件中自定义出错信息,value值为*.properties类型的文件名 -->
        <constant name="struts.custom.i18n.resources" value="struts"></constant> 

        <!-- 配置fileUpload的拦截器 -->
        <interceptor-ref name="fileUpload">
 
           <!-- 配置允许上传的文件类型 -->
           <param name="allowedTypes">image/bmp,image/gif,image/jpg</param>    
      
           <!--配置允许上传文件的扩展名,如果有多个用","隔开 -->    
           <param name="allowedExtensions">txt,excel,ppt</param>  
              
           <!-- 配置允许上传的文件大小,最大为20k -->
           <param name="maximumSize">20480</param>

        </interceptor-ref>

        <!-- 配置struts2的默认拦截器栈  -->
        <interceptor-ref name="defaultStack"></interceptor-ref>

       <result>/success.jsp</result>

       <!-- 上传失败时返回的视图页面 -->
       <result name="input">/index.jsp</result>   

     </action>
</package>
注意:(1) 拦截器实现要在UploadAction类中继承ActionSupport,否则拦截器无效。

          (2) 必须显示配置引用Struts默认的拦截器栈:defaultStack

          (3) struts的默认上传文件大小为2M,可以用常量来控制扩大上传限制:

                 <constant name="struts.multipart.maxSize" value="104857600"></constant>   //设置上传上限为10M

                  真正的视频网站会使用插件而不是这种web上传的方式上传文件,因为Web上传的稳定性差。

          (4) 在失败的页面视图中使用<s:fielderror/>标签可以输出上传失败的原因,错误信息默认是struts提供的英文字符,如果需要将其转换为中文字符,可在国际化资源文件中配置以下代码:

struts.properties:

struts.messages.error.content.type.not.allowed = 上传的文件类型不正确         
struts.messages.error.file.too.large= 上传的文件太大
struts.messages.error.uploading=上传时出现未知错误

  2.  多文件上传:

   多文件上传原理同单文件上传,主要是在action中定义File[]数组来接收多文件数据。

(1)多文件上传表单视图:

<body>
   <s:form action="multiUpload" method="post" namespace="/test3" enctype="multipart/form-data">
       <s:file name="uploadfile" label="文件1"></s:file>
       <s:file name="uploadfile" label="文件2"></s:file>
       <s:file name="uploadfile" label="文件3"></s:file>
       <s:file name="uploadfile" label="文件4"></s:file>
       <s:submit value="上传"></s:submit>
    </s:form>
</body> 

(2)多文件上传Action类:

public class UploadAction extends ActionSupport {
	private File[] uploadfile;
	private String[] uploadfileFileName;
	private String[] uploadfileContentType;

        ...//省略属性的getter、setter方法

        //方法一:
	public String upload() throws IOException {
		String realpath = ServletActionContext.getServletContext().getRealPath("/image");
		if (uploadfile != null) {
			File savepath = new File(realpath);
			if (!savepath.exists())
				savepath.mkdirs();
			for (int i = 0; i < uploadfile.length; i++) {
				File savefile = new File(realpath, uploadfileFileName[i]);
				FileUtils.copyFile(uploadfile[i], savefile);
			}
			ActionContext.getContext().put("message", "上传成功!");
		}
		return "success";
	}

        //方法二:
        public String upload() throws IOException
        {
             for(int i = 0 ; i < uploadfile.length; i ++)
             {
                    FileOutputStream fos = new FileOutputStream("D:\\"+uploadfileFileName[i]);
            
                    FileInputStream fis = new FileInputStream(uploadfile[i]);
            
                    byte [] buffer = new byte[1024];
            
                    int len = 0 ;
            
                    while((len = fis.read(buffer))>0)
                    {
                       fos.write(buffer,0,len);
                    }
                    
               }
               return "success";
         }

 }

二、文件下载

(1)文件下载Action类

public class DownloadAction extends ActionSupport {
	
        //downloaPath属性用于封装被下载文件的路径
        private String downloadPath;

        //初始化要保存的文件名
        private String filename;

        //文件保存路径
        private String savePath;

        public String getSavePath() {
            return savePath;
        }

        public void setSavePath(String savePath) {
            this.savePath = savePath;
        }  
     
        public String getFilename() {
               return filename;
        }

        public void setFilename(String filename) {
               this.filename = filename;
        }

        public void setDownloadPath(String downloadPath) {
		this.downloadPath = downloadPath;
        }

       // 隐含属性 targetFile ,用于封装下载文件
	public InputStream getTargetFile() throws FileNotFoundException
	{
		return new FileInputStream(downloadPath);
	}
	
	public String execute()
	{
		return "success";
	}

}
(2)配置struts.xml文件:

 <package name="test3_download" extends="struts-default"> 
   <action name="download" class="com.action.DownloadAction" method="execute">

      <!-- 对Action类中的文件路径参数设置初始值 -->
      <param name="downloadPath">${savePath}</param>
         
         <!-- 设置一个stream类型的result -->
         <result name="success" type="stream">
           
            <!-- 设置下载文件的输入流属性名 -->
            <param name="inputName">targetFile</param>

            <!-- 设置下载文件的文件类型,配置后可以直接在浏览器上浏览,省略则会弹出是保存文件还是打开文件信息的对话框 -->
           <!-- <param name="contentType">image/jpg</param> -->

            <!-- 设置下载文件的文件名 -->
            <param name="contentDisposition">attachment;filename=${filename}</param>

            <!-- 设置下载文件的缓冲 -->
            <param name="bufferSize">2048</param>
       </result>
    </action>
  </package>


  • 12
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜之子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值