文件上傳和下載
一些需要注意的地方:
在處理到文件上傳和下載的時(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教程