2016-08-01 50 views
0

Ich entwickle eine Webanwendung mit Java und Tomcat 8. Diese Anwendung hat eine Seite zum Hochladen einer Datei mit dem Inhalt, der auf einer anderen Seite angezeigt wird. Schlicht einfach.Java für Web - Multipart/Formulardatendatei mit falscher Codierung

Diese Dateien enthalten jedoch möglicherweise nicht so häufige Zeichen als Teil ihres Texts. Im Moment arbeite ich mit einer Datei, die zum Beispiel vietnamesischen Text enthält.

Die Datei ist in UTF-8 kodiert und kann in jedem Texteditor geöffnet werden. Allerdings konnte ich keine Möglichkeit finden, es hochzuladen und den Inhalt in der korrekten Kodierung zu behalten, trotz vielem Suchen und vielen verschiedenen Dingen.

Meine Seite, die das Hochladen von Dateien enthält die folgende Form:

<form method="POST" action="upload" enctype="multipart/form-data" accept-charset="UTF-8" > 
           File: <input type="file" name="file" id="file" multiple/><br/> 
           Param1: <input type="text" name="param1"/> <br/> 
           Param2: <input type="text" name="param2"/> <br/> 
           <input type="submit" value="Upload" name="upload" id="upload" /> 
          </form> 

Es enthält auch:

<%@page contentType="text/html" pageEncoding="UTF-8"%> 
... 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> 

Mein Servlet sieht wie folgt aus:

protected void processRequest(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     try { 
      response.setContentType("text/html;charset=UTF-8"); 
      request.setCharacterEncoding("UTF-8"); 

      String param1 = request.getParameter("param1"); 

      String param2 = request.getParameter("param2"); 

      Collection<Part> parts = request.getParts(); 

      Iterator<Part> iterator = parts.iterator(); 
      while (iterator.hasNext()) { 
       Part filePart = iterator.next(); 
       InputStream filecontent = null; 

       filecontent = filePart.getInputStream(); 

       String content = convertStreamToString(filecontent, "UTF-8"); 

       //Save the content and the parameters in the database 

       if (filecontent != null) { 
        filecontent.close(); 
       } 
      } 

     } catch (ParseException ex) { 
     } 
    } 

static String convertStreamToString(java.io.InputStream is, String encoding) { 
     java.util.Scanner s = new java.util.Scanner(is, encoding).useDelimiter("\\A"); 
     return s.hasNext() ? s.next() : ""; 
    } 

Trotz all meiner Bemühungen , Ich war nie in der Lage, diese "inhaltliche" Zeichenfolge mit den richtigen Zeichen zu erhalten. Ich bekomme entweder etwas wie "K? N" oder "Kạn" (das scheint die ISO-8859-1-Interpretation dafür zu sein), wenn das richtige "Kạn" sein sollte.

Um das Problem hinzuzufügen, wenn ich vietnamesische Zeichen in die anderen Formularparameter (param1 oder param2) schreiben, die auch möglich sein müssen, kann ich sie nur richtig lesen, wenn ich sowohl den accept-charset als auch den Servlet Scanner Codierung nach ISO-8859-1, die ich definitiv nicht verstehe. In diesem Fall, wenn ich den empfangenen Parameter drucke, bekomme ich etwas wie "K & # 7 8 4 1; n" (ohne die Leerzeichen), das eine Darstellung für das richtige Zeichen enthält. So scheint es möglich zu sein, die vietnamesischen Zeichen aus dem Formular mit ISO-8859-1 zu lesen, solange das Formular selbst diesen Zeichensatz verwendet. Es funktioniert jedoch nie mit dem Inhalt der hochgeladenen Dateien. Ich habe sogar versucht, die Datei in ISO-8859-1 zu kodieren, um den Zeichensatz für alles zu verwenden, aber es funktioniert überhaupt nicht.

Ich bin mir sicher, dass diese Art von Situation nicht so selten ist, also würde ich gerne etwas Hilfe von den Leuten verlangen, die vorher dort gewesen sein könnten. Vermutlich vermisse ich etwas, daher wird jede Hilfe geschätzt.

Vielen Dank im Voraus.


Edit 1: Obwohl diese Frage noch eine Antwort zu erhalten, werde ich meine Erkenntnisse halten Entsendung, falls jemand interessiert ist, oder es folgt.

Nachdem ich viele verschiedene Dinge ausprobiert habe, habe ich die Ursachen des Problems eingegrenzt. Ich habe eine Klasse erstellt, die eine Datei aus einem bestimmten Ordner auf der Festplatte liest und ihren Inhalt ausgibt. Der Code lautet:

public static void openFile() { 
    System.out.println(String.format("file.encoding: %s", System.getProperty("file.encoding"))); 
    System.out.println(String.format("defaultCharset: %s", Charset.defaultCharset().name())); 

    File file = new File(myFilePath); 
    byte[] buffer = new byte[(int) file.length()]; 
    BufferedInputStream f = null; 
    String content = null; 
    try { 
     f = new BufferedInputStream(new FileInputStream(file)); 
    } catch (FileNotFoundException ex) { 
    } 

    try { 
     f.read(buffer); 
     content = new String(buffer, "UTF-8"); 
     System.out.println("UTF-8 File: " + content); 
     f.close(); 
    } catch (IOException ex) { 
    } 
} 

Dann habe ich eine Hauptfunktion zu dieser Klasse hinzugefügt, so dass es ausführbar. Als ich es Standalone laufen lasse, erhalte ich die folgende Ausgabe:

file.encoding: UTF-8
DefaultCharset: UTF-8
UTF-8-Datei: {“... KAN ...„}

jedoch das Projekt als Webapp wenn ausführen, wie es sein soll, und rufen Sie die gleiche Funktion aus dieser Klasse, die ich erhalten:

file.encoding: Cp1252
DefaultCharset: windows-1252
UTF-8-Datei: { "? ... K n ..."}

natürlich ist dies eindeutig zeigte, dass die Standard-Kodierung durch die Webapp verwendet, um die Datei zu lesen war nicht UTF-8, also habe ich etwas recherchiert Gegenstand und die klassische Antwort der Schaffung eines setenv.bat für Tomcat gefunden und nachdem er sie ausführen:

set "JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8" 

Das Ergebnis ist jedoch immer noch nicht richtig:

file.encoding: UTF-8
DefaultCharset: UTF-8
UTF-8-Datei { "... Kạn ..."}

ich jetzt, dass die Standard-Kodierung wurde 8 UTF-sehen kann. Der aus der Datei gelesene Inhalt ist jedoch immer noch falsch. Der oben gezeigte Inhalt ist derselbe, den ich erhalten würde, wenn ich die Datei in Microsoft Word öffne, aber wählte, um ihn mit ISO-Latin-1 anstelle von UTF-8 zu lesen. Aus irgendeinem Grund funktioniert das Lesen der Datei immer noch mit ISO-Latin-1, obwohl alles auf die Verwendung von UTF-8 hinweist.

Noch einmal, wenn jemand Vorschläge oder Anweisungen dafür haben könnte, wird es sehr geschätzt.

Antwort

0

Ich bin nicht in der Lage, die Frage zu schließen, also lassen Sie mich mit der Antwort beitragen, die ich fand.

Das Problem ist, dass die Untersuchung dieser Art von Problem sehr schwierig ist, da es viele Punkte im Code gibt, wo die Kodierung geändert werden könnte (die Seite, die Formularkodierung, die Anfragekodierung, Datei lesen, Datei schreiben, Konsole Ausgabe, Datenbank schreiben, Datenbank lesen ...).

In meinem Fall, nachdem ich alles getan habe, was ich in der Frage gepostet habe, habe ich eine Menge Zeit verloren, ein Problem zu lösen, das nicht mehr existierte, nur weil die Konsolenausgabe in meiner IDE (NetBeans, dafür Projekt) verwendete nicht die gewünschte Zeichencodierung. Also habe ich bis zu einem gewissen Punkt alles richtig gemacht, aber wenn ich etwas drucken wollte, würde ich es falsch verstehen. Nachdem ich angefangen habe, meine Logs in Dateien anstatt in die Konsole zu schreiben und damit die Schreibcodierung zu steuern, begann ich, das Problem klar zu verstehen.

Was in meiner Lösung fehlte, nachdem alles, was ich bereits in meiner Frage beschrieben hatte (vor der Bearbeitung), war, die Kodierung für die Datenbankverbindung zu konfigurieren. Zu meiner Überraschung, obwohl meine Datenbank und alle meine Tabellen UTF-8 verwendeten, war die Kommunikation zwischen der Anwendung und MySQL immer noch in ISO-Latin. Das letzte, was fehlte, war das Hinzufügen "useUnicode = true & characteren = utf-8" auf die Verbindung, so wie diese:

con = DriverManager.getConnection("jdbc:mysql:///dbname?useUnicode=true&characterEncoding=utf-8", "user", "pass"); 

Dank dieser Antwort, unter vielen anderen: https://stackoverflow.com/a/3275661/843668