Struts2學習筆記 | 關於文件的上傳與下載

文件上傳前表單做的準備

這個在之前學習JSP的時候有接觸到,這裏再次說明一次。

  • 需要把HTML表單的enctype屬性設置爲multipart/form-data

  • 需要把HTML表單的method屬性設置爲post

  • 需要添加<input type="file">字段

文件上傳

  • Struts2的文件上傳實際上使用的是commons FileUpload組件,所以要檢查是否有commons-fileupload-1.4.jarcommons-io-2.6.jar這兩個jar包。

  • Struts2進行文件上傳需要使用FileUpload攔截器

  • 在Action類中定義三個屬性並提供對於的gettersetter方法
    文件的File對象:File [fileFieldName]
    文件類型:String [fileFieldName]ContentType
    文件名:String [fileFieldName]FileName
    有了這三個屬性就可以得到文件的基本信息了

  • 使用IO流進行文件的上傳

Demo如下:
UploadAction文件:

package com.cerr.struts2.upload;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;

import javax.servlet.ServletContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class UploadAction extends ActionSupport {
    private File ppt;
    private String pptContentType;
    private String pptFileName;
    private String pptDesc;

    public String getPptDesc() {
        return pptDesc;
    }

    public void setPptDesc(String pptDesc) {
        this.pptDesc = pptDesc;
    }

    public File getPpt() {
        return ppt;
    }

    public void setPpt(File ppt) {
        this.ppt = ppt;
    }

    public String getPptContentType() {
        return pptContentType;
    }

    public void setPptContentType(String pptContentType) {
        this.pptContentType = pptContentType;
    }

    public String getPptFileName() {
        return pptFileName;
    }

    public void setPptFileName(String pptFileName) {
        this.pptFileName = pptFileName;
    }

    @Override
    public String execute() throws Exception {
        System.out.println(ppt);
        System.out.println(pptContentType);
        System.out.println(pptFileName);
        System.out.println(pptDesc);
        ServletContext servletContext = ServletActionContext.getServletContext();
        String dir = servletContext.getRealPath("/files/"+pptFileName);

        //接下來就io操作
        FileOutputStream outputStream = new FileOutputStream(dir);
        FileInputStream inputStream = new FileInputStream(ppt);
        byte [] buffer = new byte[1024];
        int len = 0;
        while((len = inputStream.read(buffer))!= -1){
            outputStream.write(buffer,0,len);
        }
        outputStream.close();
        inputStream.close();
        return super.execute();
    }
}

一次上傳多個文件

若傳遞多個文件,則上述提到的三個屬性改爲List類型並更新其gettersetter方法即可,示例:

private List<File> ppt;
private List<String> pptContentType;
private List<String> pptFileName;
private List<String> pptDesc;

返回的是對應的集合
如果上面的Demo要改成上傳多個文件,則只需要把對一個對象的操作改成對一個集合對象的操作即可。

對上傳進行限制

  • 可以通過配置FileUploadInterceptor攔截器的參數的方式來進行限制
    maximumSize:上傳的單個文件的最大值,以字節爲單位,默認的最大值爲2M
    allowedTypes:允許的上傳文件的類型,多個類型之間使用逗號分割
    allowedExtensions:允許的上傳文件的擴展名,多個擴展名之間使用逗號分割

  • org.apache.struts2下的default.properties文件中有對上傳的文件總的大小的限制,名字爲struts.multipart.maxSize,可以使用常量的方式來修改該限制。上傳的總的大小要注意不能超過該值,在上傳多個文件的時候即使單個滿足,但是總量超了的話,也會出現錯誤,不過不會自動打印出來,該錯誤存在actionError中,因此可以使用<s:actionerror />標籤來打印。

  • 對於限制條件,可以在國際化資源文件中定義出錯時的錯誤消息
    struts.messages.error.uploading:文件上傳出錯的消息
    struts.messages.error.file.too.large:文件超過最大值的消息
    struts.messages.error.content.type.not.allowed:文件內容類型不合法的消息
    struts.messages.error.file.extension.not.allowed:文件擴展名不合法的消息

對上述的例子進行修改,添加限制
首先在struts.xml文件中定義中配置修改攔截器

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    <!-- 配置國際化資源文件 -->
    <constant name="struts.custom.i18n.resources" value="i18n"></constant>

    <package name="default" namespace="/" extends="struts-default">
        <!--自定義攔截器 -->
        <interceptors>
            <interceptor-stack name="cerrStack">
                <interceptor-ref name="defaultStack">
                    <param name="fileUpload.maximumSize">2000</param>
                    <param name="fileUpload.allowedTypes">text/html,text/xml</param>
                    <param name="fileUpload.allowedExtensions">html,dtd,xml</param>
                </interceptor-ref>
            </interceptor-stack>
        </interceptors>
        <!-- 設置我們修改的該攔截器爲默認的攔截器 -->
        <default-interceptor-ref name="cerrStack"></default-interceptor-ref>


        <action name="testUpload" class="com.cerr.struts2.upload.UploadAction">
            <result>/success.jsp</result>
            <result name="input">/upload.jsp</result>
        </action>
    </package>
</struts>

然後在國際化資源文件i18n.properties中定製錯誤消息

struts.messages.error.uploading=\u6587\u4ef6\u4e0a\u4f20\u51fa\u9519\u7684\u6d88\u606f
struts.messages.error.file.too.large=\u6587\u4ef6\u8d85\u8fc7\u6700\u5927\u503c\u7684\u6d88\u606f
struts.messages.error.content.type.not.allowed=\u6587\u4ef6\u5185\u5bb9\u7c7b\u578b\u4e0d\u5408\u6cd5\u7684\u6d88\u606f
struts.messages.error.file.extension.not.allowed=\u6587\u4ef6\u6269\u5c55\u540d\u4e0d\u5408\u6cd5\u7684\u6d88\u606f

這樣就在上面代碼的基礎上添加了上傳文件限制的功能了。
但是這樣的話,實際上定製的消息並不完善,若要修改定製信息,則可以參考org.apache.struts2下的struts-messages.properties文件。


文件下載

  • Struts2中使用type="stream"的result進行下載即可。

  • 可以爲streamresult設定如下參數
    contentType:結果類型
    contentLength:下載文件的長度
    contentDisposition:設定Content-Disposition響應頭,該響應頭指定響應是一個文件下載類型,一般取值爲attachment;filename=文件名
    inputName:指定文件輸入流的getter定義的那個屬性的名字,默認爲inputStream
    bufferSize:緩存的大小,默認爲1024
    allowCaching:是否允許使用緩存
    contentCharSet:指定下載的字符集

  • 以上參數可以在Action中以getter方法的方式提供。
    配置文件:

<action name="testDownload" class="com.cerr.struts2.upload.DownLoadAction">
            <result type="stream">
                <param name="bufferSize">2048</param>
            </result>
</action>

例子:

package com.cerr.struts2.upload;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;

import javax.servlet.ServletContext;
import java.io.FileInputStream;
import java.io.InputStream;

public class DownLoadAction extends ActionSupport {
    private String contentType;
    private long contentLength;
    private String contentDisposition;
    private InputStream inputStream;

    public String getContentType() {
        return contentType;
    }

    public long getContentLength() {
        return contentLength;
    }

    public String getContentDisposition() {
        return contentDisposition;
    }

    public InputStream getInputStream() {
        return inputStream;
    }

    @Override
    public String execute() throws Exception {
        //確定各個成員變量的值
        contentType="text/html";
        contentDisposition="attachment;filename=aa.png";
        ServletContext servletContext = ServletActionContext.getServletContext();
        String fileName = null;
        fileName = servletContext.getRealPath("/files/1.png");
        System.out.println(fileName);
        inputStream = new FileInputStream(fileName);
        contentLength = inputStream.available();
        return super.execute();
    }
}

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