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