SpringMVC response data solutions Chinese garbled Detailed

SpringMVC response data solutions Chinese garbled Detailed

First, the Chinese garbled origin?

FIG distortion look effect, as shown below:

Here Insert Picture Description

The figure above "???" is the Chinese can not display properly, garbled up. Why will lead to Chinese garbled?

In the browser, developer tools, may be opened by F12; see response header (head response) Content-Type of property values, as shown below:

Here Insert Picture Description
SpringMVC the original default value is encoded Content-Type ISO-8859-1, and the browser generally UTF-8 encoding to render pages. So Chinese garbled occurred.

Second, how to solve the Chinese coding?

This raises several options, including the most common mistakes programs.

1. (Program Error) modifying the response header is Content-Type of the Controller "text / html; charset = utf -8". As shown below:

Here Insert Picture Description
After modification, the garbage problem is not resolved; mainly because of internal SpringMVC calls MessageConverter converter set your encoding to cover the default encoding. Covering general process: When used in the controller in return, will trigger returnValueHandlers method, the following source code:

/**
*类RequestMappingHandlerAdapter中295-303行
**/
public void setReturnValueHandlers(@Nullable List<HandlerMethodReturnValueHandler> returnValueHandlers) {
		if (returnValueHandlers == null) {
			this.returnValueHandlers = null;
		}
		else {
			this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite();
			this.returnValueHandlers.addHandlers(returnValueHandlers);
		}
	}

Above source shows that, when a non-null return will trigger addHandlers HandlerMethodReturnValueHandlerComposite class. We will not go in the other classes, continue to analyze the constructor of the class RequestMappingHandlerAdapter. Source as follows:

/**
*类RequestMappingHandlerAdapter中195-209行
**/
public RequestMappingHandlerAdapter() {
		StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
		stringHttpMessageConverter.setWriteAcceptCharset(false);  // see SPR-7316

		this.messageConverters = new ArrayList<>(4);
		this.messageConverters.add(new ByteArrayHttpMessageConverter());
		this.messageConverters.add(stringHttpMessageConverter);
		try {
			this.messageConverters.add(new SourceHttpMessageConverter<>());
		}
		catch (Error err) {
			// Ignore when no TransformerFactory implementation is available
		}
		this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
	}

This code can be seen initialize class StringHttpMessageConverter, and the default value of the Content-Type of the encoding. The default setting in the class StringHttpMessageConverter. As shown Source:
Here Insert Picture Description

Summary: So disposed directly in response Controller Content-Type header is useless, because they will be coded to a default value MessageConverter coverage;

2. Add produces = "text / html; charset = utf-8" in the Controller @RequestMapping annotations. Code as follows:
@RequestMapping(value = "test",produces = "text/html;charset=utf-8")
    public String testUser(HttpServletRequest req, HttpServletResponse res){
//        res.setContentType("text/html;charset=utf-8");
        long time=System.currentTimeMillis();
        return String.format("<div><h2>测试成功。</h2><p>System.currentTimeMillis:%s</p></div>",time);
    }

To achieve results as shown below:

Here Insert Picture Description

Through the above settings, you can see the Chinese garbled does not exist. The problem is solved, but not every Controller gave it such a setting, if replaced by other coding it, it changed a lot of trouble.

3. custom class to implement the interface BeanPostProcessor, and override interface method postProcessBeforeInitialization, postProcessAfterInitialization; custom class then fitted into the container through the IOC bean tag. Source as follows:
//自定义类DefineCharSet
package com.comm;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.http.MediaType;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.lang.Nullable;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

public class DefineCharSet implements BeanPostProcessor {
    //实例化之前调用
    @Nullable
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
    //实例化之后调用
    @Nullable
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(bean instanceof StringHttpMessageConverter){
            MediaType mediaType = new MediaType("text", "html", Charset.forName("UTF-8"));
            List<MediaType> types = new ArrayList<MediaType>();
            types.add(mediaType);
            ((StringHttpMessageConverter) bean).setSupportedMediaTypes(types);
        }
        return bean;
    }
}
<!--装配自定义类DefineCharSet-->
<bean class="com.comm.DefineCharSet"/>

OK, now everything is all right, no longer have to solve the garbage by 2 ways.

Guess you like

Origin blog.csdn.net/u012475786/article/details/89501318