简体   繁体   中英

Spring Boot UTF-8 encoding issue. I suspect it tries to encode ISO-8859-1 to UTF-8

I'd like to use UTF-8 character encoding but I read somewhere that the controller's default encoding's ISO-8859-1.

I'm using spring boot with velocity.

So what I did, I tried to add the following ones (one at a time) to the header (None of them worked.)

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

Plus added to the application.properties the following lines:

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

I even tried to add the following line to the controller:

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

Plus tried to add the following bean to the application class:

 @Bean
    public HttpMessageConverter<String> responseBodyConverter() {
        HttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
        return converter;
    }

This's a sample text that I included in the velocity template:

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.

And that's the output I get:

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.

Edit:

This's the controller I'm using currently:

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

And I have a homepage.vm file at templates. Which has a header partial that contains this line:

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

可能是由于默认的 Eclipse 编码?

Window -> Preferences -> General -> Workspace : Text file encoding

To resolve same problem, I have used VelocityConfigurer with the following bean definition:

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

Please note the property set in viewResolver.属性。 When first tried providing it via VelocityEngineFactoryBean, I have realised late that my properties file was ignored.

Also, in velocity.properties make sure you have:

input.encoding=utf-8
output.encoding=utf-8

I didn't need anything else in here for simple case.

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

That was it, I had no use for "produces" attribute in controller, no http meta needed, no xml charset encoding specified in the template file and no messing with messageconverter.

EDIT:

I don't have a playground setup with Spring Boot so can't test the exact implementation for you right now. However, web.xml here only defines a filter which can also be achieved programatically with 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() {}

}

I believe Spring Boot scans the sources for @Component automatically, otherwise package with filter's implementation should be added to component scan.

As for ideas on what the filter should do within doFilter(), you could explore the source code of Spring's CharacterEncodingFilter: https://github.com/spring-projects/spring-framework/blob/v4.2.1.RELEASE/spring-web/src/main/java/org/springframework/web/filter/CharacterEncodingFilter.java Note that the above filter already extends other classes (such as OncePerRequestFilter).

I suppose you could instead add a method returning the filter instance:

@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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM