0

I have a web application which receives data on Russian language from browser and writes strings to MySql database. Strings in database look like ÐÑдел инÑоÑмаÑионнÑÑ ÑеÑно instead russian characters. How can I write strings to database correctly?

Database is encoded as utf8_general_ci. Jsp pages have the encoding utf8.

Example jsp page which sends data:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<title>ОИТ</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<body id="altbody">
<div id="wrapper-header">
  <div id="header">
    <h1>Отдел информационных технологий</h1>
  </div>
</div>
<div id="wrapper-menu">
  <div id="menu">
    <ul>
        <li><a href="index.jsp">Главная</a></li>
        <li><a href="oio.jsp">ОИО</a></li>
        <li><a href="ooz.jsp">ООЗ</a></li>
        <li><a href="oit.jsp">ОИТ</a></li>
        <li><a href="okkio.jsp">ОККИО</a></li>
    </ul>
  </div>
</div>
<div id="content">
    <form action="Controller" enctype="multipart/form-data" method="post">
        <input type="hidden" id="department" name="department" value="Отдел информационных технологий">
        <input name="computerProblem" id="computerProblem" placeholder="Укажите имя компьютера на котором возникла техническая проблема!" class="textbox" required /><br>
        <input name="problem" id="problem" placeholder="Опишите техническую проблему!" class="textbox" type="text" required /><br>
        <input type="file" id="file" name="file"><br>
        <input name="submit" class="button" type="submit" value="Отправить" />
    </form>
</div>
</body>
</html>

Servlet:

@WebServlet(name="Controller",urlPatterns={"/Controller"})
@MultipartConfig(fileSizeThreshold=1024*1024,
        maxFileSize=1024*1024*5, maxRequestSize=1024*1024*5*5)
public class Controller extends HttpServlet {

    private Executor executor;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String userName = System.getProperty("user.name");
        String department = new String(req.getParameter("department").getBytes("windows-1251"), "utf-8");
        String computerProblem = new String(req.getParameter("computerProblem").getBytes("windows-1251"), "utf-8");
        String descriptionProblem = new String(req.getParameter("problem").getBytes("windows-1251"), "utf-8");
        Part part = req.getPart("file");
        executor = new Executor();
        if (part.getSize() != 0){
            String type = part.getContentType();
            if (type.equals("image/png") || type.equals("image/jpeg")){
                String path = executor.saveImage(part, executor.getMaxIdFromDb());
                executor.writeProblemToDbWithImage(new User(userName, department), new Problem(computerProblem, descriptionProblem, path, new Date()));
                req.getRequestDispatcher("/ok.jsp").forward(req, resp);
            }else {
                req.getRequestDispatcher("/error.jsp").forward(req, resp);
            }
        }else{
            executor.writeProblemToDb(new User(userName, department), new Problem(computerProblem, descriptionProblem, new Date()));
            req.getRequestDispatcher("/ok.jsp").forward(req, resp);
        }

        if(executor != null) {
            executor.closeDb();
        }
    }
}

Connection to database:

public class ConnectionDb {
    private String hostName;
    private Properties properties;

    public ConnectionDb(String hostName, String userName, String password) {
        this.hostName = hostName;
        properties=new Properties();
        properties.setProperty("user", userName);
        properties.setProperty("password", password);
        properties.setProperty("useUnicode", "true");
        properties.setProperty("characterEncoding","utf8");
    }

    /*
        Метод возвращает подключение к базе данных
     */
    public Connection getConnection(){
        Connection connection = null;
        try{
            //Class.forName("org.postgresql.Driver");
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(hostName, properties);
        }catch (Exception ex){
            ex.printStackTrace();
        }
        return connection;
    }
}

Executor:

public class Executor {

    private Connection connection;
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    public Executor(){
        connection = new ConnectionDb("", "", "").getConnection();
        //connection = new ConnectionDb("", "", "").getConnection();
    }

    public void writeProblemToDb(User user, Problem problem) {
        try {
            PreparedStatement ps = connection.prepareStatement("INSERT INTO trubleshutting (user_Name, department, computer_Name, description_Problem, date) VALUES (?, ?, ?, ?, ?)");
            ps.setString(1, user.getName());
            ps.setString(2, user.getDepartment());
            ps.setString(3, problem.getComputerName());
            ps.setString(4, problem.getDescription());
            ps.setTimestamp(5, Timestamp.valueOf(String.valueOf(dateFormat.format(new java.util.Date()))));
            ps.execute();
            ps.close();
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void writeProblemToDbWithImage(User user, Problem problem){
        try {
            PreparedStatement ps = connection.prepareStatement("INSERT INTO trubleshutting (user_Name, department, computer_Name, description_Problem, path_Image, date) VALUES (?, ?, ?, ?, ?, ?)");
            ps.setString(1, user.getName());
            ps.setString(2, user.getDepartment());
            ps.setString(3, problem.getComputerName());
            ps.setString(4, problem.getDescription());
            ps.setString(5, problem.getPathToImage());
            ps.setTimestamp(6, Timestamp.valueOf(String.valueOf(dateFormat.format(new java.util.Date()))));
            ps.execute();
            ps.close();
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


    public int getMaxIdFromDb(){
        int result = 0;
        try {
            PreparedStatement ps = connection.prepareStatement("SELECT trubleshutting.id as 'id' FROM sboi.trubleshutting ORDER BY sboi.trubleshutting.id DESC LIMIT 1");
            ResultSet resultSet = ps.executeQuery();
            if (resultSet.next()){
                result = resultSet.getInt(1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ++result;
    }

    public String saveImage(Part part, int id){
        String path = "C:\\screenshots\\" + "image" + id + ".png";
        try {
            part.write(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return path;
    }

    public void closeDb(){
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
Oleg1n
  • 19
  • 5
  • Did you verify you have the correct values in the variables right before storing them in the database? – x80486 Aug 18 '16 at 13:56
  • Yes, i'm typing them self. Input: Отдел информационных технологий in the database: ÐÑдел инÑоÑмаÑионнÑÑ ÑеÑно. – Oleg1n Aug 18 '16 at 14:08
  • What I meant was: do you receive those values when you debug inside the system? Can you share the project in GitHub, Bitbucket, etc.? – x80486 Aug 18 '16 at 14:34
  • I copied war file of web application to folder /webapps. Then i ran it. In browser filled all fields and pressed button "Send". In database appeared string ÐÑдел инÑоÑмаÑионнÑÑ ÑеÑно. Sorry if i didn't understand you. – Oleg1n Aug 18 '16 at 14:49

1 Answers1

0

Add ?useUnicode=yes&characterEncoding=UTF-8 to the JDBC URL. Note the spelling "UTF-8", not 'utf8'. This is talking to Java, not MySQL.

What you have is Mojibake. If changing the connection is not sufficient, see Trouble with utf8 characters; what I see is not what I stored , especially the discussion of SELECT HEX... and "Mojibake".

Community
  • 1
  • 1
Rick James
  • 135,179
  • 13
  • 127
  • 222