81,092
社区成员
发帖
与我相关
我的任务
分享
public ObjectMapper setSerializationInclusion(JsonInclude.Include incl) {
_serializationConfig = _serializationConfig.withSerializationInclusion(incl);
return this;
}
<property name="serializationInclusion">
<!-- 注入枚举类型 -->
<value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value>
</property>
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="cacheSeconds" value="0" />
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<!-- <bean class="com.threeStepTech.ObjectMapper.CustomObjectMapper"/> -->
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
</bean>
</property>
<property name="serializationInclusion">
<!-- 注入枚举类型 -->
<value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value>
</property>
</bean>
</property>
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
public class CustomObjectMapper extends ObjectMapper {
private static final long serialVersionUID = 3072523733092288622L;
public CustomObjectMapper() {
super.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
super.getSerializationConfig().withSerializationInclusion(
JsonInclude.Include.NON_NULL);
}
}
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
at [Source: java.io.PushbackInputStream@3976ebfa; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:835)
at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:59)
at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:12)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3562)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2662)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:205)
... 54 more
感觉应该和那个过滤null值属性Inclusion.NON_NULL的有关.
我把我的整个配置贴上来吧.. 不多.
<context:component-scan base-package="com.threeStepTech"/>
<!-- 资源过滤 -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean id="jacksonObjectMapper" class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
</bean>
</property>
<property name="serializationInclusion">
<!-- 把枚举类型转为一个bean才能注入, 不序列化空值属性 -->
<!-- <value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value> -->
<util:constant static-field="com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL" />
</property>
</bean>
</property>
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>image/jpeg</value>
<value>image/png</value>
<!-- <value>application/json</value> -->
</list>
</property>
</bean>
</list>
</property>
</bean>
<mvc:annotation-driven />
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxUploadSize" value="10485760"></property>
<property name="maxInMemorySize" value="40960"></property>
</bean>
<!-- 拦截器 -->
<mvc:interceptors>
<!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->
<!-- sql注入检测 -->
<bean class="com.threeStepTech.interceptor.SqlInjectInterceptor" />
<!-- token检测 -->
<bean class="com.threeStepTech.interceptor.TokenInterceptor" />
<!--
<mvc:interceptor>
<mvc:mapping path="/test/number.do" />
<!- - 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 - ->
<bean class="com.host.app.web.interceptor.LoginInterceptor" />
</mvc:interceptor>
-->
</mvc:interceptors>
<!-- 切面 : 用户行为日志 -->
<!-- <aop:aspectj-autoproxy expose-proxy="true" proxy-target-class="true"/> -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<!-- spring socket -->
<websocket:handlers>
<websocket:mapping path="/myHandler" handler="myHandler"/>
<websocket:handshake-interceptors>
<bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"/>
</websocket:handshake-interceptors>
</websocket:handlers>
<bean id="myHandler" class="com.threeStepTech.springSkOfficial.MyHandler"/>
<import resource="classpath*:/server-config/spring-apphome.xml"/>
<import resource="classpath*:/server-config/spring-memcached.xml"/>
</beans>
超级感谢..... <bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<.beans>
这样写当然可以,你的不行,是因为你把该bean定义放到<mvc:annotation-driven />之后了,<mvc:annotation-driven/>为生成一个RequestMappingHandlerAdapter的bean定义,只要把你的定义放到之前就可以了,注入时取先定义的。
这样写和mvc:message-converters的区别是:
mvc:message-converters只会预先添加RequestMappingHandlerAdapter类属性messageConverters,而不会直接覆盖RequestMappingHandlerAdapter类。
代码见org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser.getMessageConverters(Element, Object, ParserContext):
private ManagedList<?> getMessageConverters(Element element, Object source, ParserContext parserContext) {
//这里就是配置的bean,注意是放到前面的,因为解析时从前到后的
Element convertersElement = DomUtils.getChildElementByTagName(element, "message-converters");
ManagedList<? super Object> messageConverters = new ManagedList<Object>();
if (convertersElement != null) {
messageConverters.setSource(source);
for (Element beanElement : DomUtils.getChildElementsByTagName(convertersElement, "bean", "ref")) {
Object object = parserContext.getDelegate().parsePropertySubElement(beanElement, null);
messageConverters.add(object);
}
}
//这里是默认的return valuehandler
if (convertersElement == null || Boolean.valueOf(convertersElement.getAttribute("register-defaults"))) {
messageConverters.setSource(source);
messageConverters.add(createConverterDefinition(ByteArrayHttpMessageConverter.class, source));
RootBeanDefinition stringConverterDef = createConverterDefinition(StringHttpMessageConverter.class, source);
stringConverterDef.getPropertyValues().add("writeAcceptCharset", false);
messageConverters.add(stringConverterDef);
messageConverters.add(createConverterDefinition(ResourceHttpMessageConverter.class, source));
messageConverters.add(createConverterDefinition(SourceHttpMessageConverter.class, source));
messageConverters.add(createConverterDefinition(AllEncompassingFormHttpMessageConverter.class, source));
if (romePresent) {
messageConverters.add(createConverterDefinition(AtomFeedHttpMessageConverter.class, source));
messageConverters.add(createConverterDefinition(RssChannelHttpMessageConverter.class, source));
}
if (jackson2XmlPresent) {
RootBeanDefinition jacksonConverterDef = createConverterDefinition(MappingJackson2XmlHttpMessageConverter.class, source);
GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
jacksonFactoryDef.getPropertyValues().add("createXmlMapper", true);
jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef);
messageConverters.add(jacksonConverterDef);
}
else if (jaxb2Present) {
messageConverters.add(createConverterDefinition(Jaxb2RootElementHttpMessageConverter.class, source));
}
if (jackson2Present) {
RootBeanDefinition jacksonConverterDef = createConverterDefinition(MappingJackson2HttpMessageConverter.class, source);
GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef);
messageConverters.add(jacksonConverterDef);
}
else if (gsonPresent) {
messageConverters.add(createConverterDefinition(GsonHttpMessageConverter.class, source));
}
}
return messageConverters;
}
org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser.parse(Element, ParserContext)
ManagedList<?> messageConverters = getMessageConverters(element, source, parserContext);
//这里生成了RequestMappingHandlerAdapter bean
RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(RequestMappingHandlerAdapter.class);
handlerAdapterDef.setSource(source);
handlerAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
handlerAdapterDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
handlerAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
handlerAdapterDef.getPropertyValues().add("messageConverters", messageConverters);
addRequestBodyAdvice(handlerAdapterDef);
addResponseBodyAdvice(handlerAdapterDef);
<mvc:annotation-driven>
<mvc:message-converters>
<bean
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<beans:property name="objectMapper">
<beans:bean class="org.codehaus.jackson.map.ObjectMapper">
<beans:property name="serializationInclusion">
<util:constant
static-field="org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL" />
</beans:property>
</beans:bean>
</beans:property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>