使用Struts 2控制文件下載

jopen 8年前發布 | 13K 次閱讀 Struts2 Web框架

          一般來說,文件下載只需要直接在頁面給出一個超級鏈接,該鏈接的href屬性值等于要下載文件的文件名,就可以實現文件下載,如:<a href=checkbox.rar”>checkbox.rar</a>。但是這樣下載存在著一些缺陷:如果該文件的文件名是中文文件名時,下載則會導致下載失敗;如果在下載時需要對用戶的身份進行判斷,來驗證用戶是否有權限來下載該文件時,那么單獨的超級鏈接是不可能實現的。這個時候,我們需要用Struts 2來控制文件下載。</span>

          Struts 2提供了stream結果類型,該結果類型就是專門用于支持文件下載功能的。通過Struts 2的文件下載支持,允許系統控制瀏覽者下載文件的權限,實現文件名是非西歐字符的文件下載。

          首先介紹利用Struts 2實現簡單的文件下載:

public class FileDownloadAction implements Action { 

    public InputStream getInputStream() throws Exception { 

        return new ByteArrayInputStream("Struts 2 下載示例".getBytes()); 

    } 

    public String execute() throws Exception { 

        return SUCCESS; 

    } 

}


 

          該類只是一個簡單的Action處理類。它提供了一個返回inputStream輸入流的方法。該輸入流代表了下載文件的入口。這個方法用來給被下載的數據提供輸入流。

 

          一、利用Struts 2實現文件名非西歐字符文件下載

          有如下一個下載頁面代碼:

<a href="download1.action?image/美女_01.jpg" >下載圖片</a>
<a href="download2.action?image/meinv_01.rar">下載壓縮文件</a>

          上面頁面中包含了兩個下載的鏈接。但是第一個鏈接資源的文件名為中文,這時如果我們單擊第一個超級練級,將會出現如下頁面:


         從上面的頁面中我們可以看到大量的%字符,很明顯,這種文件名師不能夠實現下載的。這時我們可以使用Struts 2的文件下載支持來下載該文件。

         1、實現文件下載的Action

         Struts 2的文件下載Action需要提供一個返回InputStream流的方法。

         代碼如下:

public class FileDownloadAction extends ActionSupport{
    //該屬性可以在配置文件中動態指定該屬性值
    private String inputPath;

    public void setInputPath(String inputPath) {
        this.inputPath = inputPath;
    }

    /*定義一個返回inputStream的方法
     * 該方法將作為下載文件的入口,且需要配置stream類型結果是指定inputName參數
     * inputName參數的值就是方法去掉get前綴、首字母小寫的字符串
     */
    public InputStream getTargetFile() throws Exception{
        //servletContext提供getResourceAsStream()方法
        //返回指定文件對應的輸入流
        return ServletActionContext.getServletContext().getResourceAsStream(inputPath);
    }

    @Override
    public String execute() throws Exception {
        return SUCCESS;
    }
}

         上面的Action中包含了一個getTargetFile()方法,該方法返回一個InputStream輸入流。這個輸入流返回的是下載目標文件的入口。該方法的方法名為getTargetFile,則stream類型的結果映射中inputName參數值是targetFile.

         注:返回InputStream的方法需要配置Stream類型結果時指定inputName參數;該參數值就是方法嗎去掉get前綴,首字母小寫的字符串。

         2、配置Action

         配置文件下載的Action關鍵是需要配置一個類型為stream的結果,該stream類型的結果將使用文件下載作為響應。配置時需要指定以下四個屬性


         由于Stream結果類型的邏輯試圖是返回給客服端一個輸入流,因此不需要指定location屬性。

         配置如下:

<action name="download1" class="com.app.action.FileDownloadAction">
            <!-- 指定被下載資源的位置 -->
            <param name="inputPath">\image\美女_01.jpg</param>
            <!-- 配置結果類型為stream的結果 -->
            <result name="success" type="stream">
                <!-- 指定下載文件的文件類型 -->
                <param name="contentType">image/jpg</param>
                <!-- 指定由getTargetFile()方法返回被下載文件的inputStream -->
                <param name="inputName">targetFile</param>
                <param name="contentDisposition">attachment;filename="meinv1_01.jpg"</param>
                <!-- 指定下載文件的緩沖大小 -->
                <param name="bufferSize">4096</param>
            </result>
        </action>

         通過上面的配置后,就可以實現包含中文文件名的文件下載了。如果在點擊就可以實現下載了。如下:


         二、下載前的授權控制

         有時用戶下載文件之前,我們需要對用戶的身份進行驗證,判斷用戶是否具有權限來下載該文件。這時我們通過Struts 2 的文件下載支持,就可以實現下載前的授權控制。

         下面的Action,首先通過判斷session里面的user屬性是否為chenssy,如果用戶通過了驗證就允許下載,否則直接返回登錄界面。

         代碼如下:

public class AuthorityDownAction implements Action {

    private String inputPath;

    public void setInputPath(String inputPath) {
        this.inputPath = inputPath;
    }

    public InputStream getTargetFile() throws Exception{
        //ServletContext提供了getResourceAsStream()方法
        return ServletActionContext.getServletContext().getResourceAsStream(inputPath);
    }
    public String execute() throws Exception {
        //取得ActionContext實例
        ActionContext ctx = ActionContext.getContext();
        //通過ActionContext訪問用戶的HttpSession
        Map session = ctx.getSession();
        String user = (String) session.get("user");
        //判斷session里的user是否通過檢查
        if(user!=null&&user.equals("chenssy")){
            return SUCCESS;
        }
        ctx.put("tip", "您還沒有登錄,或者登錄的用戶名不正確,請重新登錄!!!");
        return LOGIN;
    }

}

         上面的Action在校驗失敗后,會返回一個login邏輯視圖名,所以在配置該Action時,還需要配置一個名為login的結果。

<action name="download2" class="com.app.action.AuthorityDownAction">
            <!-- 定義被下載文件的物理資源 -->
            <param name="inputPath">\image\meinv_01.rar</param>
            <result name="success" type="stream">
                <!-- 指定下載文件的文件類型 -->
                <param name="contentType">application/rar</param>
                <!-- 指定由getTargetFile()方法返回被下載文件的InputStream -->
                <param name="inputName">targetFile</param>
                <param name="contentDisposition">filename="meinv_01.rar"</param>
                <!-- 指定下載文件的緩沖大小 -->
                <param name="bufferSize">4096</param>
            </result>
            <result name="login">/login.jsp</result>
        </action>

         通過上面的配置后,就可以實現用戶的授權控制。如果用戶不登錄、或者用戶名不正確,在下載該資源時,就會返回到登錄界面。

         如下:


         對于處理登錄請求的Action如下:

public class LoginAction extends ActionSupport {

    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String execute() throws Exception {
        return SUCCESS;
    }

}

          對于該Action,它只是一個簡單的處理類。它的execute方法沒有進行任何處理,直接返回success,表示任何用戶名都可以登錄成功,進入到下載界面,但是從AuthorityDownAction 處理類中可以看到只有用戶名為chengssy的用戶可以下載成功。其他任何用戶下載該資源都不會成功。

          如果登錄成功了,需要返回到下載頁面,所以該Action的配置如下:

<action name="login" class="com.app.action.LoginAction">
            <result name="success">/download.jsp</result>
        </action>

          通過上面的一些配置后,用戶再輸入"chengssy",一旦完成了登錄,用戶的sessionusername的值就會是:chenssy,這時就可以完成文件的下載了。


讀李剛《輕量級Java EE企業應用實戰》

 

 

 

 

 

 

 

 

 

 

來自: http://blog.csdn.net/chenssy/article/details/7349976

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!