解决 com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.xinping.crm.platform.mybatis.DatatablesPage["data"]->java.util.ArrayList[0]->java.util.HashMap["closeTime"]->oracle.sql.TIMESTAMP["stream"])
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:59) ~[jackson-databind-2.8.2.jar:2.8.2]
这个问题搞了我好长时间,最后在网上找了好久才发现以下两个解决方案。也算是给自己留个笔记了
该problem就是 Jackson不是转换 oracle 的TimeStamp 类型,需要我们处理一下
一。最简单的解决办法就是在 mybatis从库中读取数据后,用mybatis的 resultMap 将oracle.sql.TIMESTAMP 以时间戳转换为java.util.Date类型,前台json就可以转换了
<resultMap id="BaseResultMap" type="java.util.HashMap"> <id column="id" property="id" jdbcType="INTEGER" /> <result column="ALTER_TIME" property="ALTER_TIME" javaType="java.util.Date" jdbcType="BIGINT" /> <result column="CREATE_TIME" property="CREATE_TIME" javaType="java.util.Date" jdbcType="BIGINT" /> </resultMap>
二、第二种方式是自己实现 Oracle 的 TIMESTAMP 序列化器,并将其注册在 objectMap中。
实现JsonSerializer 自定义Oracle 的TIMESTAMP序列化
package com.***.***.common.util; import java.io.IOException; import java.sql.SQLException; import java.sql.Timestamp; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.stereotype.Component; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import oracle.sql.TIMESTAMP; @Component public class OracleTimestampSerializer extends JsonSerializer<TIMESTAMP> { @Override public void serialize(TIMESTAMP value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { Timestamp tt = null; try { tt = value.timestampValue(); Date date = new Date(tt.getTime()); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); gen.writeString(dateFormat.format(date)); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
1 package com.***.***.common.model; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.Reader; 7 import java.lang.reflect.AnnotatedElement; 8 import java.sql.Clob; 9 import java.sql.ResultSet; 10 import java.sql.ResultSetMetaData; 11 import java.sql.SQLException; 12 import java.text.SimpleDateFormat; 13 import java.util.Date; 14 15 import oracle.sql.TIMESTAMP; 16 17 import org.springframework.format.annotation.DateTimeFormat; 18 import org.springframework.stereotype.Component; 19 20 import com.***.***.common.util.ByteArrayInputStreamSerializer; 21 import com.***.***.common.util.OracleTimestampSerializer; 22 import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; 23 import com.fasterxml.jackson.annotation.PropertyAccessor; 24 import com.fasterxml.jackson.core.JsonGenerator; 25 import com.fasterxml.jackson.core.JsonProcessingException; 26 import com.fasterxml.jackson.databind.JavaType; 27 import com.fasterxml.jackson.databind.JsonSerializer; 28 import com.fasterxml.jackson.databind.ObjectMapper; 29 import com.fasterxml.jackson.databind.SerializerProvider; 30 import com.fasterxml.jackson.databind.annotation.JsonSerialize; 31 import com.fasterxml.jackson.databind.introspect.Annotated; 32 import com.fasterxml.jackson.databind.introspect.AnnotatedMethod; 33 import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; 34 import com.fasterxml.jackson.databind.module.SimpleModule; 35 //继承 ObjectMapper 类 36 @Component 37 public class CustomObjecMapper extends ObjectMapper{ 38 //public TIMESTAMP oracleTimestamp; 39 40 private static final String DEFAULT_DATE_FORMAT="yyyy-MM-dd HH:mm:ss"; 41 public CustomObjecMapper() throws JsonProcessingException{ 42 //oracleTimestamp = new TIMESTAMP(); 43 44 SimpleModule module = new SimpleModule(); 45 module.addSerializer(ByteArrayInputStream.class, new ByteArrayInputStreamSerializer()); 46 module.addSerializer(TIMESTAMP.class, new OracleTimestampSerializer()); 47 this.registerModule(module);
Spring xml 配置
<!-- 启用spring mvc 注解 --> <context:annotation-config/> <!-- 注册handlerMapper、handlerAdapter两个映射类 --> <!-- 默认的多个注解映射的支持 --> <!-- 处理responseBody 里面日期类型 --> <mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper"> <bean class="com.***.***.common.model.CustomObjecMapper"> <property name="dateFormat"> <bean class="java.text.SimpleDateFormat"> <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" /> </bean> </property> </bean> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>