How to solve the Chinese garbled code transmitted by springboot parameters

Posted by bibby on Thu, 03 Feb 2022 01:41:35 +0100

How to solve the Chinese garbled code transmitted by springboot parameters

preface

This case comes from a business scenario of a business department. Their business scenario is that their department has developed a microservice context transparent component, and its transparent principle is also very simple. That is, the request parameters are inserted into threadlocal through springboot interceptor, and then the downstream values are obtained through threadlocal. When feign calls are made between services, the threadlocal parameters are inserted into the header. This component has been used well all the time. Suddenly one day, because the parameter value passed is Chinese, it leads to garbled code. They can't solve it by trying the following solutions. Finally, let our department investigate and deal with it.

Implementation ideas of business department

Their initial thinking direction was that the inconsistent parameter coding led to Chinese garbled code. So they worked hard in this direction and came up with the following plan

Scheme I:

String value = new String("I am Chinese garbled".getBytes("ISO-8859-1"),"UTF-8");

This is one of the common methods to solve the Chinese garbled string

Scheme 2: write character coding filter

@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() {
    }
}

Then add @ ServletComponentScan to the startup class@ WebFilter is servlet3 0. Of course, you can also write this filter

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() {
    }
}

Write a bean configuration class as follows

@Bean
    public FilterRegistrationBean registerAuthFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new CharacterEncodingFilter();
        registration.addUrlPatterns("/*");
        registration.setName("CharacterEncodingFilter");
        registration.setOrder(1); 
        return registration;
    }

Scheme 3: in application YML specifies the encoding format as utf-8

spring:
  http:
    encoding:
      charset: utf-8
      enabled: true
      force: true

server:
  tomcat:
    uri-encoding: UTF-8

Scheme 4: write a StringHttpMessageConverter

Baidu basically looks like this. However, in the spring 5 version, the WebMvcConfigurerAdapter class is outdated. The alternative is to implement the WebMvcConfigurer interface or inherit WebMvcConfigurationSupport. However, if WebMvcConfigurationSupport is used, the mvc automatic assembly of springboot will be invalidated. The reason for the failure is

Expand a little knowledge and @ EnableWebMvc will also fail the mvc automatic assembly of springboot. The reason is

org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration this configuration class inherits WebMvcConfigurationSupport

The introduction of so many schemes did not solve the problem of following the example. What's the problem? As mentioned in the previous case, when feign is called, the parameters of threadlocal will be inserted into the header. Here is the real problem of garbled code. The header does not support Chinese transmission. If you insist on transmission, basically the receiver receives it??? This seemingly garbled symbol

Key to solving problems

When inserting the value of threadlocal into the header, first encode the URLEncoder, as shown in

URLEncoder.encode("I am "Chinese garbled","UTF-8")

When receiving the header parameter, do the following URLDecoder Decode as follows

URLDecoder.decode(header Parameter value to be decoded in, "UTF-8")

summary

The direction is wrong. No matter how hard you try, it seems useless, but at least you may harvest other unexpected things

Topics: Java Spring Boot Back-end