I'm using Sping MVC with freemarker views. I set up a FreeMarkerViewResolver to resolve the views and it works so far but now I have encoding problems. All my views are HTML 5 pages in UTF-8 encoding and I also added a <meta charset="UTF-8" />
to the HTML page but characters are still printed in the wrong encoding. I checked the HTTP headers with curl and found this:
k@jules:~$ curl -I http://localhost:8080/testweb/test.view
HTTP/1.1 200 OK
Content-Type: */*;charset=ISO-8859-1
But when I request some non-existing resource (Which generates a Tomcat error) then I get this:
k@jules:~$ curl -I http://localhost:8080/testweb/nothere.html
HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
So Tomcat itself returns the correct content-type but a Spring MVC Freemarker views don't.
For a JSP I can set the Content-Type in the JSP header but where can I set it for a freemarker template? I guess I have to do this somewhere in the Spring bean configuration but I can't find the right place.
The view resolver (should be in your dispatcher-servlet.xml
) has a contentType
property for that:
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="prefix" value=""/>
<property name="suffix" value=".ftl"/>
<property name="contentType" value="text/html;charset=UTF-8"/>
</bean>
I have also experienced a problem with showing UTF-8 characters (special characters like æ. ø and å etc.), when using spring framework and freemarker template.
What i did was.
1. Ensure that your .ftl page is encoded with utf-8 This is an important thing to ensure, that a page not encoded with UTF-8 charset, could show the wrong numbers even though you have all the other requirements set. Check your IDE settings, to find out which default encoding it sets your files to. I think however today that both Eclipse and NetBeans set all files with UTF-8 encoding as standard. You must ensure that it is encoding UTF-8 with no BOM.
2. Include the Meta tag in your template file to set the charset
In your template (.ftl) file, which holds your <head>
tag, set a <meta>
, with the attribute charset="UTF-8"
. This is if you use HTML 5. If you use xhtml or HTML 4, your meta tag needs to look like this
<meta charset="UTF-8" />
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
3. Make sure you set a Character Encoding Filter in your Deployment Descriptor File You have to filter all incoming/outgoing requests through a character encoding filter. This filter is set in your deployment descriptor (web.xml / or the java equivalent WebApplicationInitializer).
WebApplicationInitializer (Java File)
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
registerCharacterEncodingFilter(servletContext);
}
/**
* Filter all incoming requests with character encoding UTF-8
* @param servletContext
*/
private void registerCharacterEncodingFilter(ServletContext servletContext) {
CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
encodingFilter.setEncoding("UTF-8");
encodingFilter.setForceEncoding(true);
FilterRegistration.Dynamic characterEncodingFilter = servletContext.addFilter("characterEncodingFilter", encodingFilter);
characterEncodingFilter.addMappingForUrlPatterns(null, false, "/*");
}
web.xml
<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>
4. Set the FreeMarker Character Encoding in configurer and view resolver You also need to make all your FreeMarker files be standard encoded with UTF-8, this is done by setting their properties to UTF-8 in the FreeMarkerConfigurer and the FreeMarkerViewResolver. This is set in your spring application context file (I will only show the Java equivalent as it is the same in the XML file).
/**
* FreeMarker Configurer will help configure different settings of
* the FreeMarker template engine.
*
* @return an object of the FreeMarkerConfigurer class.
*/
@Bean
public FreeMarkerConfigurer freemarkerConfig() {
FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
freeMarkerConfigurer.setTemplateLoaderPath("/templates/");
freeMarkerConfigurer.setDefaultEncoding("UTF-8");
return freeMarkerConfigurer;
}
/**
* The View resolver to use when resolving FreeMarker views.
*
* @return the View Resolver Object used to resolve FreeMarker views.
*/
@Bean
public FreeMarkerViewResolver viewResolver() {
FreeMarkerViewResolver viewResolver = new FreeMarkerViewResolver();
viewResolver.setPrefix("");
viewResolver.setSuffix(".ftl");
viewResolver.setCache(false); //Set to true during production
viewResolver.setContentType("text/html;charset=UTF-8");
return viewResolver;
}
Hope this helps you out :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With