第一點:Java代碼實現(xiàn)文件上傳
FormFile file = manform.getFile();
String newfileName =?null;
String newpathname =?null;
String fileAddre =?"/numUp";
try
{
?InputStream stream = file.getInputStream();//?把文件讀入
?String filePath = request.getRealPath(fileAddre);//取系統(tǒng)當前路徑
?File file1 =?new?File(filePath);//添加了自動創(chuàng)建目錄的功能
?((File)file1).mkdir();
?newfileName = System.currentTimeMillis()
?+ file.getFileName().substring(
?file.getFileName().lastIndexOf('.'));
?ByteArrayOutputStream baos =?new?ByteArrayOutputStream();
?OutputStream bos =?new?FileOutputStream(filePath +?"/"
?+ newfileName);
?newpathname = filePath +?"/"?+ newfileName;
?System.out.println(newpathname);
?//?建立一個上傳文件的輸出流
?System.out.println(filePath +?"/"?+ file.getFileName());
?int?bytesRead = 0;
?byte[] buffer =?new?byte[8192];
?while?((bytesRead = stream.read(buffer, 0, 8192)) != -1)
?{
?bos.write(buffer, 0, bytesRead);//?將文件寫入服務器
?}
??bos.close();
?stream.close();
}
catch?(FileNotFoundException e)
{
?e.printStackTrace();
}
catch?(IOException e)
{
?e.printStackTrace();
}
?第二點:Jsp頁面上實現(xiàn)文件上傳
package?com.vogoal.util;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
public?class?JspFileUpload
{
?/**?request對象?*/
?private?HttpServletRequest request =?null;
?/**?上傳文件的路徑?*/
?private?String uploadPath =?null;
?/**?每次讀取得字節(jié)的大小?*/
?private?static?int BUFSIZE = 1024 * 8;
?/**?存儲參數(shù)的Hashtable?*/
?private?Hashtable paramHt =?new?Hasptable();
?/**?存儲上傳的文件的文件名的ArrayList?*/
?private?ArrayList updFileArr =?new?ArrayList();
?/**
?*?設定request對象。
?*
?*?@param?request
?*?HttpServletRequest?request對象
?*/
?public?void setRequest(HttpServletRequest request) {
?this.request = request;
?}
?/**
?*?設定文件上傳路徑羽利。
?*
?*?@param?path
?*?用戶指定的文件的上傳路徑浴骂。
?*/
?public?void setUploadPath(String path) {
?this.uploadPath = path;
?}
文件上傳上處理程序
?/**
?*?文件上傳處理主程序矮锈。???????B
?*
?*?@return?int?操作結(jié)果?0?文件操作成功哄芜;1?request對象不存在诗轻。?2?沒有設定文件保存路徑或者文件保存路徑不正確;3
?*?沒有設定正確的enctype屏歹;4?文件操作異常隐砸。
?*/
?public?int process() {
?int status = 0;
?//?文件上傳前,對request對象蝙眶,上傳路徑以及enctype進行check季希。
?status = preCheck();
?//?出錯的時候返回錯誤代碼。
?if?(status != 0)
?return?status;
?try?{
?//???參數(shù)或者文件名?u??
?String name =?null;
?//?參數(shù)的value
?String value =?null;
??????????//?讀取的流是否為文件的標志位
?boolean fileFlag =?false;
?//?要存儲的文件幽纷。
?File tmpFile =?null;
?//?上傳的文件的名字
?String fName =?null;
?FileOutputStream baos =?null;
?BufferedOutputStream bos =?null;
?//???存儲參數(shù)的Hashtable
?paramHt =?new?Hashtable();
?updFileArr =?new?ArrayList();
?int rtnPos = 0;
?byte[] buffs =?new?byte[BUFSIZE * 8];
?//??取得ContentType
?String contentType = request.getContentType();
?int index = contentType.indexOf("boundary=");
?String boundary =?"--"?+ contentType.substring(index + 9);
?String endBoundary = boundary +?"--";
?//??從request對象中取得流式塌。
?ServletInputStream sis = request.getInputStream();
?//?讀取1行
?while?((rtnPos = sis.readLine(buffs, 0, buffs.length)) != -1) {
?String strBuff =?new?String(buffs, 0, rtnPos);
?//?讀取1行數(shù)據(jù)?n??
?if?(strBuff.startsWith(boundary)) {
?if?(name !=?null?&& name.trim().length() > 0) {
?if?(fileFlag) {
?bos.flush();
?baos.close();
?bos.close();
?baos =?null;
?bos =?null;
?updFileArr.add(fName);
?}?else?{
?Object obj = paramHt.get(name);
?ArrayList al =?new?ArrayList();
?if?(obj !=?null) {
?al = (ArrayList) obj;
?}
?al.add(value);
???????System.out.println(value);
?paramHt.put(name, al);
?}
?}
?name =?new?String();
?value =?new?String();
?fileFlag =?false;
??????????????????fName =?new?String();
?rtnPos = sis.readLine(buffs, 0, buffs.length);
?if?(rtnPos != -1) {
?strBuff =?new?String(buffs, 0, rtnPos);
?if?(strBuff.toLowerCase().startsWith(
?"content-disposition: form-data; ")) {
?int nIndex = strBuff.toLowerCase().indexOf(
?"name=\"");
?int nLastIndex = strBuff.toLowerCase().indexOf(
?"\"", nIndex + 6);
?name = strBuff.substring(nIndex + 6, nLastIndex);
?}
?int fIndex = strBuff.toLowerCase().indexOf(
?"filename=\"");
?if?(fIndex != -1) {
?fileFlag =?true;
?int fLastIndex = strBuff.toLowerCase().indexOf(
?"\"", fIndex + 10);
?fName = strBuff.substring(fIndex + 10, fLastIndex);
?fName = getFileName(fName);
?if?(fName ==?null?|| fName.trim().length() == 0) {
?????fileFlag =?false;
?sis.readLine(buffs, 0, buffs.length);
?sis.readLine(buffs, 0, buffs.length);
?sis.readLine(buffs, 0, buffs.length);
?????????continue;
?}else{
?fName = getFileNameByTime(fName);
?sis.readLine(buffs, 0, buffs.length);
?sis.readLine(buffs, 0, buffs.length);
?}
?}
?}
?}?else?if?(strBuff.startsWith(endBoundary)) {
?if?(name !=?null?&& name.trim().length() > 0) {
?if?(fileFlag) {
?bos.flush();
?baos.close();
?bos.close();
?baos =?null;
?bos =?null;
?updFileArr.add(fName);
?}?else?{
?Object obj = paramHt.get(name);
?ArrayList al =?new?ArrayList();
?if?(obj !=?null) {
?al = (ArrayList) obj;
???????????????????????????}
?al.add(value);
?paramHt.put(name, al);
?}
?}
?}?else?{
?if?(fileFlag) {
?if?(baos ==?null?&& bos ==?null) {
?tmpFile =?new?File(uploadPath + fName);
?baos =?new?FileOutputStream(tmpFile);
?bos =?new?BufferedOutputStream(baos);
?}
?bos.write(buffs, 0, rtnPos);
?baos.flush();
?}?else?{
?System.out.println("test :"?+ value +?"--"?+ strBuff);
?value = value + strBuff;
?}
?}
?}
?}?catch?(IOException e) {
?status = 4;
?}
?return?status;
?}
?private?int preCheck() {
?int errCode = 0;
?if?( request ==?null?)
?return?1;
?if?( uploadPath ==?null?|| uploadPath.trim().length() == 0 )
?return?2;
?else{
?File tmpF =?new?File(uploadPath);
?if?(!tmpF.exists())
?return?2;
?}
?String contentType = request.getContentType();
?if?( contentType.indexOf("multipart/form-data") == -1 )
?return?3;
?return?errCode;
?}
?public?String getParameter(String name){
?String value =?"";
?if?( name ==?null?|| name.trim().length() == 0 )
?return?value;
?value = (paramHt.get(name) ==?null)?"":(String)((ArrayList)paramHt.get(name)).get(0);
?return?value;
?}
?public?String[] getParameters(String name){
?if?( name ==?null?|| name.trim().length() == 0 )
?return?null;
?if?( paramHt.get(name) ==?null?)
?return?null;
?ArrayList al = (ArrayList)paramHt.get(name);
?String[] strArr =?new?String[al.size()];
?for?( int i=0;i
?strArr[i] = (String)al.get(i);
?return?strArr;
?}
?public?int getUpdFileSize(){
?return?updFileArr.size();
?}
?public?String[] getUpdFileNames(){
?String[] strArr =?new?String[updFileArr.size()];
?for?( int i=0;i
?strArr[i] = (String)updFileArr.get(i);
?return?strArr;
?}
?private?String getFileName(String input){
?int fIndex = input.lastIndexOf("\\");
?if?(fIndex == -1) {
?fIndex = input.lastIndexOf("/");
?if?(fIndex == -1) {
?return?input;
?}
?}
?input = input.substring(fIndex + 1);
?return?input;
?}
?private?String getFileNameByTime(String input){
?int index = input.indexOf(".");
?Date dt =?new?Date();
?SimpleDateFormat sdf =?new?SimpleDateFormat("yyyyMMddHHmmssSSS");
?return?input.substring(0,index) + sdf.format(dt) + input.substring(index);
?}
}
?2.在Jsp頁面中進行引用該Java類:
<%@page?import="com.vogoal.util.JspFileUpload"%>
<%
?//初始化
?JspFileUpload jfu =?new?JspFileUpload();
?//設定request對象
?jfu.setRequest(request);
?//設定上傳的文件路徑
?jfu.setUploadPath("C:\\");
?//上傳處理
?int?rtn = jfu.process();
?//取得form中其他input控件參數(shù)的值
?String username = jfu.getParameter("username");
?//如果對應同一個參數(shù)有多個input控件,返回數(shù)組
?String[] usernameArr = jfu.getParameters("username");
?//取得上傳的文件的名字
?String[] fileArr = jfu.getUpdFileNames();
?//取得上傳文件的個數(shù)友浸,這個方法有點雞肋
?int?fileNumber = jfu.getUpdFileSize();
//下面的是測試輸出的代碼峰尝。
//?out.println("parameter:" + username);
//?out.println("parameter size:" + usernameArr.length);
//?out.println("fileArr size:" + fileArr.length);
//?if (fileArr.length > 0)
//?out.println("fileArr 0:" + fileArr[0]);
%>
第三點:struts2實現(xiàn)文件的上傳和下載
第一步:在WEB-INF/lib下加入commons-fileupload-1.2.1.jar、commons-io-1.3.2.jar收恢。這兩個文件可以從http://commons.apache.org/下載武学。
第二步:把form表的enctype設置為:“multipart/form-data“,如下:
Java代碼
public?class?UploadAction{?
?private?File uploadImage;?//文件?
?private?String uploadImageContentType;//文件的類型?
?private?String uploadImageFileName;//文件的名稱?
?private?String bookname;//書名?
?private?String author;//作者?
?private?String savePath;//文件的保存位置?
?//屬性的getter/setter方法?
?public?String upload()?throws?Exception{?
?//實現(xiàn)上傳代碼伦意,I/O操作完成?
?return?"uploadSuccess";?
?}?
}
注:一個表單里的文件域?qū)狝ction中三個屬性火窒,分別是文件,文件名驮肉,文件類型熏矿,命名是固定的,文件名必須表單中的文件域名稱相同(uploadImage)离钝,文件名為:文件+FileName曲掰,文件類型:文件+ContentType。
第四步:將我們的上傳Action配置到struts.xml中奈辰。
<action?name="upload"?class="com.gqy.UploadAction">?
?<param?name="savePath">/uploadFile</param>?
?<result>/success.jsp</result>?</action>
注:指定上傳文件的在服務器上的保存目錄栏妖,需要在UploadAction中為定義savePath變量并為其添加相應的setter和getter方法,便于Struts2將/uploadFile值賦給savePath屬性奖恰,即要想在UploadAction中使用savePath變量必須在UploadAction定義吊趾。
配置文件過濾類型:
<param?name="allowTypes">?image/bmp,image/png,image/gif,image/jpeg?</param>
手動配置文件大小限制
<param?name="maximumSize"?>1048576</param>?
使用Struts2的文件上傳攔截器實現(xiàn)文件過濾
Struts2提供了一個文件上傳的攔截器—fileUpload,通過配置該攔截器可以方便實現(xiàn)上傳文件的過濾瑟啃。
配置fileUpload攔截器時论泛,可以為其指定兩個參數(shù):
§ allowedTypes:指定允許上傳的文件類型,多個文件類型之間以英文逗號(,)隔開蛹屿。
§ maximumSize:指定允許上傳的文件大小屁奏,單位是字節(jié)。
提示:通過配置fileUpload攔截器错负,可以輕松的實現(xiàn)文過濾坟瓢,當文件過濾失敗后勇边,系統(tǒng)自動轉(zhuǎn)入input邏輯視圖,因此必須為該Action配置名為input的邏輯視圖折联,除此之外粒褒,還必須顯示地為該Action配置defaultStack的攔截器引用。
使用Struts2的攔截器實現(xiàn)文件過濾配置如下:
?<action?name="uploadFileAction"?class="com.actions.UploadFileAction">?
??<interceptor-ref?name="defaultStack">?
?<!--?配置允許上傳的文件類型诚镰,多個用","分隔?-->??????????????????
?<param?name="fileUpload.allowedTypes">??????????????????????
?image/bmp,image/png,image/gif,image/jpeg,image/jpg??
?,image/x-png, image/pjpeg?
?</param>?????????????????
?<!--?配置允許上傳的文件大小奕坟,單位字節(jié),本例為:1MB?-->?
?<param?name="fileUpload.maximumSize">1048576</param>?
?</interceptor-ref>?
?<result?name="input">/jsp/oneFileFileupload.jsp</result>?
?<result?name="success">/jsp/result.jsp</result>?
</action>
當用戶上傳失敗后,需要有一定的提示信息清笨。在Struts2中月杉,使用<s:fielderror/>標簽即可將錯誤提示信息輸出到頁面中。
注:要想使用Struts2錯誤提示信息抠艾,則上傳文件的Action類苛萎,必須繼承ActionSupport,否則Struts2不會提供輸出錯誤提示信息功能跌帐。
我們可以配置資源文件(.properties)來保存輸出給用戶的信息。
struts.messages.eror.file.too.large:當上傳文件大小超過設定的值時绊率,Struts2將輸出該key對應的提示信息谨敛。
struts.messages.error.content.type.not.allowed:當上傳文件類型不符合設定的值時,Struts2將輸出該key對應的提示信息滤否。
struts.messages.error.uploading:當上傳文件時出現(xiàn)未知錯誤時脸狸,Struts2將輸出該key對應的提示信息。
我們還要將資源文件配置到struts.xml文件中藐俺,接下來看看我們的資源文件炊甲,已經(jīng)包含中文了,得把它進行一下轉(zhuǎn)換再配置到工程中欲芹。
在struts.xml中設定資源文件:
<constant name="struts.custom.i18n.resources" value="messages"/>或
<constant name="struts.custom.i18n.resources" value="messages_zh_CN"/>
用命令native2ascii?d:\messages.properties d:\messages_zh_CN.properties將原有的資源文件轉(zhuǎn)換成支持中的卿啡。
注:保持國際化,資源文件的名稱后綴為: *_zh_CN+文件擴展名的形式菱父。
對于多個文件上傳的原理同上颈娜,但是需要注意的是,多個文件域的name屬性名必須相同浙宜,而且在Action中應該使用File [] 或者List<File>來接收官辽。
個人覺得用這樣的方式進行多個文件上傳不是很好。
Struts2進行文件下載:
Struts2提供了stream結(jié)果類型粟瞬,該結(jié)果類型專門用于支持文件下載的功能同仆。當指定stream結(jié)果類型時,需要配置一個inputName參數(shù)裙品,該參數(shù)指定了一個輸入流俗批,這個輸入流是被下載文件的入口(即通過該入口才能實現(xiàn)文件以流的方式實現(xiàn)下載)俗或。
實現(xiàn)文件下載的Action
?public?class?FileDownloadAction?implements?Action{?
??//該屬性值在配置文件中指定,Struts2會自動進行注入(即賦值)扶镀,需要為該屬性提供setter和 getter方法?
??private?String?inputPath;//指定要下載的文件的完整路徑(路徑名+文件名)?
??/*
??*?實現(xiàn)下載的Action類應該提供一個返回InputStream實例的方法蕴侣,該方法對應在??????
??里的inputName屬性值為targetFile
??*/
??public?InputStream?getTargetFile()?throws?Exception{?
??return?ServletActionContext.getServletContext().getResourceAsStream(inputPath);?
??}?
??//處理用戶請求的execute方法,該方法返回success字符串?
??public?String?execute()?throws?Exception{?
??return?"success";?
??}
?@Override
?public?void?doIt(FSM arg0, Input arg1) {
?//?TODO?Auto-generated method stub
?}?
?}
對應Action在struts.xml文件中的配置
<action?name="download"?class="com.FileDownloadAction">
?<!--指定被下載資源的位置-->
?<param?name="inputPath">/uploadFile/demo.txt</param>
?<!--配置結(jié)果類型為stream的結(jié)果-->
?<result?name="success"?type="stream">
?<!--指定下載文件的文件類型-->
?<param?name="contentType"></param>
?<!--指定下載文件的文件位置-->
?<param?name="inputName">targetFile</param>
?<!--指定下載文件的下載方式及下載時的保存文件名臭觉,filename保存時的文件名必須有擴展名昆雀,擴展名指示了下載類型的圖標-->
?<param?name="contentDisposition">
?attachment;filename=Struts2.txt
?</param>
?<!--指定下載文件的緩沖區(qū)大小-->
?<param?name="bufferSize">4096</param>
?</result>
</action>
后端代碼邏輯大部分是相同的,目前能夠支持MySQL,Oracle,SQL蝠筑。在使用前需要配置一下數(shù)據(jù)庫狞膘,詳細源碼可以網(wǎng)上搜索“up6”
討論群“374992201”