Reagent response character encoding
How do I set the default encoding for my UTF-8 responses?
I tried this
System.setProperty("file.encoding", "UTF-8");
and this one
System.setProperty("org.eclipse.jetty.util.UrlEncoding.charset", "utf-8");
No effect - responses are still sent with a header
Content-Type: text/html; charset=ISO-8859-1
I would like to do this for all text / html responses and ideally in code, not XML. I am using Jetty 9.
source to share
Jetty documentation claims that it uses UTF-8 by default, but that seems to be a lie. If you are doing normal response.getWrite().println("Hello")
, then the content encoding is determined as follows.
- By default the mapping of content content to content content 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));
}
Default file:
text/html = ISO-8859-1 text/plain = ISO-8859-1 text/xml = UTF-8 text/json = UTF-8
-
Response.getWriter()
tries to use this 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 text/html
it has no default value for UTF-8. I don't think there is a way to change the default from the code. The best you can do is change the file encoding.properties
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 is not there, it will default to ISO-8859-1.
source to share
I created a character encoding filter into one legacy app.
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 the web file, filter-mapping has a url pattern / *. 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>
source to share
This is important if you are using Writer ();
For me if I write
resp.getWriter().println("Return");
resp.setContentType("text/html; charset=UTF-8");
I will not work
But if I change the sequence
resp.setContentType("text/html; charset=UTF-8");
resp.getWriter().println("Return");
Everything will be good
source to share
For example, you can change UTF-8
the default to ISO-8859-1
. It's not very clear in the documentation what the parameter name is for versions later than 9.3. Before 9.3 it was org.eclipse.jetty.util.URI.charset
For newer versions it was changed to org.eclipse.jetty.util.UrlEncoding.charset
Here is 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
source to share