springboot处理乱码问题原理

我们在用spring-springmvc时,需要配置一个过滤器 CharacterEncodingFilter

CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding("utf-8");
filter.setForceRequestEncoding(true); //是否对请求对象进行编码过来
filter.setForceResponseEncoding(true); //是否对响应对象做过滤

在springboot中,由于自动装配机制,不需要我们手动配置了,HttpEncodingAutoConfiguration

 

@Configuration
@EnableConfigurationProperties(HttpProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {

    private final HttpProperties.Encoding properties;

    public HttpEncodingAutoConfiguration(HttpProperties properties) {
        this.properties = properties.getEncoding();
    }

    @Bean
    @ConditionalOnMissingBean
    public CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
        filter.setEncoding(this.properties.getCharset().name());
        filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
        filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
        return filter;
    }
}

由此可见,是否进行编码过滤,都是通过 HttpProperties.Encoding properties进行判断的:

@ConfigurationProperties(prefix = "spring.http")
public class HttpProperties {/**
     * HTTP encoding properties.
     */
    private final Encoding encoding = new Encoding();
/**
     * Configuration properties for http encoding.
     */
    public static class Encoding {

        public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;

        /**
         * Charset of HTTP requests and responses. Added to the "Content-Type" header if
         * not set explicitly.
         */
        private Charset charset = DEFAULT_CHARSET;

        /**
         * Whether to force the encoding to the configured charset on HTTP requests and
         * responses.
         */
        private Boolean force;  //如果这个属性为true就会对请求和响应都进行utft-8编码过滤

        /**
         * Whether to force the encoding to the configured charset on HTTP requests.
         * Defaults to true when "force" has not been specified.
         */
        private Boolean forceRequest; //是否对请求进行过滤

        /**
         * Whether to force the encoding to the configured charset on HTTP responses.
         */
        private Boolean forceResponse; //是否对响应进行过滤

       
    //这个是判断请求或者响应是否要过滤的代码
        public boolean shouldForce(Type type) {
       //根据类型来取配置的请求过滤还是响应过滤  Boolean force
= (type != Type.REQUEST) ? this.forceResponse : this.forceRequest;
       //如果没配置,就判断 this.force的值,因为该值对请求和响应都生效
if (force == null) { force = this.force; }
       //如果还是没配置,那么默认,请求就会进行过滤 
if (force == null) { force = (type == Type.REQUEST); } return force; } public enum Type { REQUEST, RESPONSE } } }

通过上面 shouldForce(Type type)方法可以知道,在没有相关配置时,默认只会对请求进行过滤,所以要想对响应也进行过滤,需要在yml中进行配置:

spring:
http:
encoding:
charset: UTF-8
force: true

 

 

 

 

 

 

 

 


posted @ 2023-02-28 10:49  yangxiaohui227  阅读(85)  评论(0编辑  收藏  举报