开始接触使用springmvc的时候, 返回controller 内容中文乱码。html
百度一下,而后配置 messageConverters 加上 java
<bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8"/> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>text/plain; charset=UTF-8</value> </list> </property> </bean>
即解决了中文乱码。web
假设咱们不加上 json 数据的消息处理spring
好比 json
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" >
那么 若是 controller 返回 对象或者json 对象确定会报错:HttpMediaTypeNotAcceptableException: Could not find acceptable representationmvc
由于 没有 对应消息处理器 处理该返回值,MediaType 类型返回的 contenType 类型确定是 application/jsonapp
StringHttpMessageConverter 处理返回的 contenType 是 text 或者 plain 编码
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:126) at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:90) at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:189) at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:69) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
在 messageConverters 加上 <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" > debug
便可解决了,也就是 controller 能够直接 返回对象 了。日志
就是这样解决了问题。其实不太明白这样配置的意思。
解惑
StringHttpMessageConverter
StringHttpMessageConverter 只能对 controller 的 返回 string 类型的内容进行 处理,
若是是其余的对象, 甚至是 controller 返回的 int 类型, spirngmvc 也不会使用 StringHttpMessageConverter 对返回的内容进行处理的。
会将 StringHttpMessageConverter 忽略掉,若是没有 消息处理器对这个返回结果进行处理,那么就会 抛出 :
HttpMediaTypeNotAcceptableException: Could not find acceptable representation 异常
那么为何 不配置 StringHttpMessageConverter 会致使中文乱码?
由于 查看一下 StringHttpMessageConverter 源码能够知道, StringHttpMessageConverter 默认的编码
public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
使用了这个,若是不配置指定 ISO-8859-1 确定中文乱码了。
而 StringHttpMessageConverter 有一个 构造方法,容许指定 编码
所以
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
便可 解决中文乱码。
即supportedMediaTypes 配置不指定 编码也是不会中文乱码的
<bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8"/> <property name="supportedMediaTypes"> <list> <value>text/plain</value> <value>text/html</value> </list> </property> </bean>
若是 这样配置访问 controller 返回string 类型的 方法
就能够经过 debug 日志看到 例如 :
RequestResponseBodyMethodProcessor.writeWithMessageConverters(150) | Written [{"a":"aa哈哈"}] as "text/html" using [org.springframework.http.converter.StringHttpMessageConverter@20c2
而 这时候
这时候的响应给客户端的响应头 Content-Type 确定是
Content-Type:text/html;charset=UTF-8
也就是说
supportedMediaTypes 配置的是 StringHttpMessageConverter 响应给客户端的 Content-Type 内容。
这个 StringHttpMessageConverter 源码里面,默认的 supportedMediaTypes 就是 text和 plain
即 <value>text/html</value>
<value>text/plain</value>
其实 这个 supportedMediaTypes 咱们能够配置不少种类型的
好比 配置 <value>application/json;charset=UTF-8</value>
springmvc 将 尽可能 根据内容 尽可能使用 对应的 ,正确的 Content-Type
好比 只配置了 <value>application/json;charset=UTF-8</value>
那么 Content-Type 就是 application/json;charset=UTF-8
是不会 报错的。
第二 种解决中文乱码
StringHttpMessageConverter 配置 构造方法没有指定 字符集而是 supportedMediaTypes 指定字符集
<property name="supportedMediaTypes"> <list> <value>text/plain; charset=UTF-8</value> <value>text/html; charset=UTF-8</value> </list> </property>
那么 StringHttpMessageConverter 就会根据 supportedMediaTypes 里面的 charset 来使用 响应的字符集,
也就是 这样也是能够防止乱码的。
第三 返回json 对象或者对象不乱码?
好比配置了
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" >
</bean>
也就是 说将使用其处理 全部的类型,
假如没有配置 StringHttpMessageConverter
那么 string类型的返回controller 方法 最终也是会使用 MappingJacksonHttpMessageConverter 进行处理的,
只是 contentype 将是 application/json;charset=UTF-8
若是配置 StringHttpMessageConverter 了,那么string类型的 返回方法将使用 StringHttpMessageConverter 来处理,
从 名字就能够看出来了。
MappingJacksonHttpMessageConverter 处理过的 响应头部都是 application/json;charset=UTF-8
由于
MappingJacksonHttpMessageConverter 源码默认指定了 默认字符集 UTF-8因此咱们配置的时候不须要指定 字符集了,不会乱码的