Spring Boot UTF-8编码问题。我怀疑它试图将ISO-8859-1编码为UTF-8。

3

我希望使用UTF-8字符编码,但我在某个地方读到控制器默认的编码是ISO-8859-1。

我正在使用Spring Boot和Velocity。

所以我尝试向头部添加以下内容(一次只添加一个),但没有一个有效:

<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">

在application.properties文件中添加以下行:

spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
spring.velocity.charset=UTF-8
spring.velocity.content-type=text/html

server.tomcat.uri-encoding = UTF-8

我甚至尝试在控制器中添加以下行:

@RequestMapping(value = "/", method = RequestMethod.GET, produces={"text/html; charset=UTF-8"})

Plus尝试将以下bean添加到应用程序类中:
 @Bean
    public HttpMessageConverter<String> responseBodyConverter() {
        HttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
        return converter;
    }

这里是一个样例文本,我包含在速度模板中:
A sötét lovag igazi főhőse azonban valahogy ezúttal mégsem a mostanság nőnemű családtagjait szállodaszobábkban riogató Christian Bale, azaz a denevérember lett - hanem az ellenfél.

这是我得到的输出结果:

A sötét lovag igazi fÅhÅse azonban valahogy ezúttal mégsem a mostanság nÅnemű családtagjait szállodaszobábkban riogató Christian Bale, azaz a denevérember lett - hanem az ellenfél.

编辑:

这是我目前正在使用的控制器:

@RequestMapping(value = "/", method = RequestMethod.GET, produces={"text/html; charset=UTF-8"})
    public String homepage(Map<String, Object> model) {
        return "homepage";
    }

我有一个 templates 文件夹下的 homepage.vm 文件,其中有一个包含以下代码的头部分文件:

<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">

1
你确定你用来编辑和保存模板的文本编辑器或IDE使用的是UTF8编码吗?你用什么编辑器? - JB Nizet
你尝试过使用“-Dfile.encoding=UTF-8”启动应用程序吗? - Ruben
我正在使用Intellij,并且在所有地方都使用UTF-8字符编码。该标志给了我相同的输出。我是这样启动应用程序的:mvn clean spring-boot:run -Dfile.encoding=UTF-8 - Grego
还有其他的想法吗?我真的需要一个解决方案。 - Grego
2个回答

1
可能是因为默认的Eclipse编码方式导致的吗?
Window -> Preferences -> General -> Workspace : Text file encoding

我正在使用Intellij IDEA,并且它已设置为UTF-8。 - Grego

0
为了解决同样的问题,我使用了VelocityConfigurer,并使用以下bean定义:
<bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
  <property name="resourceLoaderPath" value="/WEB-INF/pages/"/>
  <property name="configLocation" value="/WEB-INF/velocity.properties"/>
</bean>

<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
  <property name="cache" value="false"/>
  <property name="prefix" value=""/>
  <property name="suffix" value=".vm"/>
  <property name="contentType" value="text/html; charset=UTF-8"/>
</bean>

请注意在viewResolver中设置的contentType属性。当我第一次尝试通过VelocityEngineFactoryBean提供它时,我意识到我的属性文件被忽略了。
此外,在velocity.properties中确保您有:
input.encoding=utf-8
output.encoding=utf-8

对于简单的情况,我在这里不需要其他任何东西。

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

就是这样,我在控制器中没有使用“produces”属性,不需要http元数据,模板文件中也没有指定xml字符集编码,也不需要烦恼于消息转换器。

编辑:

我还没有使用Spring Boot设置游乐场,所以现在无法为您测试确切的实现。然而,这里的web.xml仅定义了一个过滤器,这也可以通过Spring Boot以编程方式实现:

import org.springframework.stereotype.Component;

import javax.servlet.*;
import java.io.IOException;

@Component
public class MyFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //action here
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void destroy() {}

}

我相信Spring Boot会自动扫描@ Component的源码,否则应将带有过滤器实现的包添加到组件扫描中。

至于关于doFilter()内部应该执行什么操作的想法,您可以探索Spring的CharacterEncodingFilter的源代码:https://github.com/spring-projects/spring-framework/blob/v4.2.1.RELEASE/spring-web/src/main/java/org/springframework/web/filter/CharacterEncodingFilter.java 请注意,上述过滤器已经扩展了其他类(例如OncePerRequestFilter)。

我认为您可以添加一个返回过滤器实例的方法:

@Bean
public Filter getCharacterEncodingFilter() {
    org.springframework.web.filter.CharacterEncodingFilter characterEncodingFilter = new org.springframework.web.filter.CharacterEncodingFilter();
    characterEncodingFilter.setEncoding("UTF-8");
    characterEncodingFilter.setForceEncoding(true);
    return characterEncodingFilter;
}

1
谢谢您的回答。不过我在使用Spring Boot,所以没有web.xml文件。我只在application.properties文件中声明东西。 - Grego
非常感谢您的帮助,但我实际上无法使其正常工作。因此,我尝试了Spring Boot的示例,并发现Freemarker和Mustache支持UTF-8开箱即用。因此,我将继续使用Freemarker。 - Grego

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接