1. Überblick über Dateien hochladen
Um die Datei -Upload -Funktion in der Webentwicklung zu realisieren, sind zwei Schritte erforderlich:
1. Addieren Sie die On -Load -Eingabelemente an die Webseite
<form action = "#" methode = "post" engTePe = "multiPart/form-data"> <input type = "Datei" name = "Dateiname1"/> <br> <Eingabe type = "Datei" name = "Dateiname2"/> <br> <Eingabe-Typ = "Subay" -Werbe-Wert "upload"/> <!-1. Nach dem Einstellen dieses Wertes wird die Dateidaten an die HTTP -Anforderungsnachrichtskörper angeschlossen, wenn der Browser die Datei hochlädt und das MIME -Protokoll verwendet, um die hochgeladene Datei zu beschreiben, um den Empfänger zu erleichtern, um die hochgeladenen Daten zu analysieren und zu verarbeiten. 3. Das Namensattribut der Eingabe muss festgelegt werden, andernfalls sendet der Browser die hochgeladenen Dateidaten nicht. ->
2. Lesen Sie die Datei -Upload -Daten im Servlet und speichern Sie sie auf der Server -Festplatte
Das Anforderungsobjekt bietet eine GetInputStream -Methode, über die vom Client übermittelte Daten gelesen werden können. Da Benutzer jedoch gleichzeitig mehrere Dateien hochladen können, ist es eine sehr problematische Aufgabe, die hochgeladenen Daten auf der Servlet -Seite zu programmieren und direkt zu lesen und die entsprechenden Dateidaten separat analysieren.
Beispielsweise finden Sie ein Teil des Inhalts des HTTP -Protokolls der vom abgefangenen Browser gesendeten Anforderung beim Hochladen der Datei:
Akzeptieren Sprache: Zh-Hans-CN, Zh-Hans; q = 0,5Content-Typ: Multipart/Form-Data; Grenze = --------------------------- Keep-AlivePRAGMA: No-Cachecookie: JSESSIONID = 11CEFF8E271AB62CE676B5A87B746B5F ----------------------------- 7DFA01D1908A4Content-Disposition: Form-Data; Name = "Benutzername" Zhangsan ----------------------------- 7DFA01D1908A4Content-Disposition: Formdaten; name = "userpass" 1234 ----------------------------- 7DFA01D1908A4Content-Disposition: Formdaten; name = "Dateiname1"; fileName = "c: /users/asus/desktop/upload.txt" content-type: text/plainthis ist erster Dateiinhalt! --------------------------------- name = "Dateiname1"; fileName = "c: /users/asus/desktop/upload2.txt" content-type: text/plainthis ist zweiter Dateiinhalt! Hallo --------------------------------- 7DFA01D1908A4-
Aus den oben genannten Daten ist auch ersichtlich, dass es schwierig ist, ein robustes und stabiles Programm zu schreiben, wenn Sie die Daten manuell teilen und lesen. Um den Benutzern die Verarbeitung von Daten zu erleichtern, bietet Apache Open Source-Organisation eine Open-Source-Komponente (Commons-fileUpload), die zum Verarbeiten von Formulardatei-Uploads verwendet wird. Diese Komponente hat eine hervorragende Leistung und ihre API ist äußerst einfach zu verwenden, sodass Entwickler die Upload -Funktionen von Webdateien einfach implementieren können. Daher wird in der Webentwicklung die Datei-Upload-Funktion normalerweise mit der Commons-Dateikomponente implementiert.
Zwei JAR-Pakete müssen importiert werden: Commons-fileUpload, Commons-io
response.setContentType ("text/html; charSet = utf-8"); // Antwort-Codierungsanforderung festlegen. Printwriter writer = response.getWriter (); // Antwortausgabe Stream ServletInputStream InputStream = Anrequenz.GetInputStream (); // Anforderungseingangsstream/** 1. Erstellen eines diskfileItemFactory -Objekts, setzen Sie die Puffergröße und temporäre Dateiverzeichnis* Es gibt zwei Konstrukteure in dieser Klasse, ein Konstruktor ohne Parameter. SizeThreshold, dieser Parameter legt die Größe des Speicherpuffers fest, der Standardwert beträgt 10k. Wenn die Upload -Datei größer als die Puffergröße ist, lädt die Datei -Pload -Komponente die Datei mit dem temporären Datei -Cache* @param java.io.file repository hoch * * Wenn ein Konstruktor ohne Parameter verwendet wird, setSizeThreshold (int Sizethreshold), setRepository (java.io.file repository) * wird manuell eingestellt */ diskFileItemFactory factory = new diskfileMFactory (); Int Sizethreshold = 1024*1024; fabrik.setSizethreshold (Sizethreshold); Datei repository = new Datei (request.getSession (). GetServletContext (). GetRealPath ("temp"); // system.out.println (request.getSession (). factory.setRepository (Repository); / * * 2. Verwenden Sie das DiskFileItemFactory -Objekt, um ein ServletFileUpload -Objekt zu erstellen und die Größe der hochgeladenen Datei zu setzen Bestimmen Sie, ob das hochgeladene Formular mit mehrteiler/Form-Daten-Typ* -Liste ParSerequest (Anfrage) ist. Nehmen Sie das Anforderungsobjekt an, wickeln Sie jedes Eingabelement in das Formular in ein FileItem -Objekt ein und geben Sie eine Listensammlung zurück, mit der alle FileItems* void setFileSeMax (Long FileSizemax) gespeichert werden. Setzen Sie den Maximalwert einer einzelnen hochgeladenen Datei* void setSizemax (Long Sizemax); Setzen Sie den Maximalwert der Gesamtmenge des hochgeladenen Wenjiang* void SetheaDerencoding (); Stellen Sie das Codierungsformat ein, um das Problem des Hochladens von Dateinamen des verstümmelten Code zu lösen. Upload.SetheAeDerencoding ("UTF-8"); // Das Codierungsformat festlegen, um das Problem des hochgeladenen Dateinamens für verstümmelten Code zu lösen. versuche {parSerequest = upload.ParSerequest (Anfrage); } catch (FileUploadexception e) {e.printstacktrace (); } / * * 4. Iterieren Sie die Liste. Jedes itererieren ein FileItem -Objekt, rufen Sie seine iSFormfield -Methode auf, um festzustellen, ob es sich um ein Datei -Upload handelt.* TRUE. Es ist ein normales Formularfeld, dann rufen Sie den GetfieldName und GetString -Methoden auf, um den Feldnamen und den Feldwert zu erhalten. von diesem Objekt sind: * boolean isFormfield (); Ermittelt, ob FileItem ein Datei -Upload -Objekt oder ein normales Formularobjekt ist. HINWEIS: Einige Browser tragen Clientpfade und müssen sich selbst subtrahieren * call getInputStream () -Methode, um den Dateneingangsstrom zu erhalten, um die Upload -Daten zu lesen * delete (); bedeutet, dass nach dem Schließen des FileItem -Eingabestreams temporäre Dateien gelöscht werden. */for (FileItem FileItem: ParSerequest) {if (FileItem.isformfield ()) {// repräsentiert das normale Feld if ("username" .equals (teateItem.getfieldname ())) {String username = fileItem.getString (); writer.write ("Dein Benutzername:"+Benutzername+"<br>"); } if ("userpass" .equals (FileItem.getFieldName ())) {String userpass = fileItem.getString (); writer.write ("Ihr Passwort:"+Benutzerpass+"<br>"); }} else {// bedeutet eine hochgeladene Datei // Die von verschiedenen Browsern hochgeladenen Dateien haben möglicherweise einen Pfadnamen, und Sie müssen String clientname = FileItem.getName () ausschneiden; String Dateiname = ""; if (clientname.contains ("//")) {// if "/" bedeutet einen Namen mit einem Pfad, der letzte Dateiname ist abgefangene Dateiname = clientname.substring (ClientName.lastIndexof ("//")). Substring (1); } else {Dateiname = clientName; · / * * Entwerfen Sie einen Algorithmus zur Verzeichnisgenerierung. Wenn die Gesamtzahl der vom Benutzer hochgeladenen Dateien mit Millionen von Größenordnungen oder mehr Bestellungen aufweist, führt das Einlegen in das gleiche Verzeichnis zu sehr langsam. * Daher ist es sehr notwendig, eine Verzeichnisstruktur zu entwerfen, um Dateien auf verstreute Weise zu speichern und den UUID-Hash-Algorithmus angemessen in einen kleineren Bereich umzuwandeln, * konvertieren den Hashcode des UUID in ein 8-Bit-Oktal-String. ist eine sehr effiziente Verzeichnisstruktur sowohl für den Server als auch für das Betriebssystem*/ int hashuuid = randomuuid.hashCode (); String hexuuid = Integer.tohexString (Hashuuid); //System.out.println(hexuUID); // Erhalten Sie den absoluten Pfad, in den der Ordner die hochgeladene Datei in String filepath = request.getSession () speichern kann. GetServletContext (). GetRealPath ("Upload"); für (char c: hexuuid.toarArray ()) {filepath = filepath+"/"+c; } // Wenn das Verzeichnis nicht vorhanden ist, generieren Sie eine Verzeichnisdatei der achten Ebene filepathfile = new Datei (filepath); if (! filepathfile.exists ()) {filepathFile.mkdirs (); } // Lesen Sie die Datei aus dem Anforderungseingangsstrom und schreiben Sie in den Server InputStream InputStream2 = FileItem.getInputStream (); // Erstellen Sie eine Datei in der Server -Seitendatei = neue Datei (FilePath+"/"+Dateiname); BufferedOutputStream bos = new bufferedOutputStream (neuer FileOutputStream (Datei)); byte [] buffer = new byte [10*1024]; int len = 0; while ((len = inputStream2.Read (Puffer, 0, 10*1024)! =-1) {Bos.Write (Buffer, 0, Len); } writer.write ("Sie haben die Datei hochgeladen"+ClientName+"erfolgreich <br>"); // die Ressourcen bos.close () schließen; InputStream2.CLOSE (); }} // Beachten Sie, dass die hochgeladene Datei von Eclipse im Auslaufverzeichnis des Projekts gespeichert ist, nicht im Projektverzeichnis im Arbeitsbereich.2. Probleme, die besondere Aufmerksamkeit auf Datei -Upload benötigen: (Diese Probleme sind alle mit einfachen Lösungen im obigen Code versehen.)
1. Wo kann Dateien gespeichert werden
Um die Sicherheit des Servers zu gewährleisten, sollte die hochgeladene Datei im Web-INF-Verzeichnis der Anwendung oder in einem vom Webserver nicht verwalteten Verzeichnis gespeichert werden. Wenn der Benutzer eine Datei mit ausführbarem Code wie eine JSP -Datei hochladen und nach dem Spleißzugriffspfad zugreift, kann er auf der Serverseite alles tun.
2. Um zu verhindern, dass mehrere Benutzer Dateien mit demselben Dateinamen hochladen, was zu einer Dateiüberschreibung führt, sollte der Datei -Uploader sicherstellen, dass die hochgeladene Datei einen eindeutigen Dateinamen enthält .
Benennen Sie mit UUID + Benutzer -Upload -Dateinamen um
Über uUid:
UUID (allgemein eindeutiger Bezeichner) Global eindeutiger Bezeichner bezieht sich auf die Anzahl, die auf einer Maschine erzeugt wird, die sicherstellt, dass sie gleichzeitig und Raum für alle Maschinen einzigartig ist. Gemäß den von der Open Software Foundation (OSF), der Ethernet -Kartenadresse, der Nanosekundenzeit, dem Chip -ID und vielen möglichen Zahlen festgelegten Standards. Es besteht aus der Kombination der folgenden Teile: dem aktuellen Datum und der aktuellen Uhrzeit (der erste Teil der UUID hängt mit der Zeit zusammen. Wenn Sie ein paar Sekunden nach dem Generieren eines UUID ein weiteres Uuid generieren, ist der erste Teil unterschiedlich, der Rest ist gleich) ist, dass die erzeugte Ergebniszeichenfolge relativ lang sein wird.
Es ist eine 128-Bit-lange Zahl, die im Allgemeinen in Hexadezimal ausgedrückt wird. Die Kernidee des Algorithmus besteht darin, in Kombination mit der Netzwerkkarte der Maschine, der lokalen Zeit und einer Sofortnummer einen GUID zu generieren. Wenn eine Maschine 100.000 Guids pro Sekunde erzeugt, kann sie (im Sinne der Wahrscheinlichkeit) garantiert werden, dass 3240 Jahre nicht wiederholt werden.
Ausgehend von JDK1.5 ist die Erzeugung von UUIDs zu einer einfachen Sache geworden und dachte, dass JDK UUIDs implementiert hat:
Java.util.uuid, rufen Sie es einfach direkt an.
UUid uUid = uUid.randomuuid ();
String S = Uuid.randomuuid (). ToString (); // Die primäre Schlüssel -ID zum Generieren der Datenbank ist sehr gut. .
UUID besteht aus einer sechzehnstelligen Zahl, die in Form von ausgedrückt wird
550E8400-E29B-11D4-A716-446655440000
3. Um zu viele Dateien in einem einzelnen Verzeichnis zu verhindern und die Les- und Schreibgeschwindigkeit der Datei zu beeinflussen, sollte das Programm, das das Hochladen von Dateien verarbeitet, den entsprechenden Algorithmus zur Erzeugung von Verzeichnisstruktur basierend auf dem Gesamtvolumen von Uploads auswählen und die hochgeladenen Dateien auf zerstreutende Weise speichern. Verwenden Sie beispielsweise die HashCode-Methode, um ein Multi-Level-Verzeichnis zu erstellen.
4. Wenn verschiedene Benutzer dieselbe Datei hochladen, müssen viele Kopien derselben Datei auf der Serverseite nicht gespeichert werden. Dies ist eine Verschwendung von Ressourcen. Ein Algorithmus sollte entwickelt werden, um das Problem doppelter Dateien zu lösen.
5. Das Prinzip der JSP-Technologie implementiert automatisch Multi-Threading. Daher müssen Entwickler keine Multi-Thread-Operationen von Hochladen von Dateien in Betracht ziehen
3. Datei -Download
<% ArrayList <string> Dateinamen = new ArrayList <string> (); Filenames.add ("Datei/aa.txt"); fileNames.add ("Datei/bb.jpg"); for(String fileName : fileNames) { %> <form action="DownloadServlet" method="get"> <input type="hidden" name="fileName" value="<%=fileName %>" /> <input type="submit" value="Download:<%=fileName %>" /> </form> <% } %> request.setCharacterEncoding("utf-8"); String Dateiname = Request.getParameter ("Dateiname"); String urlname = urlencoder.encode (Dateiname, "utf-8"); // Verhindern Sie die chinesische machtarte Reaktion. FileInputStream fis = new FileInputStream (neue Datei (request.getSession (). GetServletContext (). GetRealPath (Dateiname))); BufferedInputStream Bis = neuer BufferedInputStream (FIS); ServletoutputStream sos = response.getOutputStream (); byte [] buffer = neues byte [1024]; int len = 0; while ((len = Bis.Read (Puffer, 0, 1024))! =-1) {sos.write (buffer, 0, len); } Bis.close (); fis.close ();4. Verwenden Sie die SmartUpload -Komponente in SSH, um das Datei -Upload zu vereinfachen und herunterzuladen
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.