Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set content-type in Freemarker views when using Spring MVC?

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.

like image 848
kayahr Avatar asked Sep 04 '11 20:09

kayahr


2 Answers

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>
like image 114
Bozho Avatar answered Nov 10 '22 10:11

Bozho


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

  • HTML 5 <meta charset="UTF-8" />
  • HTML 4/XHTML <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 :)

like image 29
Rohwedder Avatar answered Nov 10 '22 09:11

Rohwedder