Ich sehe oft Leute, die mich in Diskussionsforen fragen, was ich tun soll, wenn die in JSP angezeigten chinesischen Schriftzeichen verstümmelt sind, warum die chinesischen Eingaben des Benutzers, die ich über die Anfrage erhalte, verstümmelt sind, warum die chinesischen Schriftzeichen, die ich in die Datenbank schreibe, verstümmelt sind und anderes Fragen zur Verstümmelung chinesischer Schriftzeichen.
Tatsächlich ist dieses Problem sehr einfach. Unabhängig davon, ob es sich um chinesische Zeichen, Japanisch oder eine andere Doppelbyte-Sprache handelt, werden wir es als UTF-8 behandeln.
(1) Der Doppelbyte-Text in der Anfrage ist gut. Wir werden in der gesamten Anwendung UTF-8 verwenden. Der Grund, warum wir UTF-8 wählen, liegt nicht nur in den oben genannten Gründen UTF-8. 8 oder höher, daher sollte es richtig sein, UTF-8^_^ zu wählen
Wir speichern unsere .java- und .jsp-Dateien zunächst in UTF-8-Kodierung. Es spielt keine Rolle, ob die vorherigen Dateien nicht in UTF-8 gespeichert wurden, es wird jedoch empfohlen, alle zukünftigen Dateien in UTF-8 zu speichern.
Und schreiben Sie in .jsp: < %@page contentType="text/html; charset=UTF-8"%> statt < %@page contentType="text/html; charset=UTF-8"%>
Fügen Sie dann den folgenden Absatz zu web.xml hinzu:
<Web-App>
...
<Filter>
<filter-name>Zeichenkodierung festlegen</filter-name>
<filter-class>com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>Kodierung</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<Filterzuordnung>
<filter-name>Zeichenkodierung festlegen</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
</web-app>
Der Code von com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter lautet wie folgt:
package com.redv.projects.eduadmin.util.filters;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
öffentliche Klasse SetCharacterEncodingFilter
implementiert Filter {
protected String binding = null;
protected FilterConfig filterConfig = null;
protected boolean
destroy() {
this.encoding = null;
this.filterConfig = null;
}
public void doFilter(ServletRequest-Anfrage, ServletResponse-Antwort,
FilterChain-Kette) throws IOException, ServletException {
// Wählen Sie bedingt die zu verwendende Zeichenkodierung aus und legen Sie sie fest
if (ignore || (request.getCharacterEncoding() == null)) {
String-Kodierung = selectEncoding(request);
if (Kodierung != null) {
request.setCharacterEncoding(encoding); //Das funktioniert, haha, es: Überschreibt den Namen der Zeichenkodierung, die im Hauptteil dieser Anfrage verwendet wird. Diese Methode muss vor dem Lesen von Anforderungsparametern oder dem Lesen von Eingaben mit getReader( aufgerufen werden. ).
}
}
// Kontrolle an den nächsten Filter übergeben
chain.doFilter(request, Response);
}
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("encoding");
String-Wert = filterConfig.getInitParameter("ignore");
if (Wert == null) {
this.ignore = true;
}
else if (value.equalsIgnoreCase("true")) {
this.ignore = true;
}
else if (value.equalsIgnoreCase("yes")) {
this.ignore = true;
}
anders {
this.ignore = false;
}
}
protected String selectEncoding(ServletRequest request) {
return (this.encoding);
Auf
dieseWeise
wird unsere Anforderungsanforderung in UTT-8 codiert und wir können sie im JSP-Programm verwenden: request.getParameter("myKey" ) Sie können die UTF-8-codierte Zeichenfolge direkt abrufen, anstatt wie folgt: new String(request.getParameter("myKey").getBytes("ISO-8859-1"), "GBK"), um diese verstümmelten Zeichen zu lösen. http://www.devdao.com/
(2) Von der Datenbank verarbeiteter Doppelbyte-Text http://www.upas.org/java/DatabaseEncodingProblemSolution/
Ein weiteres Problem ist das Schreiben in die Datenbank. Wir wissen, dass wir bei Verwendung von MySQL diese URL verwenden können, um das Problem der chinesischen Zeichenkodierung zu lösen: jdbc:mysql://localhost:3306/upas?useUnicode=true&characterEncoding=gb2312,
Was sollen wir also mit den Dingen tun, die wir nicht wie MySQL lösen können? Sollten wir jedes Mal so schreiben:
import java.sql.*;
Class.forName("org.gjt.mm.mysql.Driver");
Verbindung con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
versuchen {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
pstmt = con.prepareStatement("SELECT f3, f4 FROM tbl1 WHERE f1 = ? AND f2 = ?");
pstmt.setString(1, new String(f1.getBytes("GBK"), "ISO-8859-1");
pstmt.setString(2, new String(f2.getBytes("GBK"), "ISO-8859-1");
rs = pstmt.executeQuery();
Zeichenfolge f3, f4;
while(rs.next()) {
f3 = new String(rs.getString(1).getBytes("ISO-8859-1"), "GBK");
f4 = new String(rs.getString(2).getBytes("ISO-8859-1"), "GBK");
}
}
Endlich {
//Ressourcen schließen
...
}
Tatsächlich können wir es so schreiben:
java.sql.* importieren;
import com.redv.sql.encoding.*;
Class.forName("org.gjt.mm.mysql.Driver");
Verbindung con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
versuchen {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
//Übernehmen Sie die Datenbankverbindungsinstanz
boolesche Kodierung = true;
EncodingConnection bindingConnection = new EncodingConnection(con, binding, "ISO-8859-1", "GBK");
//Holen Sie sich die Datenbankverbindungsinstanz nach der Übernahme direkt. Dies ist bereits eine von EncodingConnection neu gepackte Instanz.
con = programmingConnection.getConnection();
pstmt = con.prepareStatement("SELECT f3, f4 FROM tbl1 WHERE f1 = ? AND f2 = ?");
pstmt.setString(1, f1);
pstmt.setString(2, f2);
rs = pstmt.executeQuery();
Zeichenfolge f3, f4;
while(rs.next()) {
f3 = rs.getString(1);
f4 = rs.getString(2);
}
}
Endlich {
//Ressourcen schließen
...
}
Mal sehen, wie wäre es damit? Wir müssen es nur geringfügig ändern, wo wir die Datenbankverbindung erhalten. Wir können es sogar als Parameter in den Eigenschaften speichern und den booleschen Wert der Codierung ändern, um festzulegen, ob die automatische Codierungskonvertierung verwendet werden soll. Oft können wir eine Datenbankklasse verwenden, um getConnection zu kapseln, das die Datenbankverbindung erhält, sodass wir die Datenbankverbindung von javax.sql.DataSource erhalten können. Zu diesem Zeitpunkt müssen wir nur unsere Datenbankklasse ändern, anstatt nach allen Stellen zu suchen, an denen rs.setString() und rs.getString() verwendet werden, um unseren Kodierungskonvertierungscode hinzuzufügen. Selbst wenn wir die Anweisung con.createStatment() verwenden, gibt es kein Problem, selbst wenn unsere SQL-Anweisung chinesische Zeichen oder andere Doppelbyte-Zeichen enthält:
SELECT name, gender FROM student table WHERE class LIKE '%computer%'