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>
相關文章
- 關於node實現檔案上傳
- 請教一個問題,關於上傳檔案和圖片的問題
- Django檔案上傳 -- 適用於單一小檔案上傳Django
- 關於檔案上傳的問題smartUpload
- uploadify前臺上傳檔案,java後臺處理的例子Java
- 檔案上傳之三基於flash的檔案上傳
- 單個檔案上傳和批量檔案上傳
- 關於laravel上傳的檔案驗證或者的表示?Laravel
- Java Web 檔案上傳JavaWeb
- 關於檔案上傳下載的編碼問題
- Java 中的 GraphQL 上傳檔案Java
- 請教一個檔案上傳的問題
- Java程式設計思想中關於閉包的一個例子Java程式設計
- 關於一個java專案呼叫另一個java專案的心得Java
- spring mvc(註解)上傳檔案的簡單例子SpringMVC單例
- XML上傳檔案例子(轉)XML
- 檔案上傳的幾個 - 示例
- JAVA檔案上傳下載Java
- Java如何上傳大檔案Java
- Java檔案上傳細講Java
- 【Java基礎】--上傳檔案Java
- MVC檔案上傳 - 使用Request.Files上傳多個檔案MVC
- 【詳細】關於Android上傳檔案的幾種方式Android
- 關於責任鏈模式的一個例子模式
- 關於Java的RMI程式設計的一個簡單的例子 (轉)Java程式設計
- Java大檔案上傳、分片上傳、多檔案上傳、斷點續傳、上傳檔案minio、分片上傳minio等解決方案Java斷點
- php單個檔案上傳PHP
- php多個檔案上傳PHP
- LoadRunner中檔案操作的一個例子
- 使用java的MultipartFile實現layui官網檔案上傳實現全部示例,java檔案上傳JavaUI
- java上傳檔案跟批量下載檔案Java
- php檔案上傳之多檔案上傳PHP
- 關於檔案上傳那些可能不怎麼對的姿勢
- 關於檔案上傳下載我所知道的全部內容
- Asp.net中關於上傳檔案的各項基本操作ASP.NET
- 記一個 FormData 多檔案上傳問題ORM
- 關於委託事件的一兩個很好的例子!事件
- 10個HTML檔案上傳技巧HTML