欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SPRING3.X JSON 406 和 中文乱码问题

程序员文章站 2022-05-25 13:00:53
...

简要

最近使用Spring3.2.3 版本  在使用 JSON message  convertion 的时候,老是出现406 返回类型不匹配的问题,去网上google 了一番 也没有一个明确的说法,只能自己去调试。

Maven 依赖

<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-annotations</artifactId>
	<version>2.1.0</version>
	<type>jar</type>
	<scope>compile</scope>
</dependency>
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.1.0</version>
	<type>jar</type>
	<scope>compile</scope>
</dependency>
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-core</artifactId>
	<version>2.1.0</version>
	<type>jar</type>
	<scope>compile</scope>
</dependency>


message convertor XML 配置

使用jackson2.X 版本。


<mvc:annotation-driven conversion-service="conversionService">
		<mvc:message-converters>
			<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
			</bean>
		</mvc:message-converters>
</mvc:annotation-driven>


调试过程

关键代码主要在于查找能够处理 请求要求的返回值类型的 message convertion.

/*关键类*/
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver
/*方法*/
protected <T> void writeWithMessageConverters(..)

筛选能够处理的返回值类型

List<MediaType> requestedMediaTypes = getAcceptableMediaTypes(servletRequest);
List<MediaType> producibleMediaTypes = getProducibleMediaTypes(servletRequest, returnValueClass);
请求的Accept-type  'application/json ...' (记忆不全了)


调试发现 producibleMediaTypes 竟然为空, 导致执行以下代码

if (compatibleMediaTypes.isEmpty()) {
			throw new HttpMediaTypeNotAcceptableException(producibleMediaTypes);
}
抛出了406 错误。


排查发现方法

getProducibleMediaTypes(..)
messageConverters 只有spring 默认的messageConvertor, 定义的JSON 转换未生效, 我就猜测是XML 配置文件出了问题

spring 默认的messageConvertor 列表

  • ByteArrayHttpMessageConverter
    converts byte arrays
    StringHttpMessageConverter
    converts strings.
    FormHttpMessageConverter
    converts form data to/from a MultiValueMap<String, String>.
    SourceHttpMessageConverter
    converts to/from a javax.xml.transform.Source.

后来检查发现 我在spring-mvc 配置文件中又配置了

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
...
</bean>

用于全局的PropertyEditor

------------------------------------------------------------------------------------------------------------------

其实这里就发生冲突了, 在 <mvc:annotation-driven /> 是包含了该配置的。 spring 其他地方也有很多这样的设计。

修改如下配置

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
	    <property name="messageConverters">
		      <list>
			      <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
			        	
			      </bean>
                            <!-- 返回Spring 乱码 主要是默认的 String Converter 编码是 ISO-8859-1 (按需要修改这里面的配置)-->
			      <bean class="org.springframework.http.converter.StringHttpMessageConverter">
						<property name="supportedMediaTypes">
							<list>
								<value>text/plain;charset=UTF-8</value>
							</list>
						</property>
						<property name="writeAcceptCharset" value="true"/>
					</bean>
		      </list>
	    </property>
	</bean>
	
	<mvc:annotation-driven/>
这样 JSON 的支持问题就解决了, string 的乱码问题也顺带解决下。

转载于:https://my.oschina.net/u/1156053/blog/161053