На главнуюКонтактыКарта сайта

Размещение Java программ

Проблема с кодировкой при занесении данных в базу MySQL

При занесении текстовых данных, содержащих символы кирилицы, в базу данных MySQL с помощью сервлета или JSP страницы, необходимо указать в сервлете или JSP странице, в какой кодировке попадают в сервлет данные и в какой кодировке они должны сохраняться в базу данных.

Аналогично при извлечении текстовых данных из базы и показе их с помощью сервлета или JSP страницы необходимо указать кодировку извлекаемых из базы данных и кодировку, в которой будет отображаться итоговая страница.

Указание кодировки, в которой поступают в сервлет данные, отправленные клиентом, производится с помощью метода setCharacterEncoding("кодировка") объекта типа HttpServletRequest.

Указание кодировки в которой отправляется формируемый сервлетом HTML-код производится с помощью метода setContentType("text/html; charset=кодировка") объекта типа HttpServletResponse.

Ну а указание кодировки, в которой данные сохраняются в базу данных и извлекаются от туда, производится в настройках JDBC-драйвера базы данных.

При использовании JDBC-драйвера к MySQL Connector/J настройки кодировки производятся с помощью объекта типа java.util.Properties, содержащего указание параметров кодировки базы и передаваемого как аргумент при создании соединения с базой.

Properties properties=new Properties();
properties.setProperty("user","логин");
properties.setProperty("password","пароль");
properties.setProperty("useUnicode","true");
properties.setProperty("characterEncoding","кодировкаДанныхВБазе");
Connection connection=DriverManager.getConnection(
"jdbc:mysql://localhost:3306/имяБазы", properties);

При указании кодировки, используемой JDBC-драйвером для хранения данных в базе, важно чтобы эта кодировка реально совпадала с кодировкой, используемой базой или таблицей, в которой хранятся данные.

Желательно при создании таблиц указывать кодировку хранимых в них данных явно, не пологаясь на настройки по умолчанию.

CREATE TABLE имяТаблицы (список полей) CHARACTER SET кодировка

Наиболее предпочтительной для многоязыковых текстов является кодировка utf8 (здесь приводится обозначение кодировки используемое в MySQL).

Если тексты, хранимые в таблице, содержат только символы кирилицы и латиницы, можно указать при создании таблицы кодировку cp1251.

Более подробную информацию о кодировках, используемых в БД MySQL и способах их задания, можно получить на официальном сайте MySQL.

Создать таблицу с учетом кодировки или поменять кодировку уже существующей таблицы можно с SQL-запросов, отправляемых из приложения, либо с помощью утилиты phpMyAdmin доступной клиентам нашего хостинга.

Ниже приводится пример сервлета, получающего данные от клиента в кодировке CP1251 и сохраняющего их в таблицу с кодировкой UTF-8:

import java.io.*;
import java.sql.*;
import java.util.Properties;
import javax.servlet.*;
import javax.servlet.http.*;

/*
Для работы этого примера требуется предварительно создать таблицу 
с помощью следующего SQL-запроса:
CREATE TABLE test (id INT AUTO_INCREMENT PRIMARY KEY, value VARCHAR(255)) 
CHARACTER SET utf8;
*/
public class DBServlet extends HttpServlet {
    
    protected void service(HttpServletRequest request,
    HttpServletResponse response)
    throws ServletException, IOException {
        //указываем кодировку для HTML-страницы, отправляемой клиенту
        response.setContentType("text/html; charset=windows-1251");
        //указываем кодировку для данных полученых от клиента
        request.setCharacterEncoding("CP1251"); 
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<head><title>DBServlet</title></head>");
        out.println("<body>");
        out.println("<form method=\"post\" action=\"dbservlet\">");
        out.println("<input type=\"text\" name=\"t1\">");
        out.println("<input type=\"submit\">");
        out.println("</form>");
        out.println("<hr>");
        try{
           Connection connection=getDBConnection();
           Statement statement=connection.createStatement();
           if(request.getMethod().equals("POST")){
               String t1=(request.getParameter("t1")!=null)?
	       request.getParameter("t1").trim():"";
               if(t1.length()>0){
                   statement.executeUpdate("INSERT INTO test ( value )
		   VALUES ('"+t1+"')");
               }
           }
           ResultSet result=statement.executeQuery("SELECT id, value FROM 
	   test ORDER BY id DESC");
           out.println("<table border=\"1\">");
           out.println("<tr><th>id</th><th>value</th></tr>");
           while(result.next()){
               out.println("<tr>");
               out.println("<td>"+result.getString("id")+"</td>");
               out.println("<td>"+result.getString("value")+"</td>");
               out.println("</tr>");
           }
           out.println("</table>");
           connection.close();
        }catch(Exception e){
            log(e.toString());
        }
        out.println("</body>");
        out.println("</html>");
    }
    
    /*
    Не самый лучший метод для получения соединения с базой данных.
    Для повышения производительности при работе с базами данных рекомендуем
    использовать пулы соединений.
    */
    protected Connection getDBConnection()throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        Properties properties=new Properties();
        properties.setProperty("user","логин");
        properties.setProperty("password","пароль");
        /*
          настройки указывающие о необходимости конвертировать данные из Unicode
	  в UTF-8, который используется в нашей таблице для хранения данных
        */
        properties.setProperty("useUnicode","true");
        properties.setProperty("characterEncoding","UTF-8");
        return(DriverManager.getConnection("jdbc:mysql://localhost:3306/имяБазы",
	properties));
    }
}

Полезные ссылки:

Java: Русские буквы и не только...

Служба поддержки:
E-Mail: support@brim.ru
Тел.: (495) 517-70-64
Адрес:
115419, г. Москва,
ул. Орджоникидзе, д.11, стр.11,
бизнес-центр «АВС-Эстэйт»