[java] Spring MVC UTF-8 Encoding

At the moment I'm trying to get started with Spring MVC. While trying things out I ran into an encoding issue.

I want to display UTF-8 characters on my JSP-Pages so I added a String with UTF-8 characters to my ModelAndView. It looks like this:

@Controller
public class HomeController {

    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

    @RequestMapping(value="/", method=RequestMethod.GET)
    public ModelAndView home() {
        logger.info("Welcome home!");
        return new ModelAndView("home", "utftest", "ölm");
    }

}

On the JSP page I just want to display the String with UTF-8 characters like this:

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Home</title>
</head>
<body>
    <h1>Hello world!</h1>
    <p><c:out value="ö" /></p>
    <p><c:out value="${utftest}"></c:out></p>
</body>
</html>

As result I get following:

Hello world!

ö

v?lm

Note that following code <c:out value="ö" /> was displayed without encoding error. I also set the default encoding to UTF-8 in Springsource Tool Suite but I'm still getting wrong characters.

Edit:

Maybe I should have mentioned that I'm using a Mac with OS X 10.6. For Spring development I use the Springsource Tool Suite from Spring (http://www.springsource.com/developer/sts). Hope this helps to find out what is wrong with my setting.

Edit 2:

Thanks to McDwell, I just tried out using "\u00f6lm" instead of "ölm" in my controller and the encoding issue on the JSP page is gone.

Does that mean my .java files are encoded with wrong character set? Where can I change this in Eclipse?

Thank you.

This question is related to java spring-mvc utf-8 character-encoding

The answer is


right-click to your controller.java then properties and check if your text file is encoded with utf-8, if not this is your mistake.


Depending on how you render your view, you may also need:

@Bean
public StringHttpMessageConverter stringHttpMessageConverter() {
    return new StringHttpMessageConverter(Charset.forName("UTF-8"));
}

Worked for me like here Spring MVC Java config

by added to web initializer

 @Override
      protected Filter[] getServletFilters() {

        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        return new Filter[] { characterEncodingFilter};
      }

In addition to Benjamin's answer - in case if you are using Spring Security, placing the CharacterEncodingFilter in web.xml might not always work. In this case you need to create a custom filter and add it to the filter chain as the first filter. To make sure it's the first filter in the chain, you need to add it before ChannelProcessingFilter, using addFilterBefore in your WebSecurityConfigurerAdapter:

@Configuration
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //add your custom encoding filter as the first filter in the chain
        http.addFilterBefore(new EncodingFilter(), ChannelProcessingFilter.class);

        http.authorizeRequests()
            .and()
            // your code here ...
    }
}

The ordering of all filters in Spring Security is available here: HttpSecurityBuilder - addFilter()

Your custom UTF-8 encoding filter can look like following:

public class EncodingFilter extends GenericFilterBean {

    @Override
    public void doFilter(
            ServletRequest request, 
            ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");

        chain.doFilter(request, response);
    }
}

Don't forget to add in your jsp files:

<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>

And remove the CharacterEncodingFilter from web.xml if it's there.


To solve this issue you need below three steps:

  1. Set page encoding to UTF-8 like below:

    <%@ page language="java" pageEncoding="UTF-8"%>
    <%@ page contentType="text/html;charset=UTF-8" %>
    
  2. Set filter in web.xml file as below:

    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
  3. Set resource encoding to UTF-8, in case if you are writing any UTF-8 characters in Java code or JSP directly.


Easiest solution to force UTF-8 encoding in Spring MVC returning String:

In @RequestMapping, use:

produces = MediaType.APPLICATION_JSON_VALUE + "; charset=utf-8"

Make sure you register Spring's CharacterEncodingFilter in your web.xml (must be the first filter in that file).

<filter>  
    <filter-name>encodingFilter</filter-name>  
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
    <init-param>  
       <param-name>encoding</param-name>  
       <param-value>UTF-8</param-value>  
    </init-param>  
    <init-param>  
       <param-name>forceEncoding</param-name>  
       <param-value>true</param-value>  
    </init-param>  
</filter>  
<filter-mapping>  
    <filter-name>encodingFilter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping> 

If you are on Tomcat you might not have set the URIEncoding in your server.xml. If you don't set it to UTF-8 it won't work. Definitely keep the CharacterEncodingFilter. Nevertheless, here's a concise checklist to follow. It will definitely guide you to make this work.


In addition to Benjamin's answer (which I've only skimmed), you need to make sure that your files are actually stored using the proper encoding (that would be UTF-8 for source code, JSPs etc., but note that Java Properties files must be encoded as ISO 8859-1 by definition).

The problem with this is that it's not possible to tell what encoding has been used to store a file. Your only option is to open the file using a specific encoding, and checking whether or not the content makes sense. You can also try to convert the file from the assumed encoding to the desired encoding using iconv - if that produces an error, your assumption was incorrect. So if you assume that hello.jsp is encoded as UTF-8, run "iconv -f UTF-16 -t UTF-8 hello.jsp" and check for errors.

If you should find out that your files are not properly encoded, you need to find out why. It's probably the editor or IDE you used to create the file. In case of Eclipse (and STS), make sure the Text File Encoding (Preferences / General / Workspace) is set to UTF-8 (it unfortunately defaults to your system's platform encoding).

What makes encoding problems so difficult to debug is that there's so many components involved (text editor, borwser, plus each and every software component in between, in some cases including a database), and each of them has the potential to introduce an error.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to spring-mvc

Two Page Login with Spring Security 3.2.x ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean Spring 5.0.3 RequestRejectedException: The request was rejected because the URL was not normalized The type WebMvcConfigurerAdapter is deprecated RestClientException: Could not extract response. no suitable HttpMessageConverter found Spring boot: Unable to start embedded Tomcat servlet container UnsatisfiedDependencyException: Error creating bean with name 8080 port already taken issue when trying to redeploy project from Spring Tool Suite IDE Error creating bean with name 'entityManagerFactory' defined in class path resource : Invocation of init method failed Difference between the annotations @GetMapping and @RequestMapping(method = RequestMethod.GET)

Examples related to utf-8

error UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte Changing PowerShell's default output encoding to UTF-8 'Malformed UTF-8 characters, possibly incorrectly encoded' in Laravel Encoding Error in Panda read_csv Using Javascript's atob to decode base64 doesn't properly decode utf-8 strings What is the difference between utf8mb4 and utf8 charsets in MySQL? what is <meta charset="utf-8">? Pandas df.to_csv("file.csv" encode="utf-8") still gives trash characters for minus sign UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 23: ordinal not in range(128) Android Studio : unmappable character for encoding UTF-8

Examples related to character-encoding

Changing PowerShell's default output encoding to UTF-8 JsonParseException : Illegal unquoted character ((CTRL-CHAR, code 10) Change the encoding of a file in Visual Studio Code What is the difference between utf8mb4 and utf8 charsets in MySQL? How to open html file? All inclusive Charset to avoid "java.nio.charset.MalformedInputException: Input length = 1"? UTF-8 output from PowerShell ERROR 1115 (42000): Unknown character set: 'utf8mb4' "for line in..." results in UnicodeDecodeError: 'utf-8' codec can't decode byte How to make php display \t \n as tab and new line instead of characters