views:

484

answers:

2

I work on Spring MVC + Hibernate application, use MySQL (ver. 5.0.51a) with the InnoDB engine.

The problem appears when I am sending a form with cyrillic characters. As the result, database contains senseless chars in unknown encoding.

All the JSP pages, database (+ tables and fields) created using UTF-8. Hibernate config also contains property which sets encoding to UTF-8.

I had solved this by creating filter which encodes request content with UTF-8. Exemplary code:

…
encoding = "UTF-8";
request.setCharacterEncoding(encoding);
chain.doFilter(request, response);
…

But it visibly slows down the app.

The interesting thing is that executing insert query directly from the app (i.e. running from Eclipse as Java Application) works perfect.

UPD.

As far as I understood, using filter is the only working solution in my case.

I didn't know about standard CharacterEncodingFilter. Use it now, works very well!

<filter>
    <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>
+2  A: 

It's your price for doing the correct encoding transformation: UTF-8 (request)-> UTF-16 (Java) -> UTF-8 (DB).

I would be surprised though if it (transformation) took more than a few percent of overall request time. If it does, something is done wrong IMHO.

All the JSP pages ... created using UTF-8

Does your container set UTF-8 as page encoding? (See generated page properties). If it does, you don't need to set filter, the browser would submit the form back in UTF-8.

Vladimir Dyuzhev
Browsers usually don't send encoding when submitting a form and servlet container assumes that it's `ISO-8859-1`, so filter is the only right solution in this case.
axtavt
Generated page contains the line <meta http-equiv="Content-Type" content="text/html;charset=utf-8">But, as I mentioned, no success without a filter.If you think the transformation process is kind of precey, what's the better solution in this case?
Bar
Browsers do send encoding -- the same as the original encoding of the page was, or UTF-8. Otherwise how us, non-Latin1-people, would submit our pity multibyte forms? :D
Vladimir Dyuzhev
@Bar, trace HTTP requests (use FireBug or TamperData for Firefox, for instance) and see what's coming from and goes to server. Check out headers for Content-Transfer-Encoding.
Vladimir Dyuzhev
+1  A: 

Your JSP files must be UTF-8 in two ways:

  • the header <%@page pageEncoding="UTF-8" %>
  • their content - right-click > properties in eclipse and make their encoding UTF-8 there (it may refuse to convert it, so cut the current content, change the encoding, and then paste it back)

Then spring has a CharacterEncodingFilter for this case, which shouldn't have any significant performance hit:

<filter>
    <filter-name>CharacterEncodingFilter</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>

Actually, no filter should have a significant performance hit, unless its doFilter() method is declared synchronized.

Bozho
@Bozko. I have UTF-8 in both the header and the pages. doFilter() method does not contain the keyword «synchronized». It seems like slowing down is just my subjective perception. CharacterEncodingFilter works fine! Thanks.
Bar
-1 for "If this doesn't work". If your pages are not `ISO-8859-1` (at browser side), you MUST use `CharacterEncodingFilter` for correct processing of non-us-ascii input (unless your servlet container violates the servlet spec here, like Jetty).
axtavt
@axtavt I fixed that tiny detail.
Bozho
@Bozho so the filter will convert posted form values or?
Blankman
yes, it will. 100% :)
Bozho