Javaファイルアップロードの詳細
15894 ワード
ファイルアップロードとは?
ファイルアップロードとは、ユーザーの情報を保存することです.
なぜファイルのアップロードが必要ですか?
ユーザー登録の際、ユーザーが写真を提出する必要がある場合があります.では、この写真は保存するべきです.
コンポーネントのアップロード(ツール)
なぜアップロードツールを使用するのですか?
なぜコンポーネントをアップロードする必要がありますか?クライアントのデータを取得する場合は、getParameter()メソッドで取得するのが一般的です.
アップロードファイルデータはMIMEプロトコルにより分割され,フォームはバイナリカプセル化されている.つまり、getParameter()は、アップロードされたファイルのデータを取得できません.
まず、ファイルにhttpをアップロードする方法を見てみましょう. jspページ、フォームはenctype:multipart/form-data を指定する必要があります. httpスナップ サーブレット上でgetParameter()を使用してデータを取得しようと試みる . getParameterを直接使用してもデータは取得できません.
では、私たちはどうすればいいのでしょうか???requestオブジェクトはサーブレットInputStreamストリームを提供し、データを読み取ります.ファイル を読み込んでみました jspページにinputコントロール を追加私がアップロードしたテキストファイルの内容は111111で、読み取り効果は以下の通りです: アップロードされたファイルのデータを読み取ることができますが、どうやってファイルにアップロードされたデータと普通にサーバーに転送されたデータを分割するのでしょうか??上の図では、彼らが混ざっているのを見ました.
私たちの普段のやり方では分割しにくいので、コンポーネントをアップロードする必要があります.
アップロードコンポーネントには2種類あります FileUpload【操作が複雑】 SamrtUpload【操作が簡単】 FileUpload
FileUploadコンポーネントを使用するには、2つのjarパッケージをインポートする必要があります. commons-io Commons-fileupload
開発手順解析ファクトリオブジェクトの作成【DiskFileItemFactory】 解析工場を通じて解析器を作成する【サーブレットFileUpload】 解析器メソッドを呼び出してrequestオブジェクトを解析し、アップロードされたすべてのコンテンツ【list】 を得る listを巡り、各オブジェクトがアップロードファイルであるか否かを判断する 通常フォームフィールドの場合、フィールド名とフィールド値 が得られる.ファイルをアップロードする場合、InputSteamメソッドを呼び出して入力ストリームを得る、アップロードされたデータ を読み出す.
クイックスタート
テスト普通のフィールドもアップロードしたファイルも読めるようになりました!
SmartUpload
SmartUploadコンポーネントを使用するには、smartupload.jar開発パッケージをインポートする必要があります.
クイックスタート
テスト
同様に、uploadFileフォルダにファイルをアップロードできます.コード量も确かにかなり减っています!
通常フィールドのパラメータも取得できます
ファイル名をアップロードする中国語の文字化けしとデータをアップロードする中国語の文字化けし私はファイル名を中国語に変えて、文字化けしました: フォームから提出された中国語のデータも文字化けした.
前述したように、ファイルのデータをアップロードするフォームはバイナリパッケージされているので、requestを使用してデータを符号化し、フォームから送信されたデータには効果的ではありません!
FileUploadの文字化けし
FileUploadを使って文字化けし問題を解決するのは簡単です中国語のファイル名の文字化けしを解決して、解析器を得た後に、直接解析器の符号化を設けてUTF-8になります! フォームデータの乱符号化を解決し、フォーム値を取得する際にUTF-8符号化に従って を取得する.
効果:
SmartUploadの文字化けし
このコンポーネントは文字化けしの問題を解決するのが少し面倒で、ネット上でいろいろな方法を探しても簡単な方法が見つからなかった......
だから、もしデータが中国語に及ばないならばSmartUploadコンポーネントを使って、中国語のデータに関連してFileUploadコンポーネントを使いましょう!
複数ファイルのアップロード、アップロードコントロールの動的追加
現在、アップロードするファイルが複数あると仮定し、アップロードするファイルの数は不確定です.では、私たちはどうすればいいのでしょうか??
多くのアップロードファイルのコントロールをページにリストすることはできません.これは美しくありません.ユーザーがそんなに多くのコントロールを使えなければ、無駄ですね.
だから、私たちは動的にファイルをアップロードするコントロールを追加したいと思っています.もしユーザーがファイルをアップロードしたいなら、動的にコントロールを生成するだけでいいです.
ぶんせき
ページ上でコントロールを動的に生成するには、JavaScriptコードを使用することにほかならない.
では、私たちはどうすればいいのでしょうか.
ユーザーがファイルをアップロードしたい場合は、ボタンをクリックしてイベントをバインドし、ファイルアップロードのコントロールを生成します.
より完璧にするために、ファイルアップロードのコントロールを生成するたびに、削除ボタンを提供して、このコントロールを削除します!
divを使用して生成するコントロールと削除ボタンをロードする必要がありますが、ユーザーが削除をクリックすると、削除ボタンとファイルアップロードコントロールを一緒に隠す必要があります.だから、ネストdivを使ったほうがいい!
コード#コード#ページコード: javaScriptコード
ファイルアップロードの詳細アップロードファイルのサイズが私たちが設定したファイルのサイズより大きい場合、ファイルはアップロード時に一時ファイルを使用してアップロードデータを保存します.アップロードが完了したら、一時ファイル を削除する必要があります.アップロードするファイルの位置はWEBサーバーの管理下にあることができなくて、さもなくば安全な問題をもたらす可能性があります【他の人は手段を通じてアップロードするファイルを修正する可能性があります】 アップロードファイル名が同じであれば、元のアップロードファイルを上書きします.ユニークなファイル名を生成します. ユーザー数が多い場合は、アップロードファイルが非常に多いです.では、1つのディレクトリにすべてのアップロードファイルを保存するべきではありません.これにより、ディスクがクラッシュする可能性があります.アップロードしたファイルを別のディレクトリに分散します.
ぶんせき
一時ファイルの問題を削除するのは簡単です.すべての操作が完了した後、FileItemのdelete()メソッドを呼び出すだけです.
アップロードするファイルの位置をWEBサーバーの管理下に置くことができなくて、私達はアップロードするファイルの位置をWEB-INF/ディレクトリの下に置くことができます!
ファイル名が同じ問題は、UID+ユーザーがアップロードしたファイル名を使用して、アップロードファイル名を保存することができます.このようなファイル名はユニークです.
アップロードしたファイルを分散するには、HashCodeアルゴリズムを使用して分散する必要があります.下位4ビット生成一級ディレクトリ 5-8ビット生成2次ディレクトリ コード#コード#
次に、比較的完全なアップロードファイルコードを書きます. hashCodeアルゴリズムを使用して保存ディレクトリ を分散する.ユニークなファイル名 を生成にアップロードされたコード
効果:ディレクトリの分散に成功し、ファイル名もユニークになりました.
アップロードディレクトリの下のファイルをリストして、ダウンロードを提供します
resposeオブジェクトを説明するときにファイルのダウンロードを説明しました.今回は、ファイルのダウンロードを強化するための小さなケースを直接書きます.アップロードディレクトリの下のファイルは3つの があります.
ぶんせき
まず、ディレクトリの下のファイルをすべて列挙します.後でファイル名に従ってファイルをダウンロードするので、すべてのファイルを1つのMapセットで保存します.
ファイルをダウンロードする部分も簡単で、ファイル名とアップロードファイルの場所に応じて対応するファイルを見つけて読み書きし、メッセージヘッダを修正してダウンロードすればいいです.は、アップロードファイルをロードするパスを取得し、すべてのファイルを再帰的に検索(ファイルが再帰出口であるか否かを判断)することにより、Mapセットに をロードする. Mapコレクションをフロントに転送して展示 を行うユーザがダウンロードをクリックすると、元の名前から絶対パス を取得する.リソースが存在する場合、ユーザは をダウンロードすることができる.
コード#コード# WEB-INF/ディレクトリに格納ファイルをすべてMapコレクションに ダウンロード可能ファイル をJSPページに表示ダウンロードを実現するサーブレット
効果
文章に間違いがあれば指摘を歓迎し、みんなで交流します.微信で技術的な文章を読むことに慣れている学生は、微信の公衆番号:Java 3 yに注目することができます.
ファイルアップロードとは、ユーザーの情報を保存することです.
なぜファイルのアップロードが必要ですか?
ユーザー登録の際、ユーザーが写真を提出する必要がある場合があります.では、この写真は保存するべきです.
コンポーネントのアップロード(ツール)
なぜアップロードツールを使用するのですか?
なぜコンポーネントをアップロードする必要がありますか?クライアントのデータを取得する場合は、getParameter()メソッドで取得するのが一般的です.
アップロードファイルデータはMIMEプロトコルにより分割され,フォームはバイナリカプセル化されている.つまり、getParameter()は、アップロードされたファイルのデータを取得できません.
まず、ファイルにhttpをアップロードする方法を見てみましょう.
String ss = request.getParameter("username");
System.out.println(ss);
では、私たちはどうすればいいのでしょうか???requestオブジェクトはサーブレットInputStreamストリームを提供し、データを読み取ります.
ServletInputStream inputStream = request.getInputStream();
byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes)) > 0) {
System.out.println(new String(bytes, 0, len));
}
私たちの普段のやり方では分割しにくいので、コンポーネントをアップロードする必要があります.
アップロードコンポーネントには2種類あります
FileUploadコンポーネントを使用するには、2つのjarパッケージをインポートする必要があります.
開発手順
クイックスタート
try{
//1.
DiskFileItemFactory factory = new DiskFileItemFactory();
//2.
ServletFileUpload upload = new ServletFileUpload(factory);
//3.
if(!upload.isMultipartContent(request)){
// ,
return;
}
// ,
List list = upload.parseRequest(request); //FileItem
// list, fileItem
for(FileItem item : list){
if(item.isFormField()){
//
String name = item.getFieldName(); //
String value = item.getString();
System.out.println(name + "=" + value);
}else{
//
String filename = item.getName(); // C:\Documents and Settings\ThinkPad\ \1.txt
filename = filename.substring(filename.lastIndexOf("\\")+1);
InputStream in = item.getInputStream(); //
int len = 0;
byte buffer[]= new byte[1024];
String savepath = this.getServletContext().getRealPath("/upload");
FileOutputStream out = new FileOutputStream(savepath + "\\" + filename); // upload
while((len=in.read(buffer))>0){
out.write(buffer, 0, len);
}
in.close();
out.close();
}
}
}catch (Exception e) {
e.printStackTrace();
}
テスト
SmartUpload
SmartUploadコンポーネントを使用するには、smartupload.jar開発パッケージをインポートする必要があります.
クイックスタート
//
SmartUpload smartUpload = new SmartUpload();
//
smartUpload.initialize(this.getServletConfig(), request, response);
try {
//
smartUpload.upload();
// , request 。 smartUpload
String password = smartUpload.getRequest().getParameter("password");
System.out.println(password);
// uploadFile
smartUpload.save("uploadFile");
} catch (SmartUploadException e) {
e.printStackTrace();
}
テスト
同様に、uploadFileフォルダにファイルをアップロードできます.コード量も确かにかなり减っています!
通常フィールドのパラメータも取得できます
ファイル名をアップロードする中国語の文字化けしとデータをアップロードする中国語の文字化けし
前述したように、ファイルのデータをアップロードするフォームはバイナリパッケージされているので、requestを使用してデータを符号化し、フォームから送信されたデータには効果的ではありません!
FileUploadの文字化けし
FileUploadを使って文字化けし問題を解決するのは簡単です
// upload
fileUpload.setHeaderEncoding("UTF-8");
String value = fileItem.getString("UTF-8");
効果:
SmartUploadの文字化けし
このコンポーネントは文字化けしの問題を解決するのが少し面倒で、ネット上でいろいろな方法を探しても簡単な方法が見つからなかった......
だから、もしデータが中国語に及ばないならばSmartUploadコンポーネントを使って、中国語のデータに関連してFileUploadコンポーネントを使いましょう!
複数ファイルのアップロード、アップロードコントロールの動的追加
現在、アップロードするファイルが複数あると仮定し、アップロードするファイルの数は不確定です.では、私たちはどうすればいいのでしょうか??
多くのアップロードファイルのコントロールをページにリストすることはできません.これは美しくありません.ユーザーがそんなに多くのコントロールを使えなければ、無駄ですね.
だから、私たちは動的にファイルをアップロードするコントロールを追加したいと思っています.もしユーザーがファイルをアップロードしたいなら、動的にコントロールを生成するだけでいいです.
ぶんせき
ページ上でコントロールを動的に生成するには、JavaScriptコードを使用することにほかならない.
では、私たちはどうすればいいのでしょうか.
ユーザーがファイルをアップロードしたい場合は、ボタンをクリックしてイベントをバインドし、ファイルアップロードのコントロールを生成します.
より完璧にするために、ファイルアップロードのコントロールを生成するたびに、削除ボタンを提供して、このコントロールを削除します!
divを使用して生成するコントロールと削除ボタンをロードする必要がありますが、ユーザーが削除をクリックすると、削除ボタンとファイルアップロードコントロールを一緒に隠す必要があります.だから、ネストdivを使ったほうがいい!
コード#コード#
:
function addUploadFile() {
//
var input = document.createElement("input");
input.type = 'file';
input.name = 'fileName';
//
var del = document.createElement("input");
del.type = 'button';
del.value = ' ';
// div
var innerDiv = document.createElement("div");
// div
innerDiv.appendChild(input);
innerDiv.appendChild(del);
// div , div div
var outterDiv = document.getElementById("file");
outterDiv.appendChild(innerDiv);
//
del.onclick = function dele() {
// div remove div
this.parentNode.parentNode.removeChild(this.parentNode);
}
}
ファイルアップロードの詳細
ぶんせき
一時ファイルの問題を削除するのは簡単です.すべての操作が完了した後、FileItemのdelete()メソッドを呼び出すだけです.
アップロードするファイルの位置をWEBサーバーの管理下に置くことができなくて、私達はアップロードするファイルの位置をWEB-INF/ディレクトリの下に置くことができます!
ファイル名が同じ問題は、UID+ユーザーがアップロードしたファイル名を使用して、アップロードファイル名を保存することができます.このようなファイル名はユニークです.
アップロードしたファイルを分散するには、HashCodeアルゴリズムを使用して分散する必要があります.
次に、比較的完全なアップロードファイルコードを書きます.
private String makeDirPath(String fileName, String path) {
//
int hashCode = fileName.hashCode();
int dir1 = hashCode & 0xf;
int dir2 = (hashCode & 0xf0) >> 4;
String dir = path + "\\" + dir1 + "\\" + dir2;
// ,
File file = new File(dir);
if (!file.exists()) {
file.mkdirs();
}
//
return dir;
}
private String makeFileName(String fileName) {
// UUID , 。
return UUID.randomUUID().toString() + "_"+ fileName;
}
//
DiskFileItemFactory factory = new DiskFileItemFactory();
//
ServletFileUpload fileUpload = new ServletFileUpload(factory);
// upload
fileUpload.setHeaderEncoding("UTF-8");
//
if(!fileUpload.isMultipartContent(request)){
// ,
return;
}
try {
// request , List【 】
List list = fileUpload.parseRequest(request);
// List,
for (FileItem fileItem : list) {
//
if (fileItem.isFormField()) {
//
String name = fileItem.getFieldName();
String value = fileItem.getString("UTF-8");
System.out.println(name + " = " + value);
} else {
//
// 【 】
String fileName = fileItem.getName();
//
fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
//
fileName = makeFileName(fileName);
InputStream inputStream = fileItem.getInputStream();
// ,
String path = this.getServletContext().getRealPath("/WEB-INF/uploadFile");
//
String realPath = makeDirPath(fileName, path);
FileOutputStream outputStream = new FileOutputStream(realPath + "\\" + fileName);
byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes)) > 0) {
outputStream.write(bytes, 0, len);
}
inputStream.close();
outputStream.close();
//
fileItem.delete();
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
効果:
アップロードディレクトリの下のファイルをリストして、ダウンロードを提供します
resposeオブジェクトを説明するときにファイルのダウンロードを説明しました.今回は、ファイルのダウンロードを強化するための小さなケースを直接書きます.
ぶんせき
まず、ディレクトリの下のファイルをすべて列挙します.後でファイル名に従ってファイルをダウンロードするので、すべてのファイルを1つのMapセットで保存します.
ファイルをダウンロードする部分も簡単で、ファイル名とアップロードファイルの場所に応じて対応するファイルを見つけて読み書きし、メッセージヘッダを修正してダウンロードすればいいです.
コード#コード#
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//
String filePath = this.getServletContext().getRealPath("/WEB-INF/uploadFile");
Map map = new HashMap();
// , Map
getAllFiles(new File(filePath), map);
request.setAttribute("map", map);
request.getRequestDispatcher("/listFile.jsp").forward(request, response);
}
private void getAllFiles(File filePath, Map map) {
// ,
if (!filePath.isFile()) {
// ( , )
File[] files = filePath.listFiles();
for (File file : files) {
// ( )
getAllFiles(file, map);
}
} else {
// else ,
//
String fileName = filePath.getName().substring(filePath.getName().lastIndexOf("_") + 1);
// key, value map
map.put(filePath.getName(), fileName);
}
}
${me.value}ダウンロード!
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//
String fileName = request.getParameter("fileName");
// , 。
fileName = new String(fileName.getBytes("ISO8859-1"), "utf-8");
//
String path = this.getServletContext().getRealPath("/WEB-INF/uploadFile");
// hashCode ,
String fileRealPath = makeFilePath(fileName, path);
System.out.println(fileRealPath);
//
File file = new File(fileRealPath);
if (!file.exists()) {
request.setAttribute("message", " !");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return ;
}
//
//
FileInputStream inputStream = new FileInputStream(fileRealPath);
byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes)) > 0) {
response.getOutputStream().write(bytes, 0, len);
}
inputStream.close();
// , ,
String name = fileName.substring(fileName.lastIndexOf("_") + 1);
response.setHeader("content-disposition","attachment;filename=" + URLEncoder.encode(name, "UTF-8"));
}
private String makeFilePath(String fileName, String path) {
int hashCode = fileName.hashCode();
int dir1 = hashCode & 0xf;
int dir2 = (hashCode & 0xf0) >> 4;
String dir = path + "\\" + dir1 + "\\" + dir2 +"\\"+ fileName;
return dir;
}
効果
文章に間違いがあれば指摘を歓迎し、みんなで交流します.微信で技術的な文章を読むことに慣れている学生は、微信の公衆番号:Java 3 yに注目することができます.