Struts2中使用Common-FileUpload实现文件上传

来源:互联网 发布:动感单车音乐 知乎 编辑:程序博客网 时间:2024/05/16 10:51

在web应用中,文件上传似乎是很常见的,但是采用传统的方法不但复杂而且难以控制,需要写很多代码,像控制文件大小、文件类型的过滤、存放目录等等。这些复杂的问题在Struts2中已经不存在了,struts2默认使用common-fileupload实现文件的上传。在struts.properties中我们可以看到:struts.multipart.parser=Jakarta 。下面我们就以Common-FileUpload来实现文件上传。 

首先,把commons-fileupload.jar和commons-io.jar拷贝到classpath路径下。 

建立一个上传文件的页面,upload.jsp。 

<%@ page contentType="text/html; charset=utf-8" %> 
<%@taglib prefix="s" uri="/struts-tags"%> 
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" > 
<html xmlns ="http://www.w3.org/1999/xhtml" > 
<head> 
    <title> Struts 2 File Upload </title > 
</head > 
<body > 
    <div style="color.red"> 
        <s:fielderror /> 
    </div> 
    <s:form action ="upload" method ="post" enctype ="multipart/form-data" > 
        <s:textfield name ="title" label ="文件标题" /> 
        <s:file name ="upload" label ="选择文件" />      
        <s:submit value="上传" /> 
    </s:form> 
</body > 
</html > 


上传成功后的succ.jsp 

<%@ page contentType="text/html;charset=utf-8" %> 
<%@ taglib prefix="s" uri="/struts-tags"%> 
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" > 
<html xmlns ="http://www.w3.org/1999/xhtml" > 
<head> 
    <title> Struts 2 File Upload </title > 
</head> 
<body> 
    <div style ="padding: 3px; border: solid 1px #cccccc; text-align: center" > 
        <img src ='upload/<s:property value ="uploadFileName" /> ' /> 
        <br /> 
        <s:property value ="title" /> 
    </div > 
</body > 
</html > 


然后编写UploadAction.java 

/** *//** 

* @author <a href="mailto:flustar2008@163.com">flustar</a> 
* @version 1.0 
* Creation date: Feb 15, 2008 10:24:36 PM 
*/ 
package test; 

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

import org.apache.struts2.ServletActionContext; 

import com.opensymphony.xwork2.ActionSupport; 

public class UploadAction extends ActionSupport{ 
    private static final long serialVersionUID = -7887613751080170362L; 
    private String title;//设置上传文件的标题 
    private File upload;//封装上传文件 
    private String uploadFileName;//设置上传文件的文件名 
    private String uploadContentType;//上传文件的类型 
    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 getUploadFileName() { 
        return uploadFileName; 
    } 
    public void setUploadFileName(String uploadFileName) { 
        this.uploadFileName = uploadFileName; 
    } 
    public String getUploadContentType() { 
        return uploadContentType; 
    } 
    public void setUploadContentType(String uploadContentType) { 
        this.uploadContentType = uploadContentType; 
    } 
    public String getSavePath() { 
        System.out.println(ServletActionContext.getServletContext().getRealPath(savePath)); 
        return ServletActionContext.getServletContext().getRealPath(savePath); 
    } 
    public void setSavePath(String savePath) { 
        this.savePath = savePath; 
        System.out.println("savePath: "+savePath); 
    } 
    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; 
    } 



编写struts.xml 

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE struts PUBLIC 
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 
    "http://struts.apache.org/dtds/struts-2.0.dtd"> 
<struts> 
    <package name="blog" extends="struts-default"> 
        
<action name="upload" class="test.UploadAction"> 
            <!-- Struts2内置的文件上传拦截器 --> 
            <interceptor-ref name="fileUpload"> 
                <param name="allowedTypes">image/bmp,image/x-png,image/gif,image/pjpeg</param> 
                <param name="maximumSize">2048000</param> 
            </interceptor-ref> 
            <interceptor-ref name="defaultStack" /> 
            <param name="savePath">/upload</param> 
            <result>/succ.jsp</result> 
            <result name="input">/upload.jsp</result> 
        </action> 
        
</package> 
        
</struts> 


编写struts.properties 


struts.custom.i18n.resources=mess 

struts.multipart.parser=jakarta 

struts.multipart.maxSize=10000000 



编写国际化的资源文件mess.properties 


struts.messages.error.content.type.not.allowed="Thetypeisnotbeallowed!" 

struts.messages.error.file.too.large="Thefileistoolarge!" 

struts.messages.error.uploading="unknownerror" 



在这里我没有把调试的过程写出来,这完全没必要,网上已经有很多这方面的例子了,但是网上好多例子都有一个通病,那就是错误的信息实在是太多了,都是搜索引擎惹得祸。按照上面的步骤来做,很难成功!我按照上面的步骤来操作,发现两个比较普遍的错误: 

1) 不能上传png和jpg类型的图片。解决办法可以参考上面的struts.xml。 

2) 上传过大的文件没有提示信息,而是直接抛出下面的异常: 

   org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (2359629) exceeds the configured maximum (2097152) 

为什么会出现这个错误?刚开始我还以为是Struts2的一个bug,于是我就开始研究是struts2内置的fileUpload拦截器,我研究了FileUploadInterceptor.java的源代码并调试了半天依然不能解决这个问题,我都被它快折磨死了。最后我想起了在我们编写struts.properties中有这么一句struts.multipart.parser=Jakarta,实际上这一句也可以不写因为这是struts2为了支持文件上传默认的。那么这个Jakarta到底是什么东西呢?实际上Jakarta实际上就是org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest类。打开JakartaMultiPartRequest.java的源代码你会发现这个类实现了MultiPartRequest接口,在这个类封装了对底层ServletFileUpload的操作,由于common-fileupload组件默认最大支持上传文件的大小为2M,当我们上传大于2M的文件时,就会出现上面的异常。是这个异常的发生导致了fileUpload拦截器没有机会执行,所以我看到的是页面没有任何变化,也没有任何提示信息,只是在控制台打印出了上面的异常。解决的办法在struts.properties文件中把struts.multipart.maxSize设置成一个比较大的值,也是就说maxSize远远要大于可能上传文件的大小和fileUpload拦截器中maxinumSize的值,可参见上面的struts.xml和struts.properties文件。

原创粉丝点击