maaartinus
maaartinus

Reputation: 46492

Stop Tomcat from enforcing ISO-8859-1

For whatever reason, Apache Tomcat/8.0.28 (I'm using no Spring, no JSP, just a plain Servlet) ignores my

private static final String JSON_MEDIA_TYPE = "application/json; charset=utf-8";
response.setContentType(JSON_MEDIA_TYPE);

and also the redundant

response.setHeader("Content-Type", JSON_MEDIA_TYPE);

and

response.setCharacterEncoding("UTF_8");

and sends

Content-Type: application/json;charset=ISO-8859-1

which is plain wrong (as JSON is always UTF-8) and mangles my output. The request headers contain

Accept:application/json, text/plain, */*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3

I'm pretty sure, it's Tocmcat's fault, as getting

Content-Tipe:application/json; charset=utf-8

(with the intentional typo) works perfectly.

Initially, there was no filter in the web.xml, then I added

<filter>
    <filter-name>AddDefaultCharsetFilter</filter-name>
    <filter-class>org.apache.catalina.filters.AddDefaultCharsetFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>AddDefaultCharsetFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

but without any effect.

Upvotes: 0

Views: 1588

Answers (1)

Stephen C
Stephen C

Reputation: 719729

There are a number of (potential) problems:

1) This line:

   response.setCharacterEncoding("UTF_8");

should be

   response.setCharacterEncoding("UTF-8");

2) You (probably) shouldn't be setting the content encoding as part of the content type:

   String JSON_MEDIA_TYPE = "application/json; charset=utf-8";
   response.setContentType(JSON_MEDIA_TYPE);

3) If you are calling setCharacterEncoding and setContentType after calling getWriter / getOutputStream, then they will have no effect1.


UPDATE

2) Why?

Because:

  • the javadocs don't say that you can / should set it that way, and
  • it is not clear what takes precedence if you set the character encoding via both setContentType and setCharacterEncoding (and setHeader to boot)

It is better to do things the way that the javadocs say / show ... especially if you want portability.

4) Why the filter doesn't work?

This is a guess: possibly because you have already set / attempted to set the encoding in the servlet? That filter sets the >>default<< charset.

5) Why was it too late? Nothing has been written before.

Because the javadoc says that it is the call to getWriter() etc that "commits" the response header.


1 - That is, no effect on the response sent to the client. The HttpServletResponse object is likely to reflect the calls that you have made though.

Upvotes: 2

Related Questions