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