0

I have made a simple form where a user enters a name and then this name is stored in the database. I'm using Spring MVC and Thymeleaf. My database is MySQL. The problem occurred when I was trying to enter non-latin characters. enter image description here

After storing the non-latin name in the database, I tried to display it on the webpage, but instead of cyrillic characters I got strange characters like this:

ИмÑ

  • I'm sure that encoding in the database is correct because when I tried to store a non-latin name using MySQL Workbench the encoding was right.
  • Thymeleaf encoding is also set to UTF-8. Non-lating characters are displayed correctly when I put them, for example, in a tag like this:

<h1> Заголовок </h1>

I have already tried:

  • adding this line in the html file: <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
  • adding this attribute in the form tag: <form accept-charset="UTF-8" ...

But nothing works. What am I doing wrong?

gurmigou
  • 55
  • 6
  • Have you try to specify the charset in the url data source ? spring.datasource.url = jdbc:mysql://localhost:3306/YOUR_DB_NAME?useUnicode=yes&characterEncoding=UTF-8 – Josselin Beaud'huy May 06 '21 at 12:08
  • I tried but nothing changed – gurmigou May 06 '21 at 12:35
  • Try this : https://stackoverflow.com/a/36397227/13397146 – Josselin Beaud'huy May 06 '21 at 12:56
  • I tried it earlier. GET request started work correctly with non-latin characters after adding this configurations. Unfortunately, it doesn't work for POST – gurmigou May 06 '21 at 14:57
  • 2
    Specify the `utf8mb4` character set on all tables and text columns in your database. More at [UTF-8 all the way through](https://stackoverflow.com/questions/279170/). You are facing to a simple [mojibake](https://en.wikipedia.org/wiki/Mojibake) case like in Python `'Имя'.encode('utf-8').decode('cp1252','ignore')` (returns `'ИмÑ'`). – JosefZ May 06 '21 at 15:48

2 Answers2

1

I have searched a lot and at last, I have found a solution.

- The first one I would rather call a workaround than a solution:

    @PostMapping
    public String create(@RequestParam("name") String name, @RequestParam("age") int age) {      

        byte[] bytes = name.getBytes(StandardCharsets.ISO_8859_1);
        name = new String(bytes, StandardCharsets.UTF_8); // now "name" contains characters in the correct encoding

        ...
    }

- The second solution looks much better in my opinion:
At first, create a Filter class and set the encoding of the POST request there:

   public class RequestFilter extends HttpFilter {
        @Override
        protected void doFilter(HttpServletRequest request, HttpServletResponse response,
                                FilterChain chain) throws IOException, ServletException
        {
            request.setCharacterEncoding("UTF-8");
            chain.doFilter(request, response);
        }
    }

Then you should register a Filter in web.xml

 <filter>
    <filter-name>filter_nane</filter-name>
    <filter-class>class_path_to_filter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>filter_nane</filter-name>
    <url-pattern>/*</url-pattern> 
  </filter-mapping>
gurmigou
  • 55
  • 6
0

I faced a similar problem. Thank you for your answer @gurmigou. You showed me the way to go, and I found an even better solution.

    <filter>
    <filter-name>filter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>filter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
Andrew
  • 1