1.ファイルアップロード概要
Web開発でファイルアップロード機能を実現するには、2つのステップが必要です。
1.入力項目をWebページに追加します
<form action = "#" method = "post" enctype = "multipart/form-data"> <input "file" name = "filename1"/> <br> <入力タイプ= "file" name = "filename2"/> <br> <入力タイプ= "submit" value = "upload"/> <form> <!-1。この値を設定した後、ブラウザがファイルをアップロードすると、ファイルデータがHTTP要求メッセージ本文に添付され、MIMEプロトコルを使用してアップロードされたファイルを説明し、受信機を容易にしてアップロードされたデータを解析および処理します。 3.入力の名前属性を設定する必要があります。そうしないと、ブラウザはアップロードされたファイルデータを送信しません。 - >
2.サーブレットのファイルアップロードデータを読み取り、サーバーハードディスクに保存します
リクエストオブジェクトは、クライアントが送信したデータを読み取ることができるGetInputStreamメソッドを提供します。ただし、ユーザーは複数のファイルを同時にアップロードする可能性があるため、プログラムしてサーブレット側のアップロードされたデータを直接読み取り、対応するファイルデータを個別に解析することは非常に厄介なタスクです。
たとえば、以下は、ファイルのアップロード時にインターセプトされたブラウザによって送信されたリクエストのHTTPプロトコルの内容の一部です。
Accept-Language:Zh-hans-cn、zh-hans; q = 0.5content-type:multipart/form-data;境界= --------------------------- 7DFA01D1908A4UA-CPU:AMD64ACCEPT-ENCODING:GZIP、DEFLATEUSER-AGENT:MOZILLA/5.0(Windows NT 6.2; win64; x64; trident/7.0; rv:11.0)Geckoctentent-length:653host:653host: Keep-AlivePragma:no-cachecookie:jsessionId = 11ceff8e271ab62ce676b5a87b746b5f ------------------------------ 7dfa01d1908a4content-disposition:form-data; name = "username" Zhangsan ----------------------------- 7DFA01D1908A4CONTENT-DISPOSITION:FORM-DATA; name = "userpass" 1234 ---------------------------- 7dfa01d1908a4content-disposition:form-data; name = "filename1"; filename = "c:/users/asus/desktop/upload.txt" content-type:text/plainsは最初のファイルコンテンツです!---------------------------- 7dfa01d1908a4content-disposition:form-data; name = "filename1"; filename = "c:/users/asus/desktop/upload2.txt" content-type:text/plains is is 2番目のファイルコンテンツ!こんにちは-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
また、上記のデータから、データを手動で分割して読み取ると、堅牢で安定したプログラムを作成することが困難であることがわかります。したがって、ユーザーがデータを処理するように促進するために、Apache Open Source組織は、フォームのアップロードを処理するために使用されるオープンソースコンポーネント(Commons-Fileupload)を提供します。このコンポーネントは優れたパフォーマンスを備えており、APIは非常に簡単に使用でき、開発者はWebファイルのアップロード機能を簡単に実装できます。したがって、Web開発では、通常、Commons-Fileuploadコンポーネントを使用してファイルアップロード機能が実装されます。
2つのJARパッケージをインポートする必要があります:Commons-Fileupload、Commons-Io
Response.setContentType( "text/html; charset = utf-8"); // set response encoding request.setcharacterencoding( "utf-8"); printwriter writer = respons.getwriter(); // get response output sremletinputStream inputstream = request.getInputStream(); // request inputストリーム(); // diskfileitemfactoryオブジェクトを作成します。パラメーターメモリバッファーのサイズを設定し、デフォルト値は10kです。アップロードファイルがバッファサイズよりも大きい場合、Fileuploadコンポーネントは一時ファイルキャッシュ* @param java.io.fileリポジトリを使用してファイルをアップロードします。このパラメーターは一時ファイルディレクトリを指定します。 * *パラメーターのないコンストラクターが使用されている場合、SetSizetHRESHOLD(int syzethreshold)、setRepository(java.io.fileリポジトリ) *メソッドは手動で設定されています */ diskfileItemfactory Factory = new DiskFileItemFactory(); int sizethReshold = 1024*1024; Factory.SetsizethReshold(SizethReshold); file repository = new file(request.getSession()。getServletContext()。getRealPath( "temp")); // System.out.println(request.getSession()。getRealPath()。 Factory.setRepository(リポジトリ); / * *2。DiskFileItemFactoryオブジェクトを使用してServletFileuploadオブジェクトを作成し、アップロードされたファイルのサイズを設定します * * ServletFileuploadオブジェクトは、アップロードされたファイルデータの処理を担当し、フォームの各入力アイテムをファイルにカプセル化します *このオブジェクトの共通メソッドは次のとおりです。アップロードされたフォームがMultiPart/Form-Data Type* List Parserequest(request)であるかどうかを判断します。リクエストオブジェクトを解析し、各入力アイテムをフォームにfileItemオブジェクトにラップし、すべてのfileItems* void setFilesizemax(long filesizemax)を保存するリストコレクションを返します。単一のアップロードされたファイルの最大値* void setSizemax(long sizemax)を設定します。アップロードされたwenjiang* void setheaderencoding()の総額の最大値を設定します。エンコード形式を設定して、ファイル名をアップロードする文字化けコードの問題を解決する*/ servletfileupload upload = new servletfileupload(Factory); upload.setheaderencoding( "utf-8"); //エンコード形式を設定して、ファイル名をアップロードするコードの問題を解決するために/**** 3。 try {parserequest = upload.parserequest(request); } catch(fileuploadexception e){e.printstacktrace(); } / * *4。リストを反復します。各ファイルタムオブジェクトを反復し、IsFormfieldメソッドを呼び出してファイルアップロードであるかどうかを判断します* trueは通常のフォームフィールドであることを意味します。次に、getFieldNameとgetStringメソッドを呼び出してフィールド名とフィールド値を取得します* falseはアップロードファイルです。このオブジェクトは次のとおりです。 * boolean isformfield(); fileItemがファイルアップロードオブジェクトまたは通常のフォームオブジェクトであるかどうかを判断します * trueは通常のフォームフィールドであることを意味します * getFieldNameを呼び出して、フィールド名とフィールド値を取得するためにgetStringメソッド *アップロードファイルとしてfalse *、次にgetName()を呼び出してアップロードファイルのファイル名を取得します。注:一部のブラウザはクライアントパスを搭載しており、[データ入力ストリームを取得するためにgetInputStream()メソッドを呼び出す必要があります。 fileitem入力ストリームを閉じた後、削除を削除することを意味します。 */for(fileitem fileitem:parserequest){if(fileitem.isformfield()){//通常のフィールドを表しますif( "username" .equals(fileitem.getfieldname()))){string username = fileItem.getString(); writer.write( "your username:"+username+"<br>"); } if( "userpass" .equals(fileitem.getFieldName())){String userPass = fileItem.getString(); writer.write( "パスワード:"+userpass+"<br>"); }} else {//アップロードされたファイルを意味します//異なるブラウザによってアップロードされたファイルにはパス名があり、文字列clientName = fileItem.getName();文字列filename = ""; if(clientname.contains( "//")){// if "/"はパスのある名前を意味します。最後のファイル名はインターセプトされたfilename = clientname.substring(clientname.lastindexof( "//"))。サブストリング(1); } else {filename = clientName; } uuid randomuuid = uuid.randomuuid(); // 128ビットのグローバルに一意の識別子filename = randomuid.tostring()+filenameを生成します。 / * *ディレクトリ生成アルゴリズムを設計します。ユーザーがアップロードしたファイルの総数が数百万桁以上の注文である場合、それらを同じディレクトリに置くと、ファイルインデックスが非常に遅くなります。 *したがって、ディレクトリ構造を設計して散らばった方法でファイルを保存し、UUIDハッシュアルゴリズムをより小さな範囲に合理的に * uUIDのハッシュコードを8ビットEGオクタルストリングに変換することが非常に必要です。サーバーとオペレーティングシステムの両方の非常に効率的なディレクトリ構造*/ int hashuid = randomuid.hashcode(); string hexuuid = integer.tohexstring(hashuuid); //system.out.println(hexuuid); //アップロードされたファイルを文字列filepath = request.getSession()。getServletContext()。getRealPath( "upload");に保存するフォルダーの絶対パスを取得します。 for(char c:hexuuid.tochararray()){filepath = filepath+"/"+c; } //ディレクトリが存在しない場合は、8番目のレベルのディレクトリファイルfilepathfile = new file(filepath)を生成します。 if(!filepathfile.exists()){filepathfile.mkdirs(); } //リクエスト入力ストリームからファイルを読み取り、サーバーに書き込みますinputstream inputstream2 = fileItem.getInputStream(); //サーバー側にファイルを作成するファイル= newファイル(filepath+"/"+filename); BufferedOutputStream bos = new BufferedOutputStream(new fileoutputStream(file)); byte [] buffer = new byte [10*1024]; int len = 0; while((len = inputstream2.read(buffer、0、10*1024))!= -1){bos.write(buffer、0、len); } writer.write( "ファイルをアップロードしました"+clientName+"に正常に<br>"); //リソースを閉じますbos.close(); inputstream2.close(); }} // Eclipseのアップロードされたファイルは、Workspaceのプロジェクトディレクトリではなく、プロジェクトの実行中のディレクトリに保存されていることに注意してください。2。ファイルアップロードに特別な注意が必要な問題:(これらの問題はすべて、上記のコードで簡単なソリューションで提供されます)
1.ファイルを保存する場所
サーバーのセキュリティを確保するには、アップロードされたファイルをアプリケーションのWeb-INFディレクトリ、またはWebサーバーによって管理されていないディレクトリに保存する必要があります。ユーザーがJSPファイルなどの実行可能コードを備えたファイルをアップロードし、スプライシングアクセスパスに従ってアクセスすると、サーバー側で何でもできます。
2。複数のユーザーが同じファイル名でファイルをアップロードしてファイル上書きをもたらさないようにするために、ファイルアップロード装置にアップロードされたファイルに一意のファイル名があることを確認する必要があります。
UUID +ユーザーアップロードファイル名を使用して名前を変更します
uuidについて:
UUID(普遍的に一意の識別子)グローバルに一意の識別子は、マシンで生成された数を指します。これにより、同じ時間と空間のすべてのマシンに固有のものが保証されます。 Open Software Foundation(OSF)が設定した標準によると、イーサネットカードアドレス、ナノ秒時間、チップIDコード、および多くの可能な数値が使用されています。次の部分の組み合わせで構成されています:現在の日付と時刻(UUIDの最初の部分は時間に関連しています。UUIDを生成してから数秒後に別のUUIDを生成する場合、最初の部分は異なります)、残りは同じです)、クロックシーケンス、グローバルに一意のIEEEマシン識別番号(ネットワークカードがあります)が得られます。生成された結果の文字列は比較的長くなるということです。
これは、一般に16進数で表される128ビットの長い数です。アルゴリズムの中心的なアイデアは、マシンのネットワークカード、現地時間、およびインスタント番号と組み合わせてGUIDを生成することです。理論的には、マシンが1秒あたり100,000ガイドを生成する場合、3240年が繰り返されないことを(確率の意味で)保証できます。
JDK1.5から始めて、JDKがUUIDを実装していると考えて、UUIDを生成することは簡単なことになりました。
java.util.uuid、直接呼び出すだけです。
uuid uuid = uuid.randomuuid();
string s = uuid.randomuuid()。toString(); //データベースの生成に使用されるプライマリキーIDは非常に良いです。 。
UUIDは16桁の数字で構成されており、これはの形で表されます
550E8400-E29B-11D4-A716-446655440000
3。単一のディレクトリ内のファイルが多すぎて、ファイルの読み取り速度に影響を与えるために、ファイルのアップロードを処理するプログラムは、可能なアップロードボリュームに基づいて適切なディレクトリ構造生成アルゴリズムを選択し、アップロードされたファイルを分散方法で保存する必要があります。たとえば、ハッシュコードメソッドを使用して、マルチレベルディレクトリを構築します。
4.異なるユーザーが同じファイルをアップロードした場合、サーバー側に同じファイルの多くのコピーを保存する必要はありません。これはリソースの無駄です。ファイルの重複の問題を解決するようにアルゴリズムを設計する必要があります。
5。JSPテクノロジーの原則は、マルチスレッドを自動的に実装します。したがって、開発者はファイルのアップロードのマルチスレッド操作を検討する必要はありません
3。ファイルのダウンロード
<%ArrayList <String> filenames = new ArrayList <String>(); filenames.add( "file/aa.txt"); filenames.add( "file/bb.jpg"); for(string filename:filenames){%> <form action = "downloadservlet" method = "get"> <input type = "hidden" name = "filename" value = "<%= filename%>" /> <入力タイプ= "subming" value = "ダウンロード:<%= filename%>" />> < /<%} <%文字列filename = request.getParameter( "filename"); string urlname = urlencoder.encode(filename、 "utf-8"); //中国語のresponse.setheader( "content-disposition"、 "attachment; filename ="+urlname); fileInputStream fis = new fileInputStream(new file(request.getSession()。getServletContext()。getRealPath(filename))); BufferedInputStream bis = new BufferedInputStream(FIS); ServletOutputStream SOS = Response.GetOutputStream(); byte [] buffer = new byte [1024]; int len = 0; while((len = bis.read(buffer、0、1024))!= -1){sos.write(buffer、0、len); } bis.close(); fis.close();4. SSHのSmartuploadコンポーネントを使用して、ファイルのアップロードとダウンロードを簡素化します
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。