Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jetty response character encoding

How do I set the default character encoding on my responses to UTF-8?

I've tried this

    System.setProperty("file.encoding", "UTF-8");

and this

    System.setProperty("org.eclipse.jetty.util.UrlEncoding.charset", "utf-8");

Neither has any effect - responses are still sent with the header

Content-Type: text/html; charset=ISO-8859-1

I'd like to do this for all text/html responses, and ideally in code rather than XML. I'm using Jetty 9.

like image 996
Timmmm Avatar asked Aug 04 '15 08:08

Timmmm


4 Answers

The Jetty documentation claims it uses UTF-8 by default, but that seems to be a lie. If you do the normal response.getWrite().println("Hello"), then the content encoding is determined as follows.

  1. A default mapping from content-type to content-encoding is loaded from org/eclipse/jetty/http/encoding.properties:
        // MimeTypes.java:155
        ResourceBundle encoding = ResourceBundle.getBundle("org/eclipse/jetty/http/encoding");
        Enumeration<String> i = encoding.getKeys();
        while(i.hasMoreElements())
        {
            String type = i.nextElement();
            __encodings.put(type,encoding.getString(type));
        }

The default file is:

text/html   = ISO-8859-1
text/plain  = ISO-8859-1
text/xml    = UTF-8
text/json   = UTF-8
  1. Response.getWriter() tries to use that map, but defaults to ISO-8859-1
@Override
public PrintWriter getWriter() throws IOException
{
    if (_outputType == OutputType.STREAM)
        throw new IllegalStateException("STREAM");

    if (_outputType == OutputType.NONE)
    {
        /* get encoding from Content-Type header */
        String encoding = _characterEncoding;
        if (encoding == null)
        {
            encoding = MimeTypes.inferCharsetFromContentType(_contentType);
            if (encoding == null)
                encoding = StringUtil.__ISO_8859_1;
            setCharacterEncoding(encoding);
        }

So you can see that for text/html it doesn't default to UTF-8. I don't think there is a way of changing the default from code. The best you can do is change the encoding.properties file to this:

text/html   = UTF-8
text/plain  = UTF-8
text/xml    = UTF-8
text/json   = UTF-8

But even then if it finds an encoding that isn't in there it will default to ISO-8859-1.

like image 118
Timmmm Avatar answered Nov 12 '22 04:11

Timmmm


response.setCharacterEncoding("UTF-8");
like image 27
Vladislav Avatar answered Nov 12 '22 04:11

Vladislav


It matter when you use Writer();

For me If I write

resp.getWriter().println("Return");
resp.setContentType("text/html; charset=UTF-8");

I won't work

But if I change the sequence

resp.setContentType("text/html; charset=UTF-8");
resp.getWriter().println("Return");

It will be alright

like image 41
Hleb Bandarenka Avatar answered Nov 12 '22 02:11

Hleb Bandarenka


I created character encoding filter to one legacy application.

public class CharacterEncodingFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        if(req instanceof Request){             
            req.setCharacterEncoding("UTF-8");
        }
        chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
    }

    @Override
    public void destroy() {
    }
}

In web.xml filter-mapping has the url-pattern of /*. This routes all requests from the web application through the CharacterEncodingFilter.

<filter>
    <display-name>CharacterEncoding</display-name>
    <filter-name>CharacterEncoding</filter-name>
    <filter-class>my.app.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CharacterEncoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
like image 1
JohnP Avatar answered Nov 12 '22 03:11

JohnP