I have recently been struggling with a utf-8 to ISO-8859-1 problem with Ajax
and Struts2.

The problem is basically that our application requires iso-8859-1 characters
and Ajax is configured to only post utf-8 (ajax is utf-8 either way, can not
be changed). So some kind of conversion has to take place at some level.

My problem can be divided into two parts:
1. Make Struts2 understand that there is a incoming utf-8 POST, even though
struts.xml (which set the struts2 default encoding) is configured to use
iso-8859-1
2. Convert the characters from utf-8 to iso-8859-1

My first thought was to create an interceptor which could handle the
conversion. It would test if it was a utf-8 post, and then try to convert
it. In my jQuery.ajax function I sat contentType like this:
contentType: "application/x-www-form-urlencoded; charset=utf-8",
But when I debugged my interceptor I noticed that the request character
encoding was changed, even though I sat the charset explicit in the ajax
post. So all my characters were converted into something unreadable before I
was able to do my own conversion (this occurs when you just set the
character encoding without any conversion first).
But why did this happen?

In the class org.apache.struts2.dispatcher.Dispacter, method public void
prepare(HttpServletRequest request, HttpServletResponse response) there are
some logic concerning request character encoding. It looks like this:

 public void prepare(HttpServletRequest request, HttpServletResponse
response) {
        String encoding = null;
        if (defaultEncoding != null) {
            encoding = defaultEncoding;
        }

        Locale locale = null;
        if (defaultLocale != null) {
            locale = LocalizedTextUtil.localeFromString(defaultLocale,
request.getLocale());
        }

        if (encoding != null) {
            try {
                request.setCharacterEncoding(encoding);
            } catch (Exception e) {
                LOG.error("Error setting character encoding to '" + encoding
+ "' - ignoring.", e);
            }
        }

        if (locale != null) {
            response.setLocale(locale);
        }

        if (paramsWorkaroundEnabled) {
            request.getParameter("foo"); // simply read any parameter
(existing or not) to "prime" the request
        }
    }

If you take a look at this piece of code, you can see that it overrides the
encoding if it is set as defaultEncoding (from struts.xml). This is OK, the
problem is this check:
if (encoding != null) {
            try {
                request.setCharacterEncoding(encoding);
            } catch (Exception e) {
                LOG.error("Error setting character encoding to '" + encoding
+ "' - ignoring.", e);
            }
        }

I think the correct thing would be to also do a check if the
request.getCharacterEncoding was already set. I should look like this:
if (encoding != null && request.getCharacterEncoding() == null ) {
            try {
                request.setCharacterEncoding(encoding);
            } catch (Exception e) {
                LOG.error("Error setting character encoding to '" + encoding
+ "' - ignoring.", e);
            }
        }
With this change utf-8 would be kept as the request character encoding and I
could do my conversion in my interceptor.
This would solve my problem number 1. Am I correct when I say this is a bug?

The way I went around it was to create a filter which is executed before
FilterDispatcher in struts2. In this filter I check if it is a uft-8 post
and if it is, I wrap the HttpServletRequest into my own
CharsetRequestWrapper. In my wrapper I will override getParameterMap which
converts my characters, put them back into the map and return them. I also
run a req.getParameter("foo"); after my wrapping to populate the parameters
on the request.

It works, but it took me a couple of days to work it out.

Any comments on this?

-- 
View this message in context: 
http://www.nabble.com/CharacterEncoding-bug-in-Struts2--tp15408328p15408328.html
Sent from the Struts - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to