springboot全局字符编码设置(解决乱码问题)

1,397 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第27天,点击查看活动详情

有时候我们会发现这种问题,明明已经设置了字符编码过滤器但是还会有乱码的情况出现,这个问题令我们很是头疼,我之前也遇到过这种情况。那怎么解决呢?

springboot编码格式设置有三种方式,不管使用哪种方式,总有一款适合你。

  1. 在application.properties中设置

1.1 springboot 1.x

springboot 1.x中配置文件:

#编码格式
spring.http.encoding.force=true
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true

如果出现乱码问题,这种方式解决的可能性不大,但可以尝试一下,希望还是要有的,万一解决了呢,因为查看源码发现springboot默认的编码格式就是UTF-8

1.2 springboot 2.x

spring.http.encoding.charset 被替换成server.tomcat.uri-encoding

{
  "name": "spring.http.encoding.charset",
  "type": "java.nio.charset.Charset",
  "description": "Charset of HTTP requests and responses. Added to the Content-Type header if not set explicitly.",
  "deprecated": true,
  "deprecation": {
    "level": "error",
    "replacement": "server.servlet.encoding.charset"
  }
}

所以,springboot 2.x中要配置:

server.tomcat.uri-encoding=UTF-8
  1. 自己手写编码过滤器
//字符编码过滤器
@WebFilter(urlPatterns = "/*",filterName = "CharacterEncodingFilter")
public class CharacterEncodingFilter implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");

        filterChain.doFilter(request , response);
    }
    @Override
    public void destroy() {
    }
}

如果这种方式也解决不了问题的话,只能使用最后一种方式了。

  1. 使用java配置写一个字符编码配置类
/**
 * 中文乱码解决
 */
@Configuration
public class CharsetConfig extends WebMvcConfigurerAdapter {
    @Bean
    public HttpMessageConverter<String> responseBodyConverter() {
        StringHttpMessageConverter converter = new StringHttpMessageConverter(
                Charset.forName("UTF-8"));
        return converter;
    }
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        converters.add(responseBodyConverter());
    }
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false);
    }
}

StringHttpMessageConverter是一个请求和响应信息的编码转换器,通过源码我们发现默认编码ISO-8859-1,不是UTF-8,所以我们只要通过上述配置将请求字符串转为UTF-8 即可

/**
 * Implementation of {@link HttpMessageConverter} that can read and write strings.
 *
 * <p>By default, this converter supports all media types (<code>&#42;/&#42;</code>),
 * and writes with a {@code Content-Type} of {@code text/plain}. This can be overridden
 * by setting the {@link #setSupportedMediaTypes supportedMediaTypes} property.
 *
 * @author Arjen Poutsma
 * @author Juergen Hoeller
 * @since 3.0
 */
=
public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {

   private static final MediaType APPLICATION_PLUS_JSON = new MediaType("application", "*+json");

   /**
    * The default charset used by the converter.
    */
   public static final Charset DEFAULT_CHARSET = StandardCharsets.ISO_8859_1;
 }

WebMvcConfigurerAdapter 是springmvc的一个配置支配器类,不过在springboot 2.x中已经被废弃。

在springboot 2.x 中配置如下:

@Configuration
public class IWebMvcConfigurer implements WebMvcConfigurer {

    @Bean
    public HttpMessageConverter<String> responseBodyConverter() {
        StringHttpMessageConverter converter = new StringHttpMessageConverter(
                Charset.forName("UTF-8"));
        return converter;
    }
    
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(responseBodyConverter());
    }
}

其实现的接口WebMvcConfigurer 定义了一些回调方法为springmvc提供一个通道通过java基本的配置。