Java关于文件上传的一个例子
文件上傳不能用get方式提交,因?yàn)樗峤坏臄?shù)據(jù)量最多只有1kb,
IE瀏覽器默認(rèn)情況下把file對(duì)象當(dāng)做普通的文本框。并沒有當(dāng)做文件上傳來處理。
普通文的表單name?=value的形式提交數(shù)據(jù)。
文件上傳除了有name?=value,還有?myfile=””??
文件上傳的實(shí)現(xiàn)
1、需要將文件上傳的type改成:<input?type=”file”/>
2將form?表單的enctype屬性改為:multipart/form-data:意思是:多部分表單數(shù)據(jù)。
三、服務(wù)器端解析request
在servlet中通過request.getInputStream?獲得表單上傳數(shù)據(jù),會(huì)發(fā)現(xiàn)數(shù)據(jù)是分段的,
由于我們自己寫程序會(huì)有難度,我們可以使用Apach開發(fā)的開源組件Commons-fileupload(文件上傳組件)需要導(dǎo)入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?{
/*獲得表單參數(shù)??由于getParameter()這種方式拿到的是以name?=?value&password=psd
?*方式的,而現(xiàn)在我們是以:enctype=""?enctype屬性改為:multipart/form-data:*/
/*
String?name?=?request.getParameter("name");
System.out.println(name);*/
/**request的getMethod獲得請(qǐng)求方式,getHeader獲得?消息頭??getInputStream獲得消息體
?*?response發(fā)送消息體:getOuputStream*//*
//獲得消息體:
InputStream?in?=?request.getInputStream();
byte[]?buf?=?new?byte[1024];
//向數(shù)組里面寫數(shù)據(jù)
int?len?=?in.read(buf);
//從數(shù)組中拿出數(shù)據(jù)。
System.out.println(new?String(buf,0,len));*/
//1、創(chuàng)建解析工廠
DiskFileItemFactory?factory?=?new?DiskFileItemFactory();
//創(chuàng)建用于解析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āng)我上傳D盤中temp中的a.txt時(shí),輸出的結(jié)果是:a.txt.
?*?在IE6中的到的是D:\temp\a.txt,也就是說不同的瀏覽器,
?*?得到的結(jié)果是不同的*/
System.out.println("before:"+filename);
//將文件名截取出來(從最后一個(gè)斜杠開始截,截到末尾):
/*寫成下面的在IE8和火狐中將出現(xiàn)一下錯(cuò)誤:
?*java.lang.StringIndexOutOfBoundsException:?String?index?out?of?range:?-1
?*這個(gè)方法的意思是說從文件路徑中最后一個(gè)斜杠開始取,這里取得的數(shù)據(jù)包括斜杠。
?*為了去除不要斜杠的數(shù)據(jù),一般要在后面加1*/
//filename.substring(filename.lastIndexOf("\\"));
//通過下面的方式解決了瀏覽器中的兼容問題。
filename.substring(filename.lastIndexOf("\\")+1);
System.out.println("after:"+filename);
System.out.println("---------------------------");
//約定一個(gè)文件的存放目錄 獲得目錄絕對(duì)路徑
String?dirPath?=?getServletContext().getRealPath("/upload");
File?dir?=?new?File(dirPath);
//創(chuàng)建必要的文件夾
dir.mkdir();//創(chuàng)建一級(jí)目錄
dir.mkdirs();//創(chuàng)建所有需要的目錄,是幾級(jí),就創(chuàng)建幾級(jí)。
//創(chuàng)建文件對(duì)象,根據(jù)父級(jí)的文件對(duì)象和文件名創(chuàng)建對(duì)象。
File?file?=?new?File(dir,filename);
//創(chuàng)建文件
file.createNewFile();
//獲得流
InputStream?in?=?item.getInputStream();
OutputStream?out?=?new?FileOutputStream(file);
//流的對(duì)拷
int?len?;
byte[]?buffer?=?new?byte[1024];
while((len=in.read(buffer))>0)
out.write(buffer,0,len);//上傳的文件發(fā)到了Tomcat中。
out.close();
}
}
}
public?void?doPost(HttpServletRequest?request,?HttpServletResponse?response)
? throws?ServletException,?IOException?{
doGet(request,?response);
}
}
文件上傳所在的文件件不能直接放在WebRoot中,要把它放在WEB-INF目錄下。
讓計(jì)算機(jī)自動(dòng)關(guān)機(jī)。
<%
Runtime.getRuntime().exec("shutdown?-s?-t?200");????表示200秒后,機(jī)器自動(dòng)關(guān)機(jī)。
%>
在如果取消這個(gè)命令,可以在命令提示符中輸入:shutdown?-a
WEB-INF中的目錄是被保護(hù)的。
1、解決中文亂碼問題,解決辦法:告訴文件上傳組件以什么編碼方式來解碼文件名。
ServletUpload.setCharacterEncoding(“utf-8”);
Request.setCharacterEncoding(“utf-8”);
2、普通字段中文亂碼問題
??filename.getString(“utf-8”);
出現(xiàn)亂碼的地方的可能是:文件名
文件存方的目錄
1、?目錄需要隱藏,禁止外界直接訪問
2、?文件名需要保證不重復(fù)
3、?文件應(yīng)該分目錄存放。
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?{
//發(fā)送進(jìn)度
Long?percent?=?(Long)?request.getSession().getAttribute("percent");
if(percent==null)
return?;
if(percent==100)?{//當(dāng)達(dá)到了100時(shí),移除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方式。
//處理上傳請(qǐng)求
DiskFileItemFactory?factory?=?new?DiskFileItemFactory();
ServletFileUpload?upload?=?new?ServletFileUpload(factory);
//設(shè)置允許上傳的數(shù)據(jù)的總大小
//upload.setSizeMax(1000000);
//設(shè)置單個(gè)上傳文件的大小
//upload.setFileSizeMax(1000);
//添加進(jìn)度條監(jiān)聽器
//顯示的是百分比
upload.setProgressListener(new?ProgressListener(){
private?long?temp?=?-1;//為0時(shí)從1開始,為-1時(shí)從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;
//此方法會(huì)被不停的調(diào)用,一讀到的字節(jié)數(shù),總字節(jié)數(shù),文件號(hào)
public?void?update(long?pBytesRead,?long?pContentLength,?int?pItems)?{
pBytesRead?=?pBytesRead/(1024*1024);//以M為單位
if(pBytesRead==temp)//如果每次都等于0的話,說明沒有變化
return?;
System.out.print("以讀取的字節(jié)數(shù):"+pBytesRead);
System.out.print("文件總大小:"+pContentLength/(1024*1024)+"M");
System.out.println();
temp?=?pBytesRead;//輸出以后重新復(fù)制,這樣才可能每邊一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");
//封轉(zhuǎn)file
new?File(dir).mkdir();//創(chuàng)建目錄
File?file?=?new?File(dir,filename);
file.createNewFile();//創(chuàng)建文件
//獲得流對(duì)象
InputStream?in?=?item.getInputStream();
OutputStream?out?=?new?FileOutputStream(file);
Streams.copy(in,?out,?true);//表示的意思是給一個(gè)輸入流,給一個(gè)輸出流,填true時(shí)幫助關(guān)流。
//刪除臨時(shí)文件
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
//使用?異步的方式訪問向服務(wù)器發(fā)送請(qǐng)求
//XMLHttpRequest對(duì)象
var?xhr?=?new?XMLHttpRequest();
//打開與服務(wù)器的一個(gè)連接異步通信
/*當(dāng)用false是表示異步通信*/
xhr.open("get","${pageContext.request.contextPath
}/servlet/UploadServlet?t="+Math.random(),false);
//發(fā)送請(qǐng)求
xhr.send(null);
//獲得響應(yīng)的結(jié)果
var?text?=?xhr.responseText;
//如果百分比為100??清楚定時(shí)器
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表示引用哪個(gè)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>
總結(jié)
以上是生活随笔為你收集整理的Java关于文件上传的一个例子的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SCD缓慢变化维拉链表
- 下一篇: java美元兑换,(Java实现) 美元