jackson序列化问题Type id handling not implemented for type java.util.Date

将对象保存到redis中报错

org.springframework.data.redis.serializer.SerializationException: Could not write JSON: Type id handling not implemented for type java.util.Date (by serializer of type com.zhaolaobao.redis.mode.DateToTimestamplUtil) (through reference chain: com.zhaolaobao.redis.mode.BaseEntity[“createTime”]); nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Type id handling not implemented for type java.util.Date (by serializer of type com.zhaolaobao.redis.mode.DateToTimestamplUtil) (through reference chain: com.zhaolaobao.redis.mode.BaseEntity[“createTime”])

首先问百度,我发现并没有什么暖用,还是看源码吧

at org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer.serialize(Jackson2JsonRedisSerializer.java:88)

jackson序列化问题Type id handling not implemented for type java.util.Date_第1张图片

发现实际上是this.objectMapper.writeValueAsBytes(t);报错了

然后我们一层一层点进去

第一层
com.fasterxml.jackson.databind.ObjectMapper#_configAndWriteValue

C:/Users/Dengzihua/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.9.10.4/jackson-databind-2.9.10.4-sources.jar!/com/fasterxml/jackson/databind/ObjectMapper.java:3244

第二层
com.fasterxml.jackson.databind.ser.DefaultSerializerProvider#_serialize(com.fasterxml.jackson.core.JsonGenerator, java.lang.Object, com.fasterxml.jackson.databind.JsonSerializer)

C:/Users/Dengzihua/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.9.10.4/jackson-databind-2.9.10.4-sources.jar!/com/fasterxml/jackson/databind/ser/DefaultSerializerProvider.java:319

第三层
com.fasterxml.jackson.databind.JsonSerializer#serialize

C:/Users/Dengzihua/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.9.10.4/jackson-databind-2.9.10.4-sources.jar!/com/fasterxml/jackson/databind/ser/DefaultSerializerProvider.java:480

第四层
com.fasterxml.jackson.databind.JsonSerializer#serializeWithType

C:/Users/Dengzihua/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.9.10.4/jackson-databind-2.9.10.4-sources.jar!/com/fasterxml/jackson/databind/ser/impl/TypeWrappedSerializer.java:32

第五层
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase#serializeFields

C:/Users/Dengzihua/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.9.10.4/jackson-databind-2.9.10.4-sources.jar!/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java:604

第六层
com.fasterxml.jackson.databind.ser.BeanPropertyWriter#serializeAsField

C:/Users/Dengzihua/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.9.10.4/jackson-databind-2.9.10.4-sources.jar!/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java:719

第七层
com.fasterxml.jackson.databind.JsonSerializer#serializeWithType

C:/Users/Dengzihua/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.9.10.4/jackson-databind-2.9.10.4-sources.jar!/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java:729

jackson序列化问题Type id handling not implemented for type java.util.Date_第2张图片
太多层了有木有

不过终于要到头了

jackson序列化问题Type id handling not implemented for type java.util.Date_第3张图片

serializers.reportBadDefinition(clz, String.format(
“Type id handling not implemented for type %s (by serializer of type %s)”,
clz.getName(), getClass().getName()));

进来居然是报错,心凉了半截。看似无解了。

于是我尝试重新写一个类存到redis里面

	@Test
    public void testStrin2g() {
        /*BaseEntity baseEntity = new BaseEntity(new Date(), new Date(), false);
        redisService.set("dfsdfsfsdfsdf", baseEntity);*/
        TestDate date=new TestDate(new Date());
        redisService.set("dfsdfsfsdfsdf", date);
    }
/**
 * @author TangXiang
 * @version 2.0.2
 * @date 2020/12/17 10:51
 */
@Data
@AllArgsConstructor
public class TestDate {

    private Date date;

}

然后再依照刚才的方式debug

发现进来的是不同的地方

	@Override
    public void serializeWithType(T value, JsonGenerator g, SerializerProvider provider,
            TypeSerializer typeSer) throws IOException
    {
        // NOTE: need not really be string; just indicates "scalar of some kind"
        WritableTypeId typeIdDef = typeSer.writeTypePrefix(g,
                typeSer.typeId(value, JsonToken.VALUE_STRING));
        serialize(value, g, provider);
        typeSer.writeTypeSuffix(g, typeIdDef);
    }

不使用自定义的序列化,Date类型使用的是
com.fasterxml.jackson.databind.ser.std.StdScalarSerializer#serializeWithType

ser类型是com.fasterxml.jackson.databind.ser.std.DateSerializer

public class DateSerializer
    extends DateTimeSerializerBase<Date>
public abstract class DateTimeSerializerBase<T>
    extends StdScalarSerializer<T>
    implements ContextualSerializer

所以ser使用的是父类StdScalarSerializer的serializeWithType方法

使用自定义序列化,Date类型使用的是
com.fasterxml.jackson.databind.JsonSerializer#serializeWithType

于是我们就可以做点坏事了

重写serializeWithType方法

package com.zhaolaobao.redis.mode;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.type.WritableTypeId;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.data.redis.serializer.SerializationUtils;
import org.springframework.lang.Nullable;

import java.io.IOException;
import java.util.Date;

/**
 * @Author qiuxinyao
 * @Description //TODO
 * @Date 16:08 2020/8/27
 * @Param
 * @return
 **/
public class DateToTimestamplUtil extends JsonSerializer<Object> {

    @Override
    public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        if (value != null) {
            Date date = translateToDate(value);
            jsonGenerator.writeNumber(date.getTime());
        }
    }
    /**
     * 将Object对象转成Date对象
     * @param object
     * @return
     */
    public static Date translateToDate(Object object){
        Date date;
        if(object instanceof Date){
            date=(Date)object;
        }else {
            date = new Date();
        }
        return date;
    }
    
    @Override
    public void serializeWithType(Object value, JsonGenerator g, SerializerProvider provider,
                                  TypeSerializer typeSer) throws IOException
    {
        // NOTE: need not really be string; just indicates "scalar of some kind"
        WritableTypeId typeIdDef = typeSer.writeTypePrefix(g,
                typeSer.typeId(value, JsonToken.VALUE_STRING));
        serialize(value, g, provider);
        typeSer.writeTypeSuffix(g, typeIdDef);
    }
}

我们再进行测试

在这里插入图片描述

没有报错了

以后再遇到这种问题的时候记得重写父类的方法哦

你可能感兴趣的:(java,redis,问题,redis,java)