Struts2中使用Common-FileUpload實現文件上傳(二)

web應用中,文件上傳似乎是很常見的,但是採用傳統的方法不但複雜而且難以控制,需要寫很多代碼,像控制文件大小、文件類型的過濾、存放目錄等等。這些複雜的問題在Struts2中已經不存在了,struts2默認使用common-fileupload實現文件的上傳。在struts.properties中我們可以看到:struts.multipart.parser=Jakarta 。下面我們就以Common-FileUpload來實現文件上傳。

首先,把commons-fileupload.jarcommons-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:[email protected]">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) 不能上傳pngjpg類型的圖片。解決辦法可以參考上面的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.xmlstruts.properties文件。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章