Jetty response character encoding

2020-03-24 04:03发布

问题:

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.

回答1:

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.



回答2:

response.setCharacterEncoding("UTF-8");


回答3:

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



回答4:

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>


回答5:

You can change the default UTF-8 charset to ISO-8859-1 for example. The documentation does not make it very clear which parameter name for versions later than 9.3. Before 9.3 it was org.eclipse.jetty.util.URI.charset For new versions it has been changed to org.eclipse.jetty.util.UrlEncoding.charset Here's an example:

<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>9.4.15.v20190215</version>
    <configuration>
        <systemPropertiesFile>src/main/config/jetty/encode.properties</systemPropertiesFile>
        <jettyXml>src/main/config/jetty/jetty-env.xml</jettyXml>
    </configuration>    
</plugin>

content for encode.properties

org.eclipse.jetty.util.UrlEncoding.charset=ISO-8859-1