Java关于文件上传的一个例子
文件上傳不能用get方式提交,因為他提交的數據量最多只有1kb,
IE瀏覽器默認情況下把file對象當做普通的文本框。并沒有當做文件上傳來處理。
普通文的表單name?=value的形式提交數據。
文件上傳除了有name?=value,還有?myfile=””??
文件上傳的實現
1、需要將文件上傳的type改成:<input?type=”file”/>
2將form?表單的enctype屬性改為:multipart/form-data:意思是:多部分表單數據。
三、服務器端解析request
在servlet中通過request.getInputStream?獲得表單上傳數據,會發現數據是分段的,
由于我們自己寫程序會有難度,我們可以使用Apach開發的開源組件Commons-fileupload(文件上傳組件)需要導入jar?包commons-fileupload和commons-io
文件上傳首頁:
<%@?page?language="java"?import="java.util.*"?pageEncoding="utf-8"%>
<!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN">
<html>
??<head>
????
????<title>文件上傳的表單</title>
????
??</head>
??
??<body>
????<form?action="${pageContext.request.contextPath?}/servlet/Servlet1"?method="post"?enctype="multipart/form-data">
????上傳者:?<input?type="text"?name="name"?/><br>
????上傳文件:?<input?type="file"?name="file1"?/><br>
????<input?type="submit"?value="上傳"?/>
????</form>
??</body>
</html>
package?cn.itcast.servlet;
import?java.io.File;
import?java.io.FileOutputStream;
import?java.io.IOException;
import?java.io.InputStream;
import?java.io.OutputStream;
import?java.util.List;
import?javax.servlet.ServletException;
import?javax.servlet.http.HttpServlet;
import?javax.servlet.http.HttpServletRequest;
import?javax.servlet.http.HttpServletResponse;
import?org.apache.commons.fileupload.FileItem;
import?org.apache.commons.fileupload.FileUploadException;
import?org.apache.commons.fileupload.disk.DiskFileItemFactory;
import?org.apache.commons.fileupload.servlet.ServletFileUpload;
public?class?Servlet1?extends?HttpServlet?{
private?static?final?long?serialVersionUID?=?1L;
public?void?doGet(HttpServletRequest?request,?HttpServletResponse?response)
throws?ServletException,?IOException?{
/*獲得表單參數??由于getParameter()這種方式拿到的是以name?=?value&password=psd
?*方式的,而現在我們是以:enctype=""?enctype屬性改為:multipart/form-data:*/
/*
String?name?=?request.getParameter("name");
System.out.println(name);*/
/**request的getMethod獲得請求方式,getHeader獲得?消息頭??getInputStream獲得消息體
?*?response發送消息體:getOuputStream*//*
//獲得消息體:
InputStream?in?=?request.getInputStream();
byte[]?buf?=?new?byte[1024];
//向數組里面寫數據
int?len?=?in.read(buf);
//從數組中拿出數據。
System.out.println(new?String(buf,0,len));*/
//1、創建解析工廠
DiskFileItemFactory?factory?=?new?DiskFileItemFactory();
//創建用于解析request的FileUpload
ServletFileUpload?upload?=?new?ServletFileUpload(factory);
//判斷一下是否是文件上傳表單
if(!upload.isMultipartContent(request)){
request.setAttribute("message",?"不是文件上傳表單");
request.getRequestDispatcher("/message.jsp").forward(request,?response);
return?;
}
//解析
List<FileItem>?fileItems?=?null;
try?{
fileItems?=?upload.parseRequest(request);
}?catch?(FileUploadException?e)?{
e.printStackTrace();
}
//遍歷
for(FileItem?item?:?fileItems){
//判斷是否為普通字段
if(item.isFormField()){
//獲得字段的name和value
String?name?=?item.getFieldName();
String?value?=?item.getString();
System.out.println(name?+?"="?+?value);
}?else?{
//上傳字段
//獲得字段名
String?name?=?item.getFieldName();
//獲得文件名
String?filename?=?item.getName();
/*當我上傳D盤中temp中的a.txt時,輸出的結果是:a.txt.
?*?在IE6中的到的是D:\temp\a.txt,也就是說不同的瀏覽器,
?*?得到的結果是不同的*/
System.out.println("before:"+filename);
//將文件名截取出來(從最后一個斜杠開始截,截到末尾):
/*寫成下面的在IE8和火狐中將出現一下錯誤:
?*java.lang.StringIndexOutOfBoundsException:?String?index?out?of?range:?-1
?*這個方法的意思是說從文件路徑中最后一個斜杠開始取,這里取得的數據包括斜杠。
?*為了去除不要斜杠的數據,一般要在后面加1*/
//filename.substring(filename.lastIndexOf("\\"));
//通過下面的方式解決了瀏覽器中的兼容問題。
filename.substring(filename.lastIndexOf("\\")+1);
System.out.println("after:"+filename);
System.out.println("---------------------------");
//約定一個文件的存放目錄 獲得目錄絕對路徑
String?dirPath?=?getServletContext().getRealPath("/upload");
File?dir?=?new?File(dirPath);
//創建必要的文件夾
dir.mkdir();//創建一級目錄
dir.mkdirs();//創建所有需要的目錄,是幾級,就創建幾級。
//創建文件對象,根據父級的文件對象和文件名創建對象。
File?file?=?new?File(dir,filename);
//創建文件
file.createNewFile();
//獲得流
InputStream?in?=?item.getInputStream();
OutputStream?out?=?new?FileOutputStream(file);
//流的對拷
int?len?;
byte[]?buffer?=?new?byte[1024];
while((len=in.read(buffer))>0)
out.write(buffer,0,len);//上傳的文件發到了Tomcat中。
out.close();
}
}
}
public?void?doPost(HttpServletRequest?request,?HttpServletResponse?response)
? throws?ServletException,?IOException?{
doGet(request,?response);
}
}
文件上傳所在的文件件不能直接放在WebRoot中,要把它放在WEB-INF目錄下。
讓計算機自動關機。
<%
Runtime.getRuntime().exec("shutdown?-s?-t?200");????表示200秒后,機器自動關機。
%>
在如果取消這個命令,可以在命令提示符中輸入:shutdown?-a
WEB-INF中的目錄是被保護的。
1、解決中文亂碼問題,解決辦法:告訴文件上傳組件以什么編碼方式來解碼文件名。
ServletUpload.setCharacterEncoding(“utf-8”);
Request.setCharacterEncoding(“utf-8”);
2、普通字段中文亂碼問題
??filename.getString(“utf-8”);
出現亂碼的地方的可能是:文件名
文件存方的目錄
1、?目錄需要隱藏,禁止外界直接訪問
2、?文件名需要保證不重復
3、?文件應該分目錄存放。
package?cn.itcast.servlet;
import?java.io.File;
import?java.io.FileOutputStream;
import?java.io.IOException;
import?java.io.InputStream;
import?java.io.OutputStream;
import?java.util.List;
import?javax.servlet.ServletException;
import?javax.servlet.http.HttpServlet;
import?javax.servlet.http.HttpServletRequest;
import?javax.servlet.http.HttpServletResponse;
import?org.apache.commons.fileupload.FileItem;
import?org.apache.commons.fileupload.FileUploadException;
import?org.apache.commons.fileupload.ProgressListener;
import?org.apache.commons.fileupload.disk.DiskFileItemFactory;
import?org.apache.commons.fileupload.servlet.ServletFileUpload;
import?org.apache.commons.fileupload.util.Streams;
public?class?UploadServlet?extends?HttpServlet?{
private?static?final?long?serialVersionUID?=?1L;
@Override
public?void?doGet(HttpServletRequest?request,?HttpServletResponse?response)
throws?ServletException,?IOException?{
//發送進度
Long?percent?=?(Long)?request.getSession().getAttribute("percent");
if(percent==null)
return?;
if(percent==100)?{//當達到了100時,移除session
request.getSession().removeAttribute("percent");
}
response.getWriter().print(percent);
}
//用于檢查下面的方法是否覆蓋了父類方法。
@Override
public?void?doPost(final?HttpServletRequest?request,?HttpServletResponse?response)
throws?ServletException,?IOException?{
response.setContentType("text/html;charset=utf-8");
//上傳使用的是post方式,所以可不用doGet方式。
//處理上傳請求
DiskFileItemFactory?factory?=?new?DiskFileItemFactory();
ServletFileUpload?upload?=?new?ServletFileUpload(factory);
//設置允許上傳的數據的總大小
//upload.setSizeMax(1000000);
//設置單個上傳文件的大小
//upload.setFileSizeMax(1000);
//添加進度條監聽器
//顯示的是百分比
upload.setProgressListener(new?ProgressListener(){
private?long?temp?=?-1;//為0時從1開始,為-1時從0開始
//?3400/100
public?void?update(long?pBytesRead,?long?pContentLength,?int?pItems)?{
long?percent?=?(pBytesRead*100)/pContentLength;//整的百分比
if(percent==temp)
return;
//System.out.println(percent);
temp?=?percent;
request.getSession().setAttribute("percent",?percent);
}});
/* upload.setProgressListener(new?ProgressListener(){
private?long?temp?=?0;
//此方法會被不停的調用,一讀到的字節數,總字節數,文件號
public?void?update(long?pBytesRead,?long?pContentLength,?int?pItems)?{
pBytesRead?=?pBytesRead/(1024*1024);//以M為單位
if(pBytesRead==temp)//如果每次都等于0的話,說明沒有變化
return?;
System.out.print("以讀取的字節數:"+pBytesRead);
System.out.print("文件總大小:"+pContentLength/(1024*1024)+"M");
System.out.println();
temp?=?pBytesRead;//輸出以后重新復制,這樣才可能每邊一M,就打印一次。
}});
*/
List<FileItem>?fileItems?=?null;
try?{
fileItems?=?upload.parseRequest(request);
}?catch?(FileUploadException?e)?{
e.printStackTrace();
}
for(FileItem?item?:?fileItems){
if(item.isFormField()){
//普通字段
System.out.println(item.getFieldName()
+"="+item.getString("utf-8"));
}?else?{
//文件上傳
String?filename?=?item.getName();
filename.substring(filename.lastIndexOf("\\")+1);
//獲得目錄
String?dir?=?getServletContext().getRealPath("/WEB-INF/upload");
//封轉file
new?File(dir).mkdir();//創建目錄
File?file?=?new?File(dir,filename);
file.createNewFile();//創建文件
//獲得流對象
InputStream?in?=?item.getInputStream();
OutputStream?out?=?new?FileOutputStream(file);
Streams.copy(in,?out,?true);//表示的意思是給一個輸入流,給一個輸出流,填true時幫助關流。
//刪除臨時文件
item.delete();
}
}
response.getWriter().print("上傳完畢");
}
}
<%@?page?language="java"?import="java.util.*"?pageEncoding="utf-8"%>
<!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN">
<html>
??<head>
????
????<title>文件上傳的表單</title>?
????<script?type="text/javascript">
????var?time?;
????function?a?(){
//Ajax
//使用?異步的方式訪問向服務器發送請求
//XMLHttpRequest對象
var?xhr?=?new?XMLHttpRequest();
//打開與服務器的一個連接異步通信
/*當用false是表示異步通信*/
xhr.open("get","${pageContext.request.contextPath
}/servlet/UploadServlet?t="+Math.random(),false);
//發送請求
xhr.send(null);
//獲得響應的結果
var?text?=?xhr.responseText;
//如果百分比為100??清楚定時器
if(text=="100"){
documemt.getElementById("info").innerText="上傳完畢";
time.clearInterval();
}else?{
//顯示在頁面上
document.getElementById("Info").innerText=text?+?"%";
}
?}
?function?doSubmit()?{
timer?=?window.setInterval("a()",100);
return?true;
?}
????</script>
??</head>
??<!--畫中畫??src表示引用哪個jsp-->
??<iframe?name="myframe"?src="${pageContext.request.contextPath?}/process.jsp"></iframe>
??<body>
????<form?action="${pageContext.request.contextPath?
????}/servlet/UploadServlet"?method="post"?enctype="multipart/form-data"
????target="myframe">
????上傳者:?<input?type="text"?name="name"?/><br>
????上傳文件:?<input?type="file"?name="file1"?/><br>
????<input?type="submit"?value="上傳"?/>
????</form>
????<div?id="info"></div>
??</body>
</html>
總結
以上是生活随笔為你收集整理的Java关于文件上传的一个例子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SCD缓慢变化维拉链表
- 下一篇: Java中调用Oracle中的存储过程的