Я часто вижу, как люди спрашивают меня на дискуссионных форумах, что делать, если китайские иероглифы, отображаемые в JSP, искажены, почему искажены китайские иероглифы, вводимые пользователем по запросу, почему искажены китайские иероглифы, которые я записываю в базу данных, и т. д. вопросы об искажении китайских иероглифов.
На самом деле, эта проблема очень проста. Независимо от того, будут ли это китайские иероглифы, японские или какой-либо другой двухбайтовый язык, мы будем рассматривать ее как UTF-8.
(1) Двухбайтовый текст в запросе хорош. Теперь мы будем использовать кодировку UTF-8 во всем приложении. Причина выбора UTF-8 не только по вышеуказанным причинам. Мы знаем, что Java основана на ней. UTF-8.8 или выше, поэтому мы должны быть правы, выбрав UTF-8^_^
Сначала мы сохраняем наши файлы .java и .jsp в кодировке UTF-8. Не имеет значения, были ли предыдущие файлы сохранены в UTF-8, но все последующие файлы рекомендуется сохранять в UTF-8.
И напишите в .jsp: < %@page contentType="text/html; charset=UTF-8"%> вместо < %@page contentType="text/html; charset=UTF-8"%>
Затем добавьте следующий абзац в web.xml:
<веб-приложение>
...
<фильтр>
<filter-name>Установить кодировку символов</filter-name>
<filter-class>com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter</filter-class>
<инициализирующий-параметр>
<param-name>кодировка</param-name>
<param-value>UTF-8</param-value>
</инит-парам>
</фильтр>
<сопоставление фильтра>
<filter-name>Установить кодировку символов</filter-name>
<url-шаблон>/*</url-шаблон>
</фильтр-маппинг>
...
</web-app>
Код com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter выглядит следующим образом:
package com.redv.projects.eduadmin.util.filters;
import java.io.IOException;
импортировать javax.servlet.Filter;
импортировать javax.servlet.FilterChain;
импортировать javax.servlet.FilterConfig;
импортировать javax.servlet.ServletException;
импортировать javax.servlet.ServletRequest;
импортировать javax.servlet.ServletResponse;
импортировать javax.servlet.UnavailableException;
импортировать javax.servlet.http.HttpServletRequest;
импортировать javax.servlet.http.HttpServletResponse;
общедоступный класс SetCharacterEncodingFilter
реализует фильтр {
кодирование
строки
=
null
;
this.filterConfig = null
}
Public void doFilter (запрос ServletRequest, ответ ServletResponse,
Цепочка FilterChain) выдает IOException, ServletException {
// Условно выбирает и устанавливает используемую кодировку символов
if (игнорировать || (request.getCharacterEncoding() == null)) {
Кодировка строки = selectEncoding(запрос);
если (кодировка!= ноль) {
request.setCharacterEncoding(encoding); // Вот что работает, ха-ха: переопределяет имя кодировки символов, используемой в теле этого запроса. Этот метод необходимо вызывать перед чтением параметров запроса или чтением ввода с помощью getReader(. ).
}
}
// Передаем управление следующему фильтру
Chain.doFilter(запрос, ответ);
}
Public void init(FilterConfig filterConfig) выдает ServletException {
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("кодирование");
Строковое значение = filterConfig.getInitParameter("игнорировать");
если (значение == ноль) {
this.ignore = правда;
}
иначе если (value.equalsIgnoreCase("истина")) {
this.ignore = правда;
}
иначе если (value.equalsIgnoreCase("да")) {
this.ignore = правда;
}
еще {
this.ignore = ложь;
}
}
protected String selectEncoding(ServletRequest request) {
return (this.encoding }
}
Таким
образом, наш запрос кодируется в UTT-8, и мы можем использовать его в программе JSP: request.getParameter("myKey"); ) Вы можете напрямую получить строку в кодировке UTF-8, а не так: new String(request.getParameter("myKey").getBytes("ISO-8859-1"), "GBK"), чтобы решить эти искаженные символы. http://www.devdao.com/
(2) Двухбайтовый текст, обрабатываемый базой данных http://www.upas.org/java/DatabaseEncodingProblemSolution/
Еще одна проблема — проблема записи в базу данных. Мы знаем, что при использовании MySQL мы можем использовать этот URL-адрес для решения проблемы кодировки китайских символов: jdbc:mysql://localhost:3306/upas?useUnicode=true&characterEncoding=gb2312,
Так что же нам делать с теми вещами, которые мы не можем решить, например MySQL? Стоит ли нам каждый раз писать так:
импортировать java.sql.*;
Class.forName("org.gjt.mm.mysql.Driver");
Соединение con = ноль;
ReadedStatement pstmt = null;
ResultSet rs = null;
пытаться {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
pstmt = con.prepareStatement("ВЫБЕРИТЕ f3, f4 ИЗ таблицы 1, ГДЕ f1 = ? И 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();
Строка ф3, ф4;
в то время как (rs.next ()) {
f3 = новая строка(rs.getString(1).getBytes("ISO-8859-1"), "GBK");
f4 = новая строка(rs.getString(2).getBytes("ISO-8859-1"), "GBK");
}
}
окончательно {
//закрываем ресурсы
...
}
На самом деле, мы можем написать это так:
импортировать java.sql.*;
import com.redv.sql.encoding.*;
Class.forName("org.gjt.mm.mysql.Driver");
Соединение con = ноль;
ReadedStatement pstmt = null;
ResultSet rs = null;
пытаться {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
//Принимаем на себя управление экземпляром подключения к базе данных
логическое кодирование = true;
EncodingConnection codingConnection = новое EncodingConnection (con, кодирование, «ISO-8859-1», «GBK»);
//Получить экземпляр подключения к базе данных после принятия управления. Используйте con напрямую в будущем, который уже является экземпляром, переупакованным EncodingConnection.
con = codingConnection.getConnection();
pstmt = con.prepareStatement("ВЫБЕРИТЕ f3, f4 ИЗ таблицы 1, ГДЕ f1 = ? И f2 =?");
pstmt.setString(1, f1);
pstmt.setString(2, f2);
rs = pstmt.executeQuery();
Строка ф3, ф4;
в то время как (rs.next ()) {
f3 = rs.getString(1);
f4 = rs.getString(2);
}
}
окончательно {
//закрываем ресурсы
...
}
Давайте посмотрим, как насчет этого, нам нужно только немного изменить его там, где мы получаем соединение с базой данных. Мы даже можем сохранить его как параметр в свойствах и изменить логическое значение кодирования, чтобы указать, следует ли использовать автоматическое преобразование кодировки. Часто мы можем использовать класс базы данных для инкапсуляции getConnection, который получает соединение с базой данных, чтобы мы могли получить соединение с базой данных из javax.sql.DataSource. На данный момент нам нужно только изменить наш класс базы данных вместо поиска всех мест, где rs.setString() и rs.getString() используются для добавления нашего кода преобразования кодировки. Даже когда мы используем оператор con.createStatment(), проблем не возникает, даже если наш оператор sql содержит китайские иероглифы или другие двухбайтовые символы:
ВЫБЕРИТЕ имя, пол ИЗ таблицы учеников ГДЕ класс КАК '%компьютер%'