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.
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.
- 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
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.
response.setCharacterEncoding("UTF-8");
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
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>
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