Je vois souvent des gens me demander dans les forums de discussion quoi faire si les caractères chinois affichés dans JSP sont tronqués, pourquoi la saisie chinoise de l'utilisateur que je reçois via la demande est tronquée, pourquoi les caractères chinois que j'écris dans la base de données sont tronqués, et d'autres. questions sur les caractères chinois tronqués.
En fait, ce problème est très simple. Qu'il s'agisse de caractères chinois, japonais ou d'une autre langue à deux octets, nous le traiterons comme UTF-8.
(1) Le texte à deux octets dans la requête est bon. Nous allons maintenant utiliser le codage UTF-8 dans l'ensemble de l'application. La raison pour laquelle UTF-8 est choisi n'est pas seulement pour les raisons ci-dessus. Nous savons que Java est basé sur. UTF-8.8 ou supérieur, nous devrions donc avoir raison de choisir UTF-8^_^
Nous enregistrons d'abord nos fichiers .java et .jsp en codage UTF-8. Peu importe si les fichiers précédents n'ont pas été enregistrés en UTF-8, mais il est recommandé que tous les futurs fichiers soient enregistrés en UTF-8.
Et écrivez en .jsp : < %@page contentType="text/html; charset=UTF-8"%> au lieu de < %@page contentType="text/html; charset=UTF-8"%>
Ajoutez ensuite le paragraphe suivant à web.xml :
<application Web>
...
<filtre>
<filter-name>Définir le codage des caractères</filter-name>
<filter-class>com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter</filter-class>
<param-init>
<param-name>encodage</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filtre>
<cartographie de filtre>
<filter-name>Définir le codage des caractères</filter-name>
<modèle-url>/*</modèle-url>
</filter-mapping>
...
</web-app>
Le code de com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter est le suivant :
package com.redv.projects.eduadmin.util.filters
;
importer javax.servlet.Filter ;
importer javax.servlet.FilterChain ;
importer javax.servlet.FilterConfig ;
importer javax.servlet.ServletException ;
importer javax.servlet.ServletRequest ;
importer javax.servlet.ServletResponse ;
importer javax.servlet.UnavailableException ;
importer javax.servlet.http.HttpServletRequest ;
importer javax.servlet.http.HttpServletResponse ;
classe publique SetCharacterEncodingFilter
implémente le filtre {
protected String encoding = null;
protected FilterConfig filterConfig = null;
protected boolean ignore = true;
public void destroy() {
this.encoding = null;
this.filterConfig = null;
}
public void doFilter (demande ServletRequest, réponse ServletResponse,
FilterChain chain) lance IOException, ServletException {
// Sélectionne et définit conditionnellement l'encodage de caractères à utiliser
if (ignorer || (request.getCharacterEncoding() == null)) {
Encodage de chaîne = selectEncoding(request);
if (encodage != null) {
request.setCharacterEncoding(encoding); //Voici ce qui fonctionne, haha, ça : remplace le nom du codage de caractères utilisé dans le corps de cette requête. Cette méthode doit être appelée avant de lire les paramètres de la requête ou de lire l'entrée à l'aide de getReader(. ).
}
}
// Passer le contrôle au filtre suivant
chain.doFilter(request, réponse);
}
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("encoding");
Valeur de chaîne = filterConfig.getInitParameter("ignore");
si (valeur == null) {
this.ignore = vrai;
}
sinon if (value.equalsIgnoreCase("true")) {
this.ignore = vrai;
}
sinon if (value.equalsIgnoreCase("yes")) {
this.ignore = vrai;
}
autre {
this.ignore = false;
}
}
protected String selectEncoding(ServletRequest request) {
return (this.encoding);
}
}
De cette façon, notre requête est codée en UTT-8, et nous pouvons l'utiliser dans le programme JSP : request.getParameter("myKey" ) Vous pouvez obtenir directement la chaîne codée en UTF-8, au lieu de ceci : new String(request.getParameter("myKey").getBytes("ISO-8859-1"), "GBK") pour résoudre ces caractères tronqués. http://www.devdao.com/
(2) Texte à deux octets traité par la base de données http://www.upas.org/java/DatabaseEncodingProblemSolution/
Un autre problème est l'écriture dans la base de données. Nous savons que lors de l'utilisation de MySQL, nous pouvons utiliser cette URL pour résoudre le problème d'encodage des caractères chinois : jdbc:mysql://localhost:3306/upas?useUnicode=true&characterEncoding=gb2312,
Alors, que devrions-nous faire à propos de ces problèmes que nous ne pouvons pas résoudre comme MySQL ? Faut-il écrire ainsi à chaque fois :
importer java.sql.*;
Class.forName("org.gjt.mm.mysql.Driver");
Connexion con = null ;
PreparedStatement pstmt = null ;
ResultSet rs = nul ;
essayer {
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();
Chaîne 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");
}
}
enfin {
//ferme les ressources
...
}
En fait, on peut l'écrire ainsi :
importer java.sql.* ;
importer com.redv.sql.encoding.*;
Class.forName("org.gjt.mm.mysql.Driver");
Connexion con = null ;
PreparedStatement pstmt = null ;
ResultSet rs = nul ;
essayer {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
//Reprendre l'instance de connexion à la base de données
codage booléen = vrai ;
EncodingConnection codingConnection = new EncodingConnection(con, codage, "ISO-8859-1", "GBK");
//Obtenez l'instance de connexion à la base de données après avoir pris le relais. Utilisez con directement à l'avenir, qui est déjà une instance reconditionnée par EncodingConnection.
con = codingConnection.getConnection();
pstmt = con.prepareStatement("SELECT f3, f4 FROM tbl1 WHERE f1 = ? AND f2 = ?");
pstmt.setString(1, f1);
pstmt.setString(2, f2);
rs = pstmt.executeQuery();
Chaîne f3, f4 ;
while(rs.next()) {
f3 = rs.getString(1);
f4 = rs.getString(2);
}
}
enfin {
//ferme les ressources
...
}
Voyons, qu'en est-il, il suffit de le modifier légèrement à l'endroit où nous obtenons la connexion à la base de données. Nous pouvons même l'enregistrer en tant que paramètre dans les propriétés et modifier la valeur booléenne du codage pour définir s'il faut utiliser la conversion automatique du codage. Nous pouvons souvent utiliser une classe Database pour encapsuler le getConnection qui obtient la connexion à la base de données, afin que nous puissions obtenir la connexion à la base de données à partir de javax.sql.DataSource. Pour le moment, il nous suffit de modifier notre classe Database, au lieu de rechercher tous les endroits où rs.setString() et rs.getString() sont utilisés pour ajouter notre code de conversion d'encodage. Même lorsque nous utilisons l'instruction con.createStatment(), il n'y a aucun problème même si notre instruction SQL contient des caractères chinois ou d'autres caractères codés sur deux octets :
SELECT nom, sexe FROM table d'étudiant WHERE classe LIKE '%computer%'