熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

在Struts 2中實現文件上傳

2013-11-23 20:16:44  來源: Java開源技術 

  Struts 是通過Commons FileUpload文件上傳Commons FileUpload通過將HTTP的數據保存到臨時文件夾然後Struts使用fileUpload攔截器將文件綁定到Action的實例中從而我們就能夠以本地文件方式的操作浏覽器上傳的文件
                                                                                    
具體實現

    前段時間Apache發布了Struts GA所以本文的實現是以該版本的Struts作為框架的以下是例子所依賴類包的列表依賴類包的列表 
清單 依賴類包的列表

  首先創建文件上傳頁面FileUploadjsp內容如下
<% @ page language = java contentType = text/html; charset=utf pageEncoding = utf %>
<% @ taglib prefix = s uri = /strutstags %>

<! DOCTYPE html PUBLIC //WC//DTD XHTML Transitional//EN transitionaldtd >
< html xmlns = >
< head >
    < title > Struts File Upload </ title >
</ head >
< body >
    < s:form action =fileUpload method =POST enctype =multipart/formdata >
        < s:file name =myFile label =Image File />
        < s:textfield name =caption label =Caption />        
        < s:submit />
    </ s:form >
</ body >
</ html >

清單 FileUploadjsp

  在FileUploadjsp中先將表單的提交方式設為POST然後將enctype設為multipart/formdata這並沒有什麼特別之處接下來<s:file/>標志將文件上傳控件綁定到Action的myFile屬性

  其次是FileUploadActionjava代碼


package tutorial;

import javaioBufferedInputStream;
import javaioBufferedOutputStream;
import javaioFile;
import javaioFileInputStream;
import javaioFileOutputStream;
import javaioInputStream;
import javaioOutputStream;
import javautilDate;

import orgapachestrutsServletActionContext;

import comopensymphonyxworkActionSupport;

public class FileUploadAction extends ActionSupport {
    private static final long serialVersionUID = l ;
    private static final int BUFFER_SIZE = * ;
   
    private File myFile;
    private String contentType;
    private String fileName;
    private String imageFileName;
    private String caption;
   
    public void setMyFileContentType(String contentType) {
        ntentType = contentType;
   }
   
    public void setMyFileFileName(String fileName) {
        this fileName = fileName;
   }
       
    public void setMyFile(File myFile) {
        this myFile = myFile;
   }
   
    public String getImageFileName() {
        return imageFileName;
   }
   
    public String getCaption() {
        return caption;
   }

    public void setCaption(String caption) {
        this caption = caption;
   }
   
    private static void copy(File src File dst) {
        try {
           InputStream in = null ;
           OutputStream out = null ;
            try {                
               in = new BufferedInputStream( new FileInputStream(src) BUFFER_SIZE);
               out = new BufferedOutputStream( new FileOutputStream(dst) BUFFER_SIZE);
                byte [] buffer = new byte [BUFFER_SIZE];
                while (inread(buffer) > ) {
                   outwrite(buffer);
               }
           } finally {
                if ( null != in) {
                   inclose();
               }
                if ( null != out) {
                   outclose();
               }
           }
       } catch (Exception e) {
           eprintStackTrace();
       }
   }
   
    private static String getExtention(String fileName) {
        int pos = fileNamelastIndexOf( );
        return fileNamesubstring(pos);
   }

   @Override
    public String execute()     {        
       imageFileName = new Date()getTime() + getExtention(fileName);
       File imageFile = new File(ServletActionContextgetServletContext()getRealPath( /UploadImages ) + / + imageFileName);
       copy(myFile imageFile);
        return SUCCESS;
   }
   
} 清單 tutorial/FileUploadActionjava

  在FileUploadAction中我分別寫了setMyFileContentTypesetMyFileFileNamesetMyFile和setCaption四個Setter方法後兩者很容易明白分別對應FileUploadjsp中的<s:file/>和<s:textfield/>標志但是前兩者並沒有顯式地與任何的頁面標志綁定那麼它們的值又是從何而來的呢?其實<s:file/>標志不僅僅是綁定到myFile還有myFileContentType(上傳文件的MIME類型)和myFileFileName(上傳文件的文件名該文件名不包括文件的路徑)因此<s:file name=xxx />對應Action類裡面的xxxxxxContentType和xxxFileName三個屬性

  FileUploadAction作用是將浏覽器上傳的文件拷貝到WEB應用程序的UploadImages文件夾下新文件的名稱是由系統時間與上傳文件的後綴組成該名稱將被賦給imageFileName屬性以便上傳成功的跳轉頁面使用

  下面我們就來看看上傳成功的頁面


<% @ page language = java contentType = text/html; charset=utf pageEncoding = utf %>
<% @ taglib prefix = s uri = /strutstags %>

<! DOCTYPE html PUBLIC //WC//DTD XHTML Transitional//EN transitionaldtd >
< html xmlns = >
< head >
    < title > Struts File Upload </ title >
</ head >
< body >
    < div style =padding: px; border: solid px #cccccc; textalign: center >
        < img src =UploadImages/<s:property value =imageFileName /> />
        < br />
        < s:property value =caption />
    </ div >
</ body >
</ html > 清單 ShowUploadjsp

  ShowUploadjsp獲得imageFileName將其UploadImages組成URL從而將上傳的圖像顯示出來

  然後是Action的配置文件


<? xml version= encoding=UTF ?>

<! DOCTYPE struts PUBLIC
    //Apache Software Foundation//DTD Struts Configuration //EN
    dtd >

< struts >
    < package name =fileUploadDemo extends =strutsdefault >
        < action name =fileUpload class =tutorialFileUploadAction >
            < interceptorref name =fileUploadStack />
            < result name =success > /ShowUploadjsp </ result >
        </ action >
    </ package >
</ struts > 清單 strutsxml

  fileUpload Action顯式地應用fileUploadStack的攔截器

  最後是webxml配置文件


<? xml version= encoding=UTF ?>
< webapp id =WebApp_ version =
    xmlns =
    xmlns:xsi =instance
    xsi:schemaLocation = app__xsd >

    < displayname > Struts Fileupload </ displayname >

    < filter >
        < filtername > strutscleanup </ filtername >
        < filterclass >
            orgapachestrutsdispatcherActionContextCleanUp
        </ filterclass >
    </ filter >
    
    < filter >
        < filtername > struts </ filtername >
        < filterclass >
            orgapachestrutsdispatcherFilterDispatcher
        </ filterclass >
    </ filter >
    
    < filtermapping >
        < filtername > strutscleanup </ filtername >
        < urlpattern > /* </ urlpattern >
    </ filtermapping >

    < filtermapping >
        < filtername > struts </ filtername >
        < urlpattern > /* </ urlpattern >
    </ filtermapping >

    < welcomefilelist >
        < welcomefile > l </ welcomefile >
    </ welcomefilelist >

</ webapp > 清單 WEBINF/webxml

  發布運行應用程序在浏覽器地址欄中鍵入出現圖示頁面

  
清單 FileUpload頁面

  選擇圖片文件填寫Caption並按下Submit按鈕提交出現圖示頁面

  
清單 上傳成功頁面

更多配置

  在運行上述例子如果您留心一點的話應該會發現服務器控制台有如下輸出


Mar : : PM orgapachestrutsdispatcherDispatcher getSaveDir
INFO: Unable to find strutsmultipartsaveDir property setting Defaulting to ntexttempdir
Mar : : PM orgapachestrutsinterceptorFileUploadInterceptor intercept
INFO: Removing file myFile C:\Program Files\Tomcat \work\Catalina\localhost\Struts_Fileupload\upload_c_e__ff_tmp 清單 服務器控制台輸出

  上述信息告訴我們strutsmultipartsaveDir沒有配置strutsmultipartsaveDir用於指定存放臨時文件的文件夾該配置寫在strutsproperties文件中例如如果在strutsproperties文件加入如下代碼


strutsmultipartsaveDir = /tmp 清單 struts配置

  這樣上傳的文件就會臨時保存到你根目錄下的tmp文件夾中(一般為c:\tmp)如果此文件夾不存在Struts 會自動創建一個

錯誤處理

  上述例子實現的圖片上傳的功能所以應該阻止用戶上傳非圖片類型的文件在Struts 中如何實現這點呢?其實這也很簡單對上述例子作如下修改即可

  首先修改FileUploadjsp在<body>與<s:form>之間加入<s:fielderror />用於在頁面上輸出錯誤信息

  然後修改strutsxml文件將Action fileUpload的定義改為如下所示


        < action name =fileUpload class =tutorialFileUploadAction >
            < interceptorref name =fileUpload >
                < param name =allowedTypes >
                    image/bmpimage/pngimage/gifimage/jpeg
                </ param >
            </ interceptorref >
            < interceptorref name =defaultStack />            
            < result name =input > /FileUploadjsp </ result >
            < result name =success > /ShowUploadjsp </ result >
        </ action > 清單 修改後的配置文件

  顯而易見起作用就是fileUpload攔截器的allowTypes參數另外配置還引入defaultStack它會幫我們添加驗證等功能所以在出錯之後會跳轉到名稱為input的結果也即是FileUploadjsp

  發布運行應用程序出錯時頁面如下圖所示

  
清單 出錯提示頁面

  上面的出錯提示是Struts 默認的大多數情況下我們都需要自定義和國際化這些信息通過在全局的國際資源文件中加入ntenttypenotallowed=The file you uploaded is not a image可以實現以上提及的需求對此有疑問的朋友可以參考我之前的文章《在Struts 中國際化(in)您的應用程序

  實現之後的出錯頁面如下圖所示

  
清單 自定義出錯提示頁面

  同樣的做法你可以使用參數maximumSize來限制上傳文件的大小它對應的字符資源名為ssageserrorfiletoolarge

  字符資源ssageserroruploading用提示一般的上傳出錯信息

多文件上傳

  與單文件上傳相似Struts 實現多文件上傳也很簡單你可以將多個<s:file />綁定Action的數組或列表如下例所示


< s:form action =doMultipleUploadUsingList method =POST enctype =multipart/formdata >
    < s:file label =File () name =upload />
    < s:file label =File () name =upload />
    < s:file label =FIle () name =upload />
    < s:submit />
</ s:form > 清單 多文件上傳JSP代碼片段

  如果你希望綁定到數組Action的代碼應類似


    private File[] uploads;
    private String[] uploadFileNames;
    private String[] uploadContentTypes;

    public File[] getUpload() { return this uploads; }
    public void setUpload(File[] upload) { this uploads = upload; }

    public String[] getUploadFileName() { return this uploadFileNames; }
    public void setUploadFileName(String[] uploadFileName) { this uploadFileNames = uploadFileName; }

    public String[] getUploadContentType() { return this uploadContentTypes; }
    public void setUploadContentType(String[] uploadContentType) { this uploadContentTypes = uploadContentType; } 清單 多文件上傳數組綁定Action代碼片段

  如果你想綁定到列表則應類似


    private List < File > uploads = new ArrayList < File > ();
    private List < String > uploadFileNames = new ArrayList < String > ();
    private List < String > uploadContentTypes = new ArrayList < String > ();

    public List < File > getUpload() {
        return this uploads;
   }
    public void setUpload(List < File > uploads) {
        this uploads = uploads;
   }

    public List < String > getUploadFileName() {
        return this uploadFileNames;
   }
    public void setUploadFileName(List < String > uploadFileNames) {
        this uploadFileNames = uploadFileNames;
   }

    public List < String > getUploadContentType() {
        return this uploadContentTypes;
   }
    public void setUploadContentType(List < String > contentTypes) {
        this uploadContentTypes = contentTypes;
   } 清單 多文件上傳列表綁定Action代碼片段

總結

  在Struts 中實現文件上傳的確是輕而易舉您要做的只是使用<s:file />與Action的屬性綁定這又一次有力地證明了Struts 的簡單易用


From:http://tw.wingwit.com/Article/program/Java/ky/201311/28217.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.