Spring to solve the Chinese garble problem, is the CharacterEncodingFilter through the interceptor to solve the problem we take a look at this interceptor source.

public class CharacterEncodingFilter extends OncePerRequestFilter {    
    // Encoding format
    @Nullable
    private String encoding;
    // Whether the request parameter uses the encoding set by the encoding property
    private boolean forceRequestEncoding;
    // Returns whether the argument uses the encoding set by the encoding property
    private boolean forceResponseEncoding; 

    // The method to be executed in the filter
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String encoding = this.getEncoding();
        if(encoding ! =null) {
        // Set the encoding format of the request parameters
            if (this.isForceRequestEncoding() || request.getCharacterEncoding() == null) {
                request.setCharacterEncoding(encoding);
            }
       // Set the encoding format of the returned parameter
            if (this.isForceResponseEncoding()) { response.setCharacterEncoding(encoding); } } filterChain.doFilter(request, response); }}Copy the code

Encoding does not have a default value, so it is necessary to specify the encoding (utF-8) for springMvc. The springMvc project filter needs to be configured in web.xml

<filter>
  <filter-name>encodingFilter</filter-name>Spring's built-in filter <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
    <param-name>encoding</param-name> The format of the parameter isutf8"param-value>UTF8</param-value>
  </init-param>
  <init-param>
    <param-name>forceEncoding</param-nameBoth the request and return parameters use the encoding set above.param-value>true</param-value>
  </init-param>
</filter>
Copy the code

For those of you who may be surprised to see this, the CharacterEncodingFilter does not have the forceEncoding attribute. Haha, I was also confused at first, how can this set up. It turns out that the CharacterEncodingFilter has the following two constructors

// It is clear that the configuration in web.xml uses this constructor to assign values to three attributes
    public CharacterEncodingFilter(String encoding, boolean forceEncoding) {
        this(encoding, forceEncoding, forceEncoding);
    }

    public CharacterEncodingFilter(String encoding, boolean forceRequestEncoding, boolean forceResponseEncoding) {
        this.forceRequestEncoding = false;
        this.forceResponseEncoding = false;
        Assert.hasLength(encoding, "Encoding must not be empty");
        this.encoding = encoding;
        this.forceRequestEncoding = forceRequestEncoding;
        this.forceResponseEncoding = forceResponseEncoding;
    }
Copy the code

Let’s look at how to solve the problem of Chinese garbled parameters in the springBoot project. Add a configuration to your YML or Properties configuration file. Add the following configuration to the pair, for example, YML

spring:
  http:
    encoding:
      force: true
      charset: UTF-8
      enabled: true
Copy the code

As to why to add this configuration went, just be the key that we want to understand. You all know springBoot autoassembly. Many configuration classes are loaded into the IOC container when the container starts. Let’s look at the configuration class HttpEncodingAutoConfiguration

Here is the simplified source code, leaving only those relevant to the coding problem

// indicates that this is a configuration class that can add components to the container just like the configuration files we wrote before
@Configuration(proxyBeanMethods = false)

// Enable ConfigurationProperties for the specified class; Map corresponding values in the configuration file to attributes in HttpProperties
@EnableConfigurationProperties(HttpProperties.class)


// Check whether the current project has this CharacterEncodingFilter: SpringMVC garble resolution filter
@ConditionalOnClass(CharacterEncodingFilter.class)

public class HttpEncodingAutoConfiguration {

	// It has been mapped to the values in the SpringBoot configuration file
	private final HttpProperties.Encoding properties;

	// If there is only one parameter constructor, the value of the parameter is taken from the container
	public HttpEncodingAutoConfiguration(HttpProperties properties) {
		this.properties = properties.getEncoding();
	}

	@Bean  // Add a component to the container. Some of the values in this component need to be retrieved from properties
	@ConditionalOnMissingBean  // Check that the component does not exist in the container
	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));
		returnfilter; }}Copy the code

@ EnableConfigurationProperties annotations, attribute values, in the configuration file will be mapped to HttpProperties class As for the comments of how to realize these functions, temporarily do not do research

The HttpProperties code is as follows

@ConfigurationProperties(prefix = "spring.http")
public class HttpProperties {

	private boolean logRequestDetails;
	
	private final Encoding encoding = new Encoding();

	public boolean isLogRequestDetails() {
		return this.logRequestDetails;
	}

	public void setLogRequestDetails(boolean logRequestDetails) {
		this.logRequestDetails = logRequestDetails;
	}

	public Encoding getEncoding() {
		return this.encoding;
	}

	/** * Configuration properties for http encoding. */
	public static class Encoding {

		public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
		private Charset charset = DEFAULT_CHARSET;
		private Boolean force;
		private Boolean forceRequest;
		private Boolean forceResponse;
		private Map<Locale, Charset> mapping;

		public boolean shouldForce(Type type) {
			Booleanforce = (type ! = Type.REQUEST) ?this.forceResponse : this.forceRequest;
			if (force == null) {
				force = this.force;
			}
			if (force == null) {
				force = (type == Type.REQUEST);
			}
			return force;
		}

		public enum Type {

			REQUEST, RESPONSE

		}

	}

Copy the code

Looking at the properties in HttpProperties, you should see that these are the same properties we configured in the configuration file. And the default is UTF-8. After assigning values to these attributes, see how they relate to the CharacterEncodingFilter.

Here’s a way to find out

This method in HttpEncodingAutoConfiguration on CharacterEncodingFilter instantiation

This. properties is httpproperties.encoding. ShouldForce is one of those methods. The code is up here

	@Bean  // Add a component to the container. Some of the values in this component need to be retrieved from properties
	@ConditionalOnMissingBean  // Check that the component does not exist in the container
	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;
	}
Copy the code

Ok, this configuration will not be too confusing, I wonder why this configuration