Why is the encoding not set in the Tomcat response? How can I handle this?

I recently ran into a problem encoding web sites created by a servlet that occurred if the servlets were deployed under Tomcat, but not under Jetty. I worked a bit on this research and simplified the problem to the following servlet:

public class TestServlet extends HttpServlet implements Servlet {
    @Override
    public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/plain");
        Writer output = response.getWriter();
        output.write("öäüÖÄÜß");
        output.flush();
        output.close();
    }
}

If I deploy it under Jetty and point the browser at it, it returns the expected result. Data is returned as ISO-8859-1, and if I look at the headers, Jetty returns:

Content-Type: text/plain; charset=iso-8859-1

The browser determines the encoding from this header. If I distribute the same servlet in Tomcat, strange characters will appear in the browser. But Tomcat also returns data as ISO-8859-1, the difference is that not a single header says this. Therefore, the browser must guess the encoding, and this is not so.

, Tomcat ? , ? , response.setCharacterEncoding("UTF-8"); , , , . , , , . , ?

+5
4

, Servlet ISO-8859-1. , AFAIK , , , "text/plain". :

setContentType , charset.

, ,

response.setContentType("text/plain; charset=XXXX")

Tomcat . , .

, UTF-8 ( , ), , /plain, , .

+4

, apache Wiki , . , Tomcat 5.5 SetCharacterEncodingFilter, apache, Jesse ( Jesse). tomcat , .

, Tomcat :

5.x

WebApps/-/WEB-INF///SetCharacterEncodingFilter.java

WebApps/JSP-/WEB-INF///SetCharacterEncodingFilter.java

6.x

WebApps//WEB-INF///SetCharacterEncodingFilter.java

7.x

7.0.20 Tomcat - . . , Tomcat. : org.apache.catalina.filters.SetCharacterEncodingFilter

: http://wiki.apache.org/tomcat/FAQ/CharacterEncoding#Q3

+2

, , UTF-8:

public class CharacterEncodingFilter implements Filter {
private static final Logger log = Logger.getLogger( CharacterEncodingFilter.class.getName() );

boolean isConnectorConfigured = false;

public void init( FilterConfig filterConfig ) throws ServletException {}

public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException {
    request.setCharacterEncoding( "utf-8" );
    response.setCharacterEncoding( "utf-8" );
    if( ! isConnectorConfigured ) {
        isConnectorConfigured = true;
        try { //I need to do all of this with reflection, because I get NoClassDefErrors otherwise. --jsb
            Field f = request.getClass().getDeclaredField( "request" ); //Tomcat wraps the real request in a facade, need to get it
            f.setAccessible( true );
            Object req = f.get( request );
            Object connector = req.getClass().getMethod( "getConnector", new Class[0] ).invoke( req ); //Now get the connector
            connector.getClass().getMethod( "setUseBodyEncodingForURI", new Class[] {boolean.class} ).invoke( connector, Boolean.TRUE );
        } catch( NoSuchFieldException e ) {
            log.log( Level.WARNING, "Servlet container does not seem to be Tomcat, cannot programatically alter character encoding. Do this in the Server.xml <Connector> attribute instead." );
        } catch( Exception e ) {
            log.log( Level.WARNING, "Could not setUseBodyEncodingForURI to true on connector" );
        }
    }
    chain.doFilter( request, response );
}

public void destroy() {}

}

0

, Tomcat , , , Tomcat. , - response.setCharacterEncoding("UTF-8").

You should not worry about the likelihood that the browser will not understand the encoding, since almost all browsers released over the past 10 years support UTF-8. Although, if you are really worried, you can check the "Accept-Encoding" headers provided by the user agent.

-1
source

All Articles