文件上傳和下載
 
一些需要注意的地方:
 
在處理到文件上傳和下載的時(shí)候首先說明一些需要注意的地方。
 
1)  使用HTML默認(rèn)的功能不能上傳目錄,這里的默認(rèn)功能指的是不做額外的開發(fā)(例如ActiveX)的情況下。
   所以客戶如果跟你說:“我有一個(gè)目錄需要上傳,能不能讓我選擇目錄,然后一下子上傳整個(gè)目錄?”,出于工作量的考慮你最好回絕他,然后使用動(dòng)態(tài)增加的方式來動(dòng)態(tài)的支持多個(gè)上傳文件,或者更簡(jiǎn)單的讓客戶指定所有的上傳文件。
 
2)  不能設(shè)置文件上傳字段的默認(rèn)值。
   出于安全的考慮,HTML不支持默認(rèn)的文件上傳字段的默認(rèn)值。例如,在你不知道的情況下,你訪問了某個(gè)網(wǎng)站的某個(gè)頁面,結(jié)果你的password文件被上傳上去了,哈哈,你有危險(xiǎn)了。
   所以如果客戶跟你說:“我能不能打開畫面的時(shí)候就設(shè)置好上傳的文件?”,處于工作量和技術(shù)難度的考慮,你最好說:“哦,為了您的安全,還是不要這樣子做了”,呵呵,
 
3)文件類型
    每一種文件都有類型,一般情況下擴(kuò)展明決定了文件的類型。。所有文件類型的列表可以從這個(gè)目錄中找到,相信可以為你提供參考:
TOMCAT_HOME\conf\web.xml  
<mime-mapping>
        <extension>bin</extension>
        <mime-type>application/octet-stream</mime-type>
</mime-mapping>
<mime-mapping>
        <extension>gif</extension>
        <mime-type>image/gif</mime-type>
</mime-mapping>
4) 下載文件時(shí)本頁面內(nèi)部打開,還是彈出另存對(duì)話框?
文件下載的時(shí)候可以在本頁面打開,和可以彈出另存對(duì)話框。選擇條件是設(shè)置文件下載的:contentDisposition,inline表示當(dāng)前頁面打開,attachment表示彈出另存對(duì)話框。
例如:
contentDisposition=inline;filename="image.jpg"             當(dāng)前畫面打開
contentDisposition=attachment;filename="image.jpg"         打開另存對(duì)話框
 
5)文件上傳需要使用method="post" 和 enctype="multipart/form-data"類型的form
 
使用Struts2上傳文件:
Struts文件上傳需要使用File Upload Filter。Filter Upload Filter使用一些默認(rèn)的規(guī)則:
Form中的<s:file name="image"></s:file>標(biāo)簽對(duì)應(yīng)著Action類中的三個(gè)屬性分別是:上傳文件(java.io.File類 型),文件名(java.lang.String類型),文件類型(java.lang.String類型,例如:image/jpeg)。命名規(guī)約為:
文件:名字與<s:file>標(biāo)簽中的name屬性一致,這里為:image
文件名:文件 + FileName,這里為:imageFileName
文件類型:文件 + ContentType,這里為:imageContentType
 
所以針對(duì)上述<s:file name="image"></s:file>表示啊的上傳文件的JSP和Action類被別為:
 
imageUpload.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="s" uri="/struts-tags" %>
 
<html>
<head><title>Image Upload</title></head>
<body>
    <h1> Image Upload Page </h1>
 
    <s:form action="imageUpload" method="post" enctype="multipart/form-data">
        <s:file name="image"></s:file>
        <s:submit></s:submit>
 
    </s:form>
</body>
</html>
 
ImageUploadAction.java:
package com.jpleasure;
 
import com.opensymphony.xwork2.ActionSupport;
 
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
 
public class ImageUploadAction extends ActionSupport {
 
    private File image;
    private String imageFileName;
    private String imageContentType;
 
    public File getImage() {
        return image;
    }
 
    public void setImage(File image) {
        this.image = image;
    }
 
    public String getImageFileName() {
        return imageFileName;
    }
 
    public void setImageFileName(String imageFileName) {
        this.imageFileName = imageFileName;
    }
 
    public String getImageContentType() {
        return imageContentType;
    }
 
    public void setImageContentType(String imageContentType) {
        this.imageContentType = imageContentType;
    }
 
 
    public String execute() {
 
        if (image != null) {
            System.out.println("file name is:" + this.imageFileName);
            System.out.println("file content type is:" + this.imageContentType);
            System.out.println("file length is:" + this.image.length());
         }
        return SUCCESS;
    }
}
 
Struts.xml配置文件:
<action name="imageUpload" class="com.jpleasure.ImageUploadAction">
            <result>/success.jsp</result>
</action>
 
這樣當(dāng)我們選中上傳文件,提交的時(shí)候:文件內(nèi)容會(huì)以File類型的方式放在image聲明的變量中。文件的名字將會(huì)被放在imageFileName命名的變量中,文件的類型被放在imageContentType命名的變量中。
 
文件下載:
文件下載需要使用一個(gè)特殊的Result,stream類型的Result。Stream類型的Result主要用來處理文件下載操作。
處理原理為:所有的下載文件都是將一個(gè)二進(jìn)制的流寫入到HttpResponse中去。在Action類中定義一個(gè)InputSream類型的二進(jìn)制流,在Result返回給用戶的時(shí)候返回給用戶。
 
擴(kuò)展上述的代碼,將上傳來的文件直接下載給用戶:
ImageUploadAction中需要追加一個(gè)InputSream類型的對(duì)象,并且指向上傳的文件,代碼如下,紅色部分表示變化:
package com.jpleasure;
 
import com.opensymphony.xwork2.ActionSupport;
 
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
 
public class ImageUploadAction extends ActionSupport {
 
    private File image;
    private String imageFileName;
    private String imageContentType;
 
    private InputStream imageInputStream = null;
 
 
    public InputStream getImageInputStream() {
        return imageInputStream;
    }
 
    public void setImageInputStream(InputStream imageInputStream) {
        this.imageInputStream = imageInputStream;
    }
 
    public File getImage() {
        return image;
    }
 
    public void setImage(File image) {
        this.image = image;
    }
 
    public String getImageFileName() {
       return imageFileName;
    }
 
    public void setImageFileName(String imageFileName) {
        this.imageFileName = imageFileName;
    }
 
    public String getImageContentType() {
        return imageContentType;
    }
 
    public void setImageContentType(String imageContentType) {
        this.imageContentType = imageContentType;
    }
 
 
    public String execute() {
 
        if (image != null) {
            System.out.println("file name is:" + this.imageFileName);
            System.out.println("file content type is:" + this.imageContentType);
            System.out.println("file length is:" + this.image.length());
 
            try {
                this.imageInputStream = new FileInputStream (image);
            } catch (FileNotFoundException e) {
               e.printStackTrace();          
 }
 
        }
 
        return SUCCESS;
    }
}
配置文件為,紅色為變化部分:
<action name="imageUpload" class="com.jpleasure.ImageUploadAction">
            <result name="success" type="stream">
              <param name="contentType">image/pjpeg</param>
              <param name="inputName">imageInputStream</param>
              <param name="contentDisposition">attachment;filename="image.jpg"</param>
              <param name="bufferSize">1024</param>
            </result>
</action>
ContentType表示下載文件的類型。
InputName表示Action類中用來下載文件的字段的名字。
ContentDisposition用來控制文件下載的一些信息,包括是否打開另存對(duì)話框,下載文件名等。
BufferSize表示文件下載時(shí)使用的緩沖區(qū)的大小。
 
實(shí)際項(xiàng)目開發(fā)的考慮:
控制上傳文件的類型和最大允許上傳文件的size
使用File Upload Intercepter的參數(shù)可盈控制上傳文件的類型和最大允許上傳文件的size。例如:
<struts>
    <package name="myPackage" extends="struts-default">
 
        <interceptor-ref name="fileUpload">
            <param name="maximumSize">2MB</param>
            <param name="allowedTypes">text/html,image/jpeg</param>
        </interceptor-ref>
 
        <interceptor-ref name="basicStack"/>
 
        <action name="imageUpload" class="com.jpleasure.ImageUploadAction">
            <result name="success" type="stream">
                <param name="contentType">image/pjpeg</param>
                <param name="inputName">imageInputStream</param>
                <param name="contentDisposition">
attachment;filename="image.jpg"
</param>
                <param name="bufferSize">1024</param>
            </result>
        </action>
    </package>
</struts>
 
上述表示允許上傳jpeg和html類型的文件,且最大文件上傳size為2MB
 
顯示錯(cuò)誤信息:
可以使用如下key表示的message來顯示文件上傳出錯(cuò)的提示信息:

消息Key
說明
struts.messages.error.uploading
文件無法正常上傳時(shí)的公共錯(cuò)誤
struts.messages.error.file.too.large
文件大小超過最大允許size時(shí)的錯(cuò)誤提示
struts.messages.error.content.type.not.allowed
文件類型不在上傳文件允許類型中的錯(cuò)誤提示


ExtJS教程- Hibernate教程-Struts2 教程-Lucene教程