views:

668

answers:

2

I have a strange encoding situation, whereby the html page itself displays as it should (with all the accénted chäracters properly displayed), but all the popup dojo dialogs fail to use the correct encoding.

Here is the setup:

  • Java web project with Hibernate/Spring/Struts2 running on Tomcat6.0.18; the pages are generated as JSP tiles, assembled together by Tiles2.
  • all the source files are UTF-8 encoded, except for the resource property files (*.properties) which are in ISO-8859-1 (as per Java specifications).
  • Database is UTF-8 encoded.
  • struts.xml contains a definition of the constant:

    <constant name="struts.i18n.encoding" value="UTF-8"/>
    
  • Each JSP tile starts with the statement

    <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
    
  • Each JSP page (formed of several tiles) starts with the statement

    <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
    <?xml version="1.0" encoding="UTF-8"?>
    
  • Each HTML page generated from the JSP code contains the following <head> meta-tag:

    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
    
  • A Tomcat encoding filter sets the header for every single request going through Tomcat to the value:

    text/html;charset=UTF-8
    
  • dojo 1.2.3 is initialized on each page with the statement

    <script type="text/javascript" src="/scripts/dojo/dojo/dojo.js" djConfig="parseOnLoad:true,usePlainJson:true,locale:'fr'"></script>
    
  • A dijit.Dialog is first created and then opened by the following statements (the /votingOptions action-URL returning a JSP snippet that follows the same specifications as previously---that JSP snippet ends up embedded inside the <div> of the dialog):

    dialog = new dijit.Dialog({title:"My title",loadingMessage:"Loading..."});
    dialog.setHref('/votingOptions');
    dialog.show();
    

As a result of all that setup, all the "normal" pages (that is, putting aside the dojo dialogs) display all the characters as they should, accents and all, whether the text comes from the database or from the resource files.

On the other hand, the content of any dojo dialog gets mangled: all the non-accented characters are fine, but the accented characters get displayed exactly as if one was attempting to read UTF-8 characters as ISO-8859-1 ones (whether these characters come from the database or from the resource files).

So, for example, the name "Kurt Gödel" (as it would correctly appear on the main page) will be displayed as "Kurt Gödel" in the dojo dialog!

Note that Firebug reports the same response headers as served by Tomcat in both situations (whether calling the main page, or, once on the page, opening a dojo dialog):

Server: Apache/2.2.3 (CentOS)
Content-Language: en-US
Connection: close
Content-Type: text/html;charset=UTF-8

The only difference between those two types of request (apart from Content-Length) is:

Transfer-Encoding: chunked

which is present when requesting the main page but absent in the dojo-dialog case.

Can anyone figure what escaped me so far? Alternatively, suggestions would be welcome as to the kind of sleuthing I should perform to get to the bottom of this!

A: 

The Dialog widget in Dojo calls the URL /votingOptions, which I assume is handled by a servlet or Struts action.

Because it's an Ajax call, I also assume that if you're using the struts action, then you're sending the response via the HttpServletResponse object instead of redirecting to a view.

Either way, make sure to use:

String str = "こんにちわ、 Kürt Gödel";
response.getWriter().write(str);

instead of:

response.getOutputStream().println(str);

I was able to reproduce the behavior you were experiencing with these pieces of code. The first one shows all characters correctly (even the japanese ones !), the second shows a garbled message.

Since you're developping an Ajax app, also make sure to install the HttpFox plugin, which is better at showing Http traffic than Firebug.

Leonel
A: 

I had a similar problem.
In my case the dojo javascript files where returned in iso-8859-1 format. To fix it I had to override the method getContentType() in the default FilterDispatcher class. I replaced it to the following code (tested in Struts 2.0.9):


protected String getContentType(String name) {
        if (name.endsWith(".js")) {
            return "text/javascript;charset=\"UTF-8\"";
        } else if (name.endsWith(".css")) {
            return "text/css";
        } else if (name.endsWith(".html")) {
            return "text/html;charset=\"UTF-8\"";
        } else if (name.endsWith(".txt")) {
            return "text/plain";
        } else if (name.endsWith(".gif")) {
            return "image/gif";
        } else if (name.endsWith(".jpg") || name.endsWith(".jpeg")) {
            return "image/jpeg";
        } else if (name.endsWith(".png")) {
            return "image/png";
        } else {
            return null;
        }
}
Guillermo Vasconcelos