使用 Spring MVC 时如何在 Freemarker 视图中设置内容类型?

Posted

技术标签:

【中文标题】使用 Spring MVC 时如何在 Freemarker 视图中设置内容类型?【英文标题】:How to set content-type in Freemarker views when using Spring MVC? 【发布时间】:2011-11-10 06:00:48 【问题描述】:

我正在使用带有 freemarker 视图的 Sping MVC。我设置了一个 FreeMarkerViewResolver 来解析视图,到目前为止它可以工作,但现在我遇到了编码问题。我所有的视图都是 UTF-8 编码的 html 5 页面,我还在 HTML 页面中添加了 <meta charset="UTF-8" />,但字符仍然以错误的编码打印。我用 curl 检查了 HTTP 标头,发现:

k@jules:~$ curl -I http://localhost:8080/testweb/test.view
HTTP/1.1 200 OK
Content-Type: */*;charset=ISO-8859-1

但是当我请求一些不存在的资源(这会产生 Tomcat 错误)时,我会得到这个:

k@jules:~$ curl -I http://localhost:8080/testweb/nothere.html
HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8

所以 Tomcat 本身会返回正确的内容类型,但 Spring MVC Freemarker 视图不会。

对于 JSP,我可以在 JSP 标头中设置 Content-Type,但是在哪里可以为 freemarker 模板设置呢?我想我必须在 Spring bean 配置中的某个地方执行此操作,但我找不到正确的位置。

【问题讨论】:

【参考方案1】:

视图解析器(应该在您的 dispatcher-servlet.xml 中)有一个 contentType 属性:

<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>

【讨论】:

【参考方案2】:

在使用 spring 框架和 freemarker 模板时,我也遇到了显示 UTF-8 字符(如 æ.ø 和 å 等特殊字符)的问题。

我所做的是。

1.确保您的 .ftl 页面使用 utf-8 编码 这是确保未使用 UTF-8 字符集编码的页面可能显示错误数字的重要事项,即使您设置了所有其他要求。检查您的 IDE 设置,找出它将文件设置为的默认编码。然而,我认为今天 Eclipse 和 NetBeans 都将所有文件都设置为 UTF-8 编码作为标准。您必须确保它是 UTF-8 编码,没有 BOM。

2。在模板文件中包含 Meta 标记以设置字符集 在包含 &lt;head&gt; 标记的模板 (.ftl) 文件中,设置 &lt;meta&gt;,其属性为 charset="UTF-8"。这是如果您使用 HTML 5。如果您使用 xhtml 或 HTML 4,您的元标记需要看起来像这样

HTML 5 &lt;meta charset="UTF-8" /&gt; HTML 4/XHTML &lt;meta http-equiv="content-type" content="text/html; charset=utf-8"/&gt;

3.确保在部署描述符文件中设置字符编码过滤器 您必须通过字符编码过滤器过滤所有传入/传出请求。此过滤器在您的部署描述符中设置(web.xml / 或 java 等效的 WebApplicationInitializer)。

WebApplicationInitializer(Java 文件)

@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.在配置器中设置 FreeMarker 字符编码并查看解析器 您还需要使所有 FreeMarker 文件都使用 UTF-8 进行标准编码,这是通过在 FreeMarkerConfigurer 和 FreeMarkerViewResolver 中将它们的属性设置为 UTF-8 来完成的。这是在您的 spring 应用程序上下文文件中设置的(我将只显示 Java 等效项,因为它在 XML 文件中是相同的)。

/**
 * 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;

希望对你有所帮助:)

【讨论】:

谢谢!对我来说关键的缺失部分是在 FreeMarkerViewResolver 上配置内容类型,我使用的是通过调用 ViewResolverRegistry.freeMarker() 设置的默认值。事实上,一旦我设置了这个,大多数其他编码配置都变成了多余的。

以上是关于使用 Spring MVC 时如何在 Freemarker 视图中设置内容类型?的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring MVC 中,如何在使用 @ResponseBody 时设置 mime 类型标头

spring mvc 如何配置最简洁的

如何使用角度和 Spring MVC 提供静态图像?

spring3 mvc的service如何在类中的中的怎么样使用

当使用 Spring MVC for REST 时,如何让 Jackson 漂亮地打印呈现的 JSON?

如何在 Spring MVC 中使用 AJAX 渲染视图