A menudo veo gente preguntándome en foros de discusión qué hacer si los caracteres chinos mostrados en JSP están confusos, por qué la entrada china del usuario que recibo a través de la solicitud está confusa, por qué los caracteres chinos que escribo en la base de datos están confusos, y otras preguntas sobre caracteres chinos confusos.
De hecho, este problema es muy simple, independientemente de si se trata de caracteres chinos, japoneses o algún otro idioma de doble byte, lo trataremos como UTF-8.
(1) El texto de doble byte en la solicitud es bueno. Ahora usaremos la codificación UTF-8 en toda la aplicación. La razón por la que se elige UTF-8 no es solo por las razones anteriores. UTF-8 o superior, por lo que deberíamos hacer lo correcto al elegir UTF-8^_^.
Primero guardamos nuestros archivos .java y .jsp en codificación UTF-8. No importa si los archivos anteriores no se guardaron en UTF-8, pero se recomienda que todos los archivos futuros se guarden en UTF-8.
Y escriba en .jsp: < %@page contentType="text/html; charset=UTF-8"%> en lugar de < %@page contentType="text/html; charset=UTF-8"%>
Luego agregue el siguiente párrafo a web.xml:
<aplicación web>
...
<filtro>
<filter-name>Establecer codificación de caracteres</filter-name>
<filter-class>com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter</filter-class>
<parámetro-inicio>
<param-name>codificación</param-name>
<valor-param>UTF-8</valor-param>
</init-param>
</filtro>
<asignación de filtros>
<filter-name>Establecer codificación de caracteres</filter-name>
<patrón-url>/*</patrón-url>
</filtro-mapeo>
...
</web-app>
El código de com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter es el siguiente:
paquete com.redv.projects.eduadmin.util.filters;
import java.io.IOException;
importar javax.servlet.Filter;
importar javax.servlet.FilterChain;
importar javax.servlet.FilterConfig;
importar javax.servlet.ServletException;
importar javax.servlet.ServletRequest;
importar javax.servlet.ServletResponse;
importar javax.servlet.UnavailableException;
importar javax.servlet.http.HttpServletRequest;
importar javax.servlet.http.HttpServletResponse;
clase pública SetCharacterEncodingFilter
implementa el filtro {
codificación de cadena protegida = nulo;
FilterConfig protegido filterConfig = nulo;
booleano protegido ignorar = verdadero
destrucción pública vacía () {
this.encoding = nulo;
this.filterConfig = null;
}
public void doFilter (solicitud ServletRequest, respuesta ServletResponse,
Cadena FilterChain) lanza IOException, ServletException {
// Selecciona y establece condicionalmente la codificación de caracteres que se utilizará
if (ignorar || (request.getCharacterEncoding() == nulo)) {
Codificación de cadena = selectEncoding(solicitud);
si (codificación! = nulo) {
request.setCharacterEncoding(encoding); // Esto es lo que funciona, jaja: anula el nombre de la codificación de caracteres utilizada en el cuerpo de esta solicitud. Este método debe llamarse antes de leer los parámetros de la solicitud o leer la entrada usando getReader(. ).
}
}
// Pasa el control al siguiente filtro
chain.doFilter(solicitud, respuesta);
}
public void init(FilterConfig filterConfig) lanza ServletException {
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("codificación");
Valor de cadena = filterConfig.getInitParameter("ignorar");
si (valor == nulo) {
this.ignore = verdadero;
}
de lo contrario si (valor.equalsIgnoreCase ("verdadero")) {
this.ignore = verdadero;
}
de lo contrario si (value.equalsIgnoreCase("sí")) {
this.ignore = verdadero;
}
demás {
this.ignore = falso;
}
}
protected String selectEncoding(ServletRequest request) {
return (this.encoding);
}
}
De esta manera, nuestra solicitud está codificada en UTT-8 y podemos usarla en el programa JSP: request.getParameter("myKey" ) Puede obtener directamente la cadena codificada en UTF-8, en lugar de así: new String(request.getParameter("myKey").getBytes("ISO-8859-1"), "GBK") para resolver esos caracteres confusos. http://www.devdao.com/
(2) Texto de doble byte procesado por la base de datos http://www.upas.org/java/DatabaseEncodingProblemSolution/
Otro es el problema de escribir en la base de datos. Sabemos que cuando usamos mysql, podemos usar esta URL para solucionar el problema de codificación de caracteres chinos: jdbc:mysql://localhost:3306/upas?useUnicode=true&characterEncoding=gb2312.
Entonces, ¿qué debemos hacer con aquellas cosas que no podemos resolver como MySQL? ¿Deberíamos escribir así cada vez?
importar java.sql.*;
Class.forName("org.gjt.mm.mysql.Driver");
Conexión con = nulo;
Declaración preparada pstmt = nulo;
Conjunto de resultados rs = nulo;
intentar {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
pstmt = con.prepareStatement("SELECCIONE f3, f4 DE tbl1 DONDE f1 =? Y f2 =?");
pstmt.setString(1, nueva cadena(f1.getBytes("GBK"), "ISO-8859-1");
pstmt.setString(2, nueva cadena(f2.getBytes("GBK"), "ISO-8859-1");
rs = pstmt.executeQuery();
Cadena f3, f4;
mientras(rs.siguiente()) {
f3 = nueva cadena(rs.getString(1).getBytes("ISO-8859-1"), "GBK");
f4 = nueva cadena(rs.getString(2).getBytes("ISO-8859-1"), "GBK");
}
}
finalmente {
//cerrar recursos
...
}
De hecho, podemos escribirlo así:
importar java.sql.*;
importar com.redv.sql.encoding.*;
Class.forName("org.gjt.mm.mysql.Driver");
Conexión con = nulo;
Declaración preparada pstmt = nulo;
Conjunto de resultados rs = nulo;
intentar {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
//Asumir el control de la instancia de conexión de la base de datos
codificación booleana = verdadero;
EncodingConnection codingConnection = new EncodingConnection(con, codificación, "ISO-8859-1", "GBK");
// Obtenga la instancia de conexión de la base de datos después de asumir el control. Use con directamente en el futuro, que ya es una instancia reempaquetada por EncodingConnection.
con = codificaciónConnection.getConnection();
pstmt = con.prepareStatement("SELECCIONE f3, f4 DE tbl1 DONDE f1 =? Y f2 =?");
pstmt.setString(1, f1);
pstmt.setString(2, f2);
rs = pstmt.executeQuery();
Cadena f3, f4;
mientras(rs.siguiente()) {
f3 = rs.getString(1);
f4 = rs.getString(2);
}
}
finalmente {
//cerrar recursos
...
}
Veamos, ¿qué tal? Solo necesitamos modificarlo ligeramente donde obtenemos la conexión de la base de datos. Incluso podemos guardarlo como un parámetro en las propiedades y cambiar el valor booleano de codificación para establecer si usar la conversión de codificación automática. A menudo podemos usar una clase de base de datos para encapsular getConnection que obtiene la conexión de la base de datos, de modo que podamos obtener la conexión de la base de datos desde javax.sql.DataSource. En este momento, solo necesitamos modificar nuestra clase de base de datos, en lugar de buscar todos los lugares donde se usan rs.setString() y rs.getString() para agregar nuestro código de conversión de codificación. Incluso cuando usamos la declaración con.createStatment(), no hay problema incluso si nuestra declaración sql contiene caracteres chinos u otros caracteres de doble byte:
SELECCIONE nombre, género DE la tabla de estudiantes DONDE la clase COMO '%computadora%'