Was ist Datei -Upload?
Das Datei -Upload besteht darin, Benutzerinformationen zu speichern.
Warum muss ich eine Datei hochladen?
Wenn ein Benutzer registriert, muss der Benutzer möglicherweise ein Foto einreichen. Dann sollte dieses Foto gespeichert werden.
Upload -Komponenten (Tools) hochladen. Warum müssen wir das Upload -Tool verwenden?
Warum müssen wir Komponenten hochladen? Wenn wir die Daten des Kunden erhalten möchten, erhalten wir sie normalerweise über die GetParameter () -Methode.
Die hochgeladenen Dateidaten werden durch MIME -Protokoll geteilt und das Formular in binär eingekapselt. Mit anderen Worten: GetParameter () kann die Daten der hochgeladenen Datei nicht abrufen.
Schauen wir uns zunächst an, wie HTTP -Datei -Uploads Daten mitbringen
JSP-Seite, Formular muss engTepe angeben: Mehrart/Formdaten-Daten
<form action = "$ {pageContext.request.contextPath}/Servlet/UploadServlet1" Enctype = "MultiPart/Form-Data" methode = "post"> Upload-Benutzer hochladen: <Eingabe type type = "text" name = "username"> <br/> upload-Datei 1: <Eingabe type type = "Datei" name "Datei" Datei "Datei" Datei ". name = "file2"> <br/> <Eingabe type = "surenden" value = "suruging"> </form>HTTP -Paket greifen
Versuchen Sie, Daten mit GetParameter () auf dem Servlet zu erhalten
String ss = request.getParameter ("Benutzername"); System.out.println (SS);Sie können die Daten nicht erhalten, indem Sie GetParameter direkt verwenden.
Also, was sollen wir tun? ? ? ? Das Anforderungsobjekt stellt den ServletInputStream -Stream zur Verfügung, um die Daten an uns zu lesen
Wir versuchen, die Datei zu lesen
ServletInputStream InputStream = Request.GetInputStream (); byte [] bytes = neues byte [1024]; int len = 0; while ((len = inputStream.read (bytes))> 0) {System.out.println (neue String (Bytes, 0, len)); }Fügen Sie der JSP -Seite eine zusätzliche Eingabesteuerung hinzu
<Eingabe type = "text" name = "password">
Die Textdatei, die ich hochgeladen habe, ist 111111 und der Leseeffekt lautet wie folgt:
Jetzt können wir die Daten zum Hochladen von Dateien lesen, aber nun lautet die Frage: Wie trennen Sie die hochgeladenen Daten der Datei von den an den Server gesendeten Daten? ? ? Wir haben oben auf dem Bild gesehen, sie werden zusammen gemischt.
Es ist schwierig, nach unserer üblichen Praxis zu trennen, daher müssen wir Komponenten hochladen
Es gibt zwei Arten von FileUploads hochladen Komponenten
Um die Datei -Pload -Komponente zu verwenden, müssen Sie zwei JAR -Pakete importieren
Commons-io Commons-fileUpload-Entwicklungsschritte Erstellen Sie ein Parser Factory-Objekt [diskFileItemfactory] Erstellen Sie einen Parser über die Parser Factory [ServletFileUpload]. Rufen Sie die Parser-Methode auf, um das Anforderungsobjekt zu präsentieren, und erwerben Sie alle hochgeladenen Inhalte [Liste], um die Liste zu ermitteln, ob jedes Objekt eine hochgeladene Datei hochgeladen ist. Wenn es sich um ein normales Formularfeld handelt, erhalten Sie den Feldnamen und den Feldwert. Wenn es sich um eine hochgeladene Datei handelt, rufen Sie die InputSteam -Methode auf, um den Eingabestream abzurufen, und lesen Sie die hochgeladenen Daten schnell.
Versuchen Sie {// 1. Holen Sie sich die Parser Factory diskFileItemFactory Factory = new diskFileItemfactory (); // 2. Holen Sie sich den Parser ServletFileUpload Upload = new ServletFileUpload (Fabrik); // 3. Bestimmen Sie die Art des Hochladensformulars if (! Upload.ismultiPartContent (Anfrage)) {// Hochladen Das Formular ist ein normales Formular, und erhalten Sie die Daten auf die traditionelle Weise zurück. } // Um das Formular hochzuladen, rufen Sie den Parser an, um die hochgeladene Datenliste <FileItem> list = Upload.ParSequest (Anfrage) analysieren zu lassen. // FileItem // Die Liste übertragen und das DateiItem -Objekt abrufen, mit dem das erste Eingangselementdata -DateiItem -Objekt für (FileItem Element: List) {it item.isformfield ()) {// Was Sie erhalten, ist der normale Eingangselement -String -Name = item.getfieldname (); // Erhalten Sie den Namen des Eingabelement -String -Zeichens = item.getString (); System.out.println (Name + "=" + Wert); } else {// abrufen Sie das Upelad -Eingangselement String mateiname = item.getName (); // Erhalten Sie den Upload -Dateiname C:/Dokumente und Einstellungen/ThinkPad/Desktop/1.Txt Dateiname = Dateiname.substring (Dateiname.lastIndexof ("//")+1); InputStream in = item.getInputStream (); // Daten hochladen Daten int len = 0; Byte Buffer [] = neues Byte [1024]; String SavePath = this.getServletContext (). GetRealPath ("/upload"); FileOutputStream out = new FileOutputStream (speichernPath + "//" + Dateiname); // Datei in das Upload -Verzeichnis schreiben, während ((len = in.read (puffer))> 0) {out.write (Buffer, 0, len); } in.close (); out.close (); }}} catch (exception e) {e.printstacktrace (); }Testen, dass sowohl gewöhnliche Felder als auch hochgeladene Dateien gelesen und erhalten werden können!
SmartUpload
Um die SmartUpload -Komponente zu verwenden, müssen Sie das SmartUpload.jar -Entwicklungspaket importieren
Schneller Start
// Instantierte Komponente SmartUpload SmartUpload = new SmartUpload (); // Initialisieren Sie den Upload -Betrieb smartUpload.initialize (this.getServletConfig (), Request, Antwort); Versuchen Sie {// Vorbereitung smartUpload.Upload () hochladen; // Bei gewöhnlichen Daten ist es so einfach, dass das Anforderungsobjekt die übermittelten Parameter nicht abrufen kann. Außerdem müssen Sie sich auf SmartUpload -String -Passwort = smartUpload.getRequest () verlassen. GetParameter ("Passwort"); System.out.println (Passwort); // Upload in UploadFile Ordner SmartUpload.save ("UploadFile"); } catch (smartUploadexception e) {e.printstacktrace (); }prüfen
In ähnlicher Weise können wir Dateien in den Uploadfile -Ordner hochladen. Die Menge an Code wird in der Tat stark reduziert!
Sie können auch Parameter normaler Felder erhalten
Ich habe den Dateinamen in chinesischen verstümmelten Code und chinesischem verstümmelten Code geändert, um Daten hochzuladen, und es handelte sich um verstümmelte Code:
Die vom Formular eingereichten chinesischen Daten sind ebenfalls verstümmelt.
Wie oben erwähnt, wird die Form des Hochladens der Dateidaten in Binärdaten eingekapselt. Die Verwendung der Anforderung zur Encodierung der Daten funktioniert daher nicht für die vom Formular übermittelten Daten!
FileUpload löst verstümmelte Code
Die Verwendung von FileUploads zur Lösung verstümmelter Probleme ist sehr einfach
Lösen Sie den verstümmelten chinesischen Dateinamen. Setzen Sie nach dem Erhalten des Parsers einfach die Codierung des Parsers auf UTF-8!
// Setzen Sie die Codierung von Upload FileUpload.
Lösen Sie die verstümmelten Formdaten. Verwenden Sie beim Erhalten von Formularwerten die UTF-8-Codierung, um sie zu erhalten.
String value = FileItem.getString ("utf-8");Wirkung:
SmartUpload löst verstümmelte Code
Diese Komponente ist etwas problematisch, um das Problem des verstümmelten Code zu lösen. Ich habe verschiedene Lösungen online gefunden, konnte aber kein einfaches finden ...
Wenn die Daten nicht Chinesisch umfassen, verwenden Sie die SmartUpload -Komponente und verwenden Sie die DateiEUpload -Komponente, wenn sie chinesische Daten beinhalten!
Laden Sie mehrere Dateien hoch und addieren Sie hochgeladene Steuerelemente dynamisch
Angenommen, ich habe jetzt mehrere Dateien zum Hochladen, und die Anzahl der zum Hochladen zu hochgeladenen Dateien ist ungewiss. Also, was sollen wir tun? ? ?
Es ist für uns unmöglich, viele Steuerelemente für das Hochladen von Dateien auf der Seite aufzulisten, was nicht schön ist. Wenn der Benutzer nicht so viele Steuerelemente verwenden kann, ist es ein Abfall.
Daher möchten wir dynamisch Steuerelemente zum Hochladen von Dateien hinzufügen. Wenn der Benutzer auch Dateien hochladen möchte, muss er nur dynamisch Steuerelemente generieren!
analysieren
Um Steuerelemente dynamisch auf der Seite zu generieren, ist es nichts anderes, als den JavaScript -Code zu verwenden.
Also, was machen wir? ?
Lassen Sie uns dies tun: Wenn der Benutzer eine Datei hochladen möchte, klicken Sie auf die Schaltfläche und die Schaltfläche bindet das Ereignis, um die Steuerung für das Hochladen der Datei zu generieren.
Um perfekter zu machen, wird auch bei der Erstellung eines Datei -Upload -Steuerelements eine Schaltfläche Löschung bereitgestellt, um die Steuerung zu löschen!
Wir sollten DIV verwenden, um die Steuerelemente zu laden und Schaltflächen zu löschen, die wir generieren möchten. Wenn der Benutzer zum Löschen klickt, sollte er die Schaltfläche Löschen ausblenden und die Datei -Upload -Steuerelemente zusammenladen. Es ist also am besten, verschachtelte Divs zu verwenden!
Code -Seitencode:
<table> <tr> <td>Upload user: </td> <td><input type="text" name="username"></td> </tr> <tr> <td>Add upload file</td> <td><input type="button" value="Add upload file"> </td> </tr> <tr> <td> <div> </div> </td> </td> </tr> </table>
JavaScript -Code
<script type = "text/javaScript"> Funktion addUploadFile () {// Datei -Upload -Steuereladung Var input = document.createelement ("input"); input.type = 'Datei'; input.name = 'Dateiname'; // Schaltfläche lösche var del = document.createelement ("input"); del.type = 'button'; del.value = 'delete'; // interne div var innerdiv = document.createelement ("div") generieren; // zwei Steuerelemente an Innerdiv.AppendChild (Eingabe) binden; Innerdiv.AppendChild (Del); // die externe Div -Kontrolle erhalten und die interne Div an das externe Div var outterdiv = document.getElementById ("Datei") binden; Outterdiv.AppendChild (Innerdiv); // Ereignis del.onclick = function delete () {// Aufrufen der Methode des externen Divs, um den internen Div this.parentnode.parentnode.removechild (this.parentnode) abzutöten; }} </script>Datei -Upload -Details Wenn die Größe der hochgeladenen Datei größer ist als die Größe der von uns festgelegten Datei, wird in der Datei eine temporäre Datei zum Speichern der hochgeladenen Daten beim Hochladen verwendet. Nach dem Hochladen sollten wir die temporäre Datei löschen. Der Speicherort, an dem die Upload -Datei nicht vom Webserver verwaltet werden kann, kann sie zu Sicherheitsproblemen führen. [Andere können die Upload -Datei mit Mitteln ändern], wenn der Name der Upload -Datei gleich ist. Die ursprüngliche Upload -Datei wird überschrieben. Wir möchten einen eindeutigen Dateinamen generieren. Wenn die Anzahl der Benutzer groß ist, werden viele Dateien hochgeladen. Dann sollten wir nicht alle Upload -Dateien in einem Verzeichnis speichern, was wahrscheinlich dazu führt, dass die Festplatte abstürzt. Wir müssen also die hochgeladenen Dateien in verschiedene Verzeichnisse zerstreuen. analysieren
Das Problem des Löschens temporärer Dateien ist sehr einfach. Sie müssen nur die Methode Delete () von FileItem aufrufen, nachdem alle Vorgänge abgeschlossen sind.
Um zu verhindern, dass die hochgeladene Datei vom Webserver verwaltet wird, können wir einfach den hochgeladenen Dateispeicherort im Web-INF/ Verzeichnis platzieren!
Für denselben Dateinamen können wir den vom Benutzer hochgeladenen UUID+ -Dateinamen wie unseren hochgeladenen Dateinamen verwenden. Ein solcher Dateiname ist eindeutig.
Um die hochgeladenen Dateien aufzubrechen, müssen wir den HashCode -Algorithmus verwenden, um sich zu trennen.
Die unteren vier Bits erzeugen das Verzeichnis der ersten Stufe 5-8 Bits erzeugen Verzeichniscode auf zweiter Ebene
Lassen Sie uns einen relativ vollständigen Upload -Dateicode schreiben
Verwenden Sie den Hashcode -Algorithmus, um gespeicherte Verzeichnisse aufzubrechen
private String makedirpath (String -Dateiname, String -Pfad) {// Berechnen Sie die primären und sekundären Verzeichnisse über den Dateinamen int HashCode = Dateiname.hashCode (); Int Dir1 = HashCode & 0xf; Int Dir2 = (HashCode & 0xf0) >> 4; String Dir = Pfad + "//" + Dir1 + "//" + dir2; // Wenn das Verzeichnis nicht vorhanden ist, erstellen Sie die Verzeichnisdatei = neue Datei (DIR). if (! file.exists ()) {file.mkdirs (); } // den vollständigen Pfad return Dir; }Generieren Sie eindeutige Dateinamen
private Zeichenfolge MakefileName (String -Dateiname) {// Verwenden Sie Unterstrich, um den UUID und den Dateinamen zu trennen, und der Dateiname kann später analysiert werden. return uUid.randomuuid (). toString () + "_" + Dateiname; }Hochgeladener Code
// Factory diskFileItemFactory factory = new diskFileItemfactory (); // Erstellen Sie einen Parser über das Werk servletFileUpload FileUpload = new servletFileUpload (factory); // Setzen Sie den Code von Upload FileUpload.SetheaDerenCoding ("UTF-8"); // Beurteilen Sie den Typ des Upload -Formulars if (! FileUpload.ismultiPartContent (Anfrage)) {// Laden Sie das Formular als normales Formular hoch und erhalten Sie die Daten auf die herkömmliche Art zur Rückgabe; } try {// das Anforderungsobjekt analysieren, um die Liste zu erhalten. // durchlist reisen, um festzustellen, ob der geladene Inhalt ein normales Feld oder eine Upload -Datei für (FileItem FileItem: List) ist {// Wenn es sich um ein normales Eingabemelement handelt, if (FileItem.isformfield ()) {// den Namen und den Wert des Eingabelements -String -Namens = FileItem.getfieldname () abrufen; String value = FileItem.getString ("utf-8"); System.out.println (Name + "=" + Wert); } else {// Wenn es sich um eine Upload -Datei handelt // den Upload -Namen [einschließlich Pfadname] String fileName = fileItem.getName () erhalten; // Abfangen den Dateinamen fileName = Dateiname.substring (Dateiname.lastIndexof ("//") + 1); // generieren Sie einen eindeutigen Dateinamen Dateiname = MakefileName (Dateiname); InputStream inputStream = fileItem.getInputStream (); // den Projektpfad abrufen und die hochgeladene Datei in den Projekt String path = this.getServletContext () schreiben. GetRealPath ("/webinf/uploadFile"); // den verstreuten Verzeichnispfad String realPath = makedirpath (Dateiname, Pfad) erhalten; FileOutputStream outputStream = new FileOutputStream (RealPath + "//" + Dateiname); byte [] bytes = neues byte [1024]; int len = 0; while ((len = inputStream.read (bytes))> 0) {outputStream.write (bytes, 0, len); } inputStream.close (); outputStream.close (); // die Daten der temporären FileItem.delete () löschen; }}} catch (FileUploadexception e) {e.printstacktrace (); }Effekt: Das Verzeichnis wurde erfolgreich aufgelöst und der Dateiname war eindeutig.
Listen Sie die Dateien im hochgeladenen Verzeichnis auf und geben Sie Downloads an
Bei der Erläuterung des Respose -Objekts wurde der Datei -Download erläutert. Dieses Mal schreiben wir einen kleinen Fall, um den Datei -Download zu konsolidieren.
Es gibt 3 Dateien im Upload -Verzeichnis
analysieren
Listen Sie zunächst alle Dateien im Verzeichnis auf. Da wir die Datei später entsprechend dem Dateinamen herunterladen müssen, verwenden wir eine Kartensammlung, um alle Dateien zu speichern
Der Download -Teil ist auch sehr einfach. Suchen Sie die entsprechende Datei gemäß dem Dateinamen und hochladen Dateispeicherort, lesen Sie sie und schreiben Sie sie und ändern Sie den Nachrichtenheader, um das Herunterladen zu erreichen.
Holen Sie sich den Pfad zum Laden und Hochladen von Dateien, finden Sie alle Dateien heraus, indem Sie rekursiv (urteilen, ob es sich um eine Datei handelt oder um einen rekursiven Ausgang), laden Sie sie in die Kartensammlung und geben Sie die Kartensammlung an die Rezeption an, um anzuzeigen, wenn der Benutzer klickt, um sie herunterzuladen, und erhalten Sie dann den absoluten Pfad gemäß dem ursprünglichen Namen. Wenn die Ressource vorhanden ist, darf der Benutzer den Code herunterladen und alle Dateien, die im Web-INF/ Verzeichnis in der Kartensammlung gespeichert sind, einfügen.
Protected Void Dopost (HttpServletRequest-Anforderung, httpServletResponse-Antwort) löst ServletException aus, IOException {// Erhalten Sie das Verzeichnis, in dem die hochgeladene Datei String filepath = this.getServletContext () ist ("/webinf/uploadFile"); Map map = new HashMap (); // Verwenden Sie eine Rekursion, um alle Dateien zu erhalten und sie zur Kartensammlung GetAllFiles (neue Datei (Filepath), MAP) hinzuzufügen. Request.SetatTribute ("Karte", Karte); request.getRequestDispatcher ("/listfile.jsp"). Forward (Request, Antwort); } private void getAllFiles (Datei filepath, map map) {// Wenn es sich nicht um eine Datei handelt, ist es ein Ordner if (! filepath.isfile ()) {// Auflisten Sie alle Dateien im Ordner (möglicherweise A -Datei, möglicherweise eine Ordner). Datei [] filepath.listFiles (); für (Dateidatei: Dateien) {// beurteilen Sie die erhaltene Datei (oder Ordner) und getAllFiles (Datei, Karte); }} else {// Geben Sie die Anweisung an. Es muss eine Datei sein // den Dateinamen String fileName = filepath.getName (). Substring (filepath.getName (). LastIndexof ("_") + 1); // Wir speichern den vollständigen Namen der Datei als Schlüssel und den Dateinamen als Wert in der Karte der Kartensammlung.put (filepath.getName (), Dateiname); }}Downloadbare Dateien auf der JSP -Seite anzeigen
<c:forEach items="${map}" var="me"> <c:url var="url" value="/DownFileServlet"> <c:param name="fileName" value="${me.key}"></c:param> </c:url> ${me.value}<a href="${url}" rel="external nofollow" >Download! </a> <br> </c: foreach>Implementieren Sie das heruntergeladene Servlet
Protected void dopost (httpServletRequest -Anforderung, HttpServletResponse -Antwort) löst ServletException aus, iOException {// Erhalten Sie den vollständigen Namen des Datei String Dateiname = Request.getParameter ("FileName"); // Wenn es sich um chinesische Daten handelt, ist eine Transkodierung erforderlich. Dateiname = new String (Dateiname.getBytes ("ISO8859-1"), "UTF-8"); // den Speicherort abrufen, an dem die Datei gespeichert ist String path = this.getServletContext (). GetRealPath ("/webinf/uploadFile"); // Die Datei wird über den Dateinamen per HashCode gespeichert, und die Datei wird über den Dateinamen String fileRealpath = meefilepath (Dateiname, Pfad) erhalten. System.out.println (fileRealPath); // beurteilen, ob die Datei Datei Datei = neue Datei (fileRealPath) existiert; if (! file.exists ()) {request.setAttribute ("meldung", "Die Ressource, die Sie herunterladen möchten, existiert nicht!"); Request.GetRequestDispatcher ("/message.jsp"). Weiterleiten (Anfrage, Antwort); zurückkehren ; } // existieren // die Datei lesen und die Daten in den Browser FileInputStream InputStream = New FileInputStream (FileRealPath) schreiben. byte [] bytes = neues byte [1024]; int len = 0; while ((len = inputStream.read (bytes))> 0) {response.getOutputStream (). Schreiben (Bytes, 0, len); } inputStream.close (); // Setzen Sie den Meldungsheader, um dem Browser mitzuteilen, dass es sich um den heruntergeladenen Dateistring -Namen = Dateiname.substring (Dateiname.lastIndexof ("_") + 1 handelt. response.setheader ("Inhaltsdisposition", "Anhang; Dateiname =" + urlencoder.encode (Name "utf-8"); } private String makeFilePath (String -Dateiname, String -Pfad) {int HashCode = Dateiname.hashCode (); Int Dir1 = HashCode & 0xf; Int Dir2 = (HashCode & 0xf0) >> 4; String Dir = Pfad + "//" + Dir1 + "//" + dir2 + "//" + Dateiname; Return Dir; }Wirkung
Wenn der Artikel ein Fehler gibt, korrigieren Sie mich bitte und jeder kommuniziert miteinander. Vielen Dank für Ihre Unterstützung bei Wulin.com.