***
23191 ワード
Webアプリケーションシステムの開発において、ファイルのアップロードとダウンロード機能は非常によく使われる機能であり、今日はJavaWebにおけるファイルのアップロードとダウンロード機能の実現についてお話しします.
ファイルのアップロードについては、ブラウザがアップロード中にファイルをストリームとしてサーバ側に提出するので、サーブレットを直接使用してアップロードファイルの入力ストリームを取得してから中の要求パラメータを解析するのは面倒なので、apacheのオープンソースツールcommon-fileuploadというファイルアップロードコンポーネントを使用するのが一般的です.このcommon-fileuploadアップロードコンポーネントのjarパッケージはapache公式サイトにダウンロードしたり、strutsのlibフォルダの下に見つけたりすることができます.strutsアップロードの機能はこれに基づいて実現されています.common-fileuploadはcommon-ioというパッケージに依存するので、このパッケージをダウンロードする必要があります.
一、開発環境の構築
次の図に示すように、FileUpload AndDownLoadプロジェクトを作成し、Apacheのcommons-fileuploadファイルアップロードコンポーネントに関連するJarパッケージを追加します.
二、ファイルアップロードを実現する
2.1、ファイルアップロードページとメッセージ提示ページ
upload.jspページのコードは次のとおりです.
ファイルをアップロード1:
ファイルをアップロード2:
message.jspのコードは以下の通りです.
2.2.ファイルアップロードの処理サーブレット
UploadHandleServiceletのコードは次のとおりです.
Web.xmlファイルにUploadHandleServiceletを登録する
実行効果は次のとおりです.
ファイルのアップロードに成功した後、アップロードしたファイルはWEB-INFディレクトリの下のuploadディレクトリに保存され、下図のように:
2.3、ファイルアップロードの詳細
上記のコードは、サーバ上の指定されたディレクトリにファイルをアップロードすることに成功しましたが、ファイルアップロード機能には注意すべき細部の問題が多く、以下の点で特に注意すべき点がいくつかあります.
1、サーバーの安全を保証するために、アップロードファイルは外部から直接アクセスできないディレクトリの下に置くべきで、例えばWEB-INFディレクトリの下に置く.
2、ファイルの上書きを防止するために、アップロードファイルに一意のファイル名を作成します.
3、1つのディレクトリの下にファイルが多すぎるのを防ぐために、hashアルゴリズムを使用してストレージを分散します.
4、アップロードファイルの最大値を制限する.
5、アップロードファイルの種類を制限するには、アップロードファイル名を受け取ったときに、接尾辞名が合法かどうかを判断します.
上記の5つの詳細について、UploadHandleServletを改善します.改善されたコードは以下の通りです.
上記の5つの細部の問題について改善した後、私たちのファイルアップロード機能は比較的完備しています.
三、ファイルのダウンロード
3.1、ダウンロードを提供するファイル資源をリストする
Webアプリケーションシステムのファイルリソースをユーザーに提供してダウンロードするには、まず、アップロードファイルディレクトリの下のすべてのファイルをリストするページが必要です.ユーザーがファイルをクリックしてハイパーリンクをダウンロードすると、ダウンロード操作を行い、WebアプリケーションシステムのすべてのダウンロードファイルをリストするListFileServiceletを作成します.
ListFileServiceletのコードは次のとおりです.
ここではListFileServiceletのlistfileメソッドについて簡単に説明します.listfileメソッドはディレクトリの下にあるすべてのファイルをリストするためのものです.listfileメソッドの内部には再帰が使われています.実際の開発では、アップロードしたファイル名やファイルの具体的な保存ディレクトリを格納するテーブルをデータベースに作成するに違いありません.この例は、データベースを使用してアップロードされたファイル名とファイルの特定の格納場所を格納していないため、アップロードされたファイルの格納場所はハッシュアルゴリズムを使用して分散格納されているため、再帰に使用する必要があります.取得したファイル名をリストメソッドに外部から渡されたMapコレクションに格納することで,すべてのファイルが同じMapコレクションに格納されることを保証できる.
Web.xmlファイルでListFileServiceletを構成する
ダウンロードファイルのlistfileを表示します.jspページは次のとおりです.
ListFileServiceletにアクセスするとlistfile.jspページには、次の図に示すように、ユーザーにダウンロードされたファイルリソースが表示されます.
3.2、ファイルのダウンロードを実現する
ファイルのダウンロードを処理するサーブレットを作成します.DownLoadサーブレットのコードは次のとおりです.
Web.xmlファイルでのDownLoadServiceletの構成
[ダウンロード]ハイパーリンクをクリックし、DownLoadServiceletに要求を提出すれば処理できます.
実行結果から、私たちのファイルダウンロード機能は正常にファイルをダウンロードできるようになりました.
JavaWebのファイルのアップロードとダウンロード機能に関する内容はこれだけです.
この文書は次のとおりです.http://www.cnblogs.com/xdp-gacl/p/4200090.html#!comments#undefined
いい文だ!ブロガーに感謝!
ファイルのアップロードについては、ブラウザがアップロード中にファイルをストリームとしてサーバ側に提出するので、サーブレットを直接使用してアップロードファイルの入力ストリームを取得してから中の要求パラメータを解析するのは面倒なので、apacheのオープンソースツールcommon-fileuploadというファイルアップロードコンポーネントを使用するのが一般的です.このcommon-fileuploadアップロードコンポーネントのjarパッケージはapache公式サイトにダウンロードしたり、strutsのlibフォルダの下に見つけたりすることができます.strutsアップロードの機能はこれに基づいて実現されています.common-fileuploadはcommon-ioというパッケージに依存するので、このパッケージをダウンロードする必要があります.
一、開発環境の構築
次の図に示すように、FileUpload AndDownLoadプロジェクトを作成し、Apacheのcommons-fileuploadファイルアップロードコンポーネントに関連するJarパッケージを追加します.
二、ファイルアップロードを実現する
2.1、ファイルアップロードページとメッセージ提示ページ
upload.jspページのコードは次のとおりです.
HTML>
ユーザーのアップロード:ファイルをアップロード1:
ファイルをアップロード2:
message.jspのコードは以下の通りです.
HTML>
${message}
2.2.ファイルアップロードの処理サーブレット
UploadHandleServiceletのコードは次のとおりです.
package me.gacl.web.controller;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadHandleServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// , WEB-INF , ,
String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
File file = new File(savePath);
//
if (!file.exists() && !file.isDirectory()) {
System.out.println(savePath+" , ");
//
file.mkdir();
}
//
String message = "";
try{
// Apache :
//1、 DiskFileItemFactory
DiskFileItemFactory factory = new DiskFileItemFactory();
//2、
ServletFileUpload upload = new ServletFileUpload(factory);
//
upload.setHeaderEncoding("UTF-8");
//3、
if(!ServletFileUpload.isMultipartContent(request)){
//
return;
}
//4、 ServletFileUpload , List , FileItem Form
List list = upload.parseRequest(request);
for(FileItem item : list){
// fileitem
if(item.isFormField()){
String name = item.getFieldName();
//
String value = item.getString("UTF-8");
//value = new String(value.getBytes("iso8859-1"),"UTF-8");
System.out.println(name + "=" + value);
}else{// fileitem
// ,
String filename = item.getName();
System.out.println(filename);
if(filename==null || filename.trim().equals("")){
continue;
}
// : , , : c:\a\b\1.txt, , :1.txt
// ,
filename = filename.substring(filename.lastIndexOf("\\")+1);
// item
InputStream in = item.getInputStream();
//
FileOutputStream out = new FileOutputStream(savePath + "\\" + filename);
//
byte buffer[] = new byte[1024];
//
int len = 0;
// ,(len=in.read(buffer))>0 in
while((len=in.read(buffer))>0){
// FileOutputStream (savePath + "\\" + filename)
out.write(buffer, 0, len);
}
//
in.close();
//
out.close();
//
item.delete();
message = " !";
}
}
}catch (Exception e) {
message= " !";
e.printStackTrace();
}
request.setAttribute("message",message);
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
Web.xmlファイルにUploadHandleServiceletを登録する
UploadHandleServlet
me.gacl.web.controller.UploadHandleServlet
UploadHandleServlet
/servlet/UploadHandleServlet
実行効果は次のとおりです.
ファイルのアップロードに成功した後、アップロードしたファイルはWEB-INFディレクトリの下のuploadディレクトリに保存され、下図のように:
2.3、ファイルアップロードの詳細
上記のコードは、サーバ上の指定されたディレクトリにファイルをアップロードすることに成功しましたが、ファイルアップロード機能には注意すべき細部の問題が多く、以下の点で特に注意すべき点がいくつかあります.
1、サーバーの安全を保証するために、アップロードファイルは外部から直接アクセスできないディレクトリの下に置くべきで、例えばWEB-INFディレクトリの下に置く.
2、ファイルの上書きを防止するために、アップロードファイルに一意のファイル名を作成します.
3、1つのディレクトリの下にファイルが多すぎるのを防ぐために、hashアルゴリズムを使用してストレージを分散します.
4、アップロードファイルの最大値を制限する.
5、アップロードファイルの種類を制限するには、アップロードファイル名を受け取ったときに、接尾辞名が合法かどうかを判断します.
上記の5つの詳細について、UploadHandleServletを改善します.改善されたコードは以下の通りです.
package me.gacl.web.controller;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
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.FileUploadBase;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
* @ClassName: UploadHandleServlet
* @Description: TODO( )
* @author:
* @date: 2015-1-3 11:35:50
*
*/
public class UploadHandleServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// , WEB-INF , ,
String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
//
String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
File tmpFile = new File(tempPath);
if (!tmpFile.exists()) {
//
tmpFile.mkdir();
}
//
String message = "";
try{
// Apache :
//1、 DiskFileItemFactory
DiskFileItemFactory factory = new DiskFileItemFactory();
// , , 。
factory.setSizeThreshold(1024*100);// 100KB, , 10KB
//
factory.setRepository(tmpFile);
//2、
ServletFileUpload upload = new ServletFileUpload(factory);
//
upload.setProgressListener(new ProgressListener(){
public void update(long pBytesRead, long pContentLength, int arg2) {
System.out.println(" :" + pContentLength + ", :" + pBytesRead);
/**
* :14608, :4096
:14608, :7367
:14608, :11419
:14608, :14608
*/
}
});
//
upload.setHeaderEncoding("UTF-8");
//3、
if(!ServletFileUpload.isMultipartContent(request)){
//
return;
}
// , 1024*1024 , 1MB
upload.setFileSizeMax(1024*1024);
// , = , 10MB
upload.setSizeMax(1024*1024*10);
//4、 ServletFileUpload , List , FileItem Form
List list = upload.parseRequest(request);
for(FileItem item : list){
// fileitem
if(item.isFormField()){
String name = item.getFieldName();
//
String value = item.getString("UTF-8");
//value = new String(value.getBytes("iso8859-1"),"UTF-8");
System.out.println(name + "=" + value);
}else{// fileitem
// ,
String filename = item.getName();
System.out.println(filename);
if(filename==null || filename.trim().equals("")){
continue;
}
// : , , : c:\a\b\1.txt, , :1.txt
// ,
filename = filename.substring(filename.lastIndexOf("\\")+1);
//
String fileExtName = filename.substring(filename.lastIndexOf(".")+1);
// ,
System.out.println(" :"+fileExtName);
// item
InputStream in = item.getInputStream();
//
String saveFilename = makeFileName(filename);
//
String realSavePath = makePath(saveFilename, savePath);
//
FileOutputStream out = new FileOutputStream(realSavePath + "\\" + saveFilename);
//
byte buffer[] = new byte[1024];
//
int len = 0;
// ,(len=in.read(buffer))>0 in
while((len=in.read(buffer))>0){
// FileOutputStream (savePath + "\\" + filename)
out.write(buffer, 0, len);
}
//
in.close();
//
out.close();
//
//item.delete();
message = " !";
}
}
}catch (FileUploadBase.FileSizeLimitExceededException e) {
e.printStackTrace();
request.setAttribute("message", " !!!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
}catch (FileUploadBase.SizeLimitExceededException e) {
e.printStackTrace();
request.setAttribute("message", " !!!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
}catch (Exception e) {
message= " !";
e.printStackTrace();
}
request.setAttribute("message",message);
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
/**
* @Method: makeFileName
* @Description: , :uuid+"_"+
* @Anthor:
* @param filename
* @return uuid+"_"+
*/
private String makeFileName(String filename){ //2.jpg
// ,
return UUID.randomUUID().toString() + "_" + filename;
}
/**
* , hash
* @Method: makePath
* @Description:
* @Anthor:
*
* @param filename ,
* @param savePath
* @return
*/
private String makePath(String filename,String savePath){
// hashCode , filename
int hashcode = filename.hashCode();
int dir1 = hashcode&0xf; //0--15
int dir2 = (hashcode&0xf0)>>4; //0-15
//
String dir = savePath + "\\" + dir1 + "\\" + dir2; //upload\2\3 upload\3\5
//File
File file = new File(dir);
//
if(!file.exists()){
//
file.mkdirs();
}
return dir;
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
上記の5つの細部の問題について改善した後、私たちのファイルアップロード機能は比較的完備しています.
三、ファイルのダウンロード
3.1、ダウンロードを提供するファイル資源をリストする
Webアプリケーションシステムのファイルリソースをユーザーに提供してダウンロードするには、まず、アップロードファイルディレクトリの下のすべてのファイルをリストするページが必要です.ユーザーがファイルをクリックしてハイパーリンクをダウンロードすると、ダウンロード操作を行い、WebアプリケーションシステムのすべてのダウンロードファイルをリストするListFileServiceletを作成します.
ListFileServiceletのコードは次のとおりです.
package me.gacl.web.controller;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @ClassName: ListFileServlet
* @Description: Web
* @author:
* @date: 2015-1-4 9:54:40
*
*/
public class ListFileServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//
String uploadFilePath = this.getServletContext().getRealPath("/WEB-INF/upload");
//
Map fileNameMap = new HashMap();
// filepath , map
listfile(new File(uploadFilePath),fileNameMap);//File
// Map listfile.jsp
request.setAttribute("fileNameMap", fileNameMap);
request.getRequestDispatcher("/listfile.jsp").forward(request, response);
}
/**
* @Method: listfile
* @Description:
* @Anthor:
* @param file ,
* @param map Map
*/
public void listfile(File file,Map map){
// file ,
if(!file.isFile()){
//
File files[] = file.listFiles();
// files[]
for(File f : files){
//
listfile(f,map);
}
}else{
/**
* , uuid_ , uuid_
file.getName().indexOf("_") "_" , :9349249849-88343-8344_ _ _ .avi
file.getName().substring(file.getName().indexOf("_")+1) _ _ .avi
*/
String realName = file.getName().substring(file.getName().indexOf("_")+1);
//file.getName() , , key,realName ,
map.put(file.getName(), realName);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
ここではListFileServiceletのlistfileメソッドについて簡単に説明します.listfileメソッドはディレクトリの下にあるすべてのファイルをリストするためのものです.listfileメソッドの内部には再帰が使われています.実際の開発では、アップロードしたファイル名やファイルの具体的な保存ディレクトリを格納するテーブルをデータベースに作成するに違いありません.この例は、データベースを使用してアップロードされたファイル名とファイルの特定の格納場所を格納していないため、アップロードされたファイルの格納場所はハッシュアルゴリズムを使用して分散格納されているため、再帰に使用する必要があります.取得したファイル名をリストメソッドに外部から渡されたMapコレクションに格納することで,すべてのファイルが同じMapコレクションに格納されることを保証できる.
Web.xmlファイルでListFileServiceletを構成する
ListFileServlet
me.gacl.web.controller.ListFileServlet
ListFileServlet
/servlet/ListFileServlet
ダウンロードファイルのlistfileを表示します.jspページは次のとおりです.
HTML>
${me.value}ダウンロード
ListFileServiceletにアクセスするとlistfile.jspページには、次の図に示すように、ユーザーにダウンロードされたファイルリソースが表示されます.
3.2、ファイルのダウンロードを実現する
ファイルのダウンロードを処理するサーブレットを作成します.DownLoadサーブレットのコードは次のとおりです.
package me.gacl.web.controller;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DownLoadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//
String fileName = request.getParameter("filename"); //23239283-92489- .avi
fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");
// /WEB-INF/upload
String fileSaveRootPath=this.getServletContext().getRealPath("/WEB-INF/upload");
//
String path = findFileSavePathByFileName(fileName,fileSaveRootPath);
//
File file = new File(path + "\\" + fileName);
//
if(!file.exists()){
request.setAttribute("message", " !!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
}
//
String realname = fileName.substring(fileName.indexOf("_")+1);
// ,
response.setHeader("content-disposition", "p_w_upload;filename=" + URLEncoder.encode(realname, "UTF-8"));
// ,
FileInputStream in = new FileInputStream(path + "\\" + fileName);
//
OutputStream out = response.getOutputStream();
//
byte buffer[] = new byte[1024];
int len = 0;
//
while((len=in.read(buffer))>0){
// ,
out.write(buffer, 0, len);
}
//
in.close();
//
out.close();
}
/**
* @Method: findFileSavePathByFileName
* @Description:
* @Anthor:
* @param filename
* @param saveRootPath , /WEB-INF/upload
* @return
*/
public String findFileSavePathByFileName(String filename,String saveRootPath){
int hashcode = filename.hashCode();
int dir1 = hashcode&0xf; //0--15
int dir2 = (hashcode&0xf0)>>4; //0-15
String dir = saveRootPath + "\\" + dir1 + "\\" + dir2; //upload\2\3 upload\3\5
File file = new File(dir);
if(!file.exists()){
//
file.mkdirs();
}
return dir;
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
Web.xmlファイルでのDownLoadServiceletの構成
DownLoadServlet
me.gacl.web.controller.DownLoadServlet
DownLoadServlet
/servlet/DownLoadServlet
[ダウンロード]ハイパーリンクをクリックし、DownLoadServiceletに要求を提出すれば処理できます.
実行結果から、私たちのファイルダウンロード機能は正常にファイルをダウンロードできるようになりました.
JavaWebのファイルのアップロードとダウンロード機能に関する内容はこれだけです.
この文書は次のとおりです.http://www.cnblogs.com/xdp-gacl/p/4200090.html#!comments#undefined
いい文だ!ブロガーに感謝!