原因:org.springframework.data.redis.serializer.SerializationException:无法反序列化;嵌套异常是 org.springframework.core.seriali

Caused by: org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; nested exception is org.springframework.core.seriali

我正在开发 Spring Boot + Spring Data Redis 示例。在此示例中,尝试使用 @EnableRedisHttpSession 并从 https://www.youtube.com/watch?v=_M8xoagybzU&t=231s 获取了代码参考。

我开发了代码,当我尝试 运行 示例时。我收到以下错误。我不知道发生了什么事?另外,我不清楚为什么错误 Caused by: java.lang.ClassNotFoundException: com.example.Order.

Caused by: org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is org.springframework.core.NestedIOException: Failed to deserialize object type; nested exception is java.lang.ClassNotFoundException: com.example.Order
    at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:84) ~[spring-data-redis-2.1.2.RELEASE.jar:2.1.2.RELEASE]
    at org.springframework.data.redis.serializer.DefaultRedisElementReader.read(DefaultRedisElementReader.java:48) ~[spring-data-redis-2.1.2.RELEASE.jar:2.1.2.RELEASE]
    at org.springframework.data.redis.serializer.RedisSerializationContext$SerializationPair.read(RedisSerializationContext.java:226) ~[spring-data-redis-2.1.2.RELEASE.jar:2.1.2.RELEASE]
    at org.springframework.data.redis.cache.RedisCache.deserializeCacheValue(RedisCache.java:254) ~[spring-data-redis-2.1.2.RELEASE.jar:2.1.2.RELEASE]
    at org.springframework.data.redis.cache.RedisCache.lookup(RedisCache.java:88) ~[spring-data-redis-2.1.2.RELEASE.jar:2.1.2.RELEASE]
    at org.springframework.cache.support.AbstractValueAdaptingCache.get(AbstractValueAdaptingCache.java:58) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.cache.interceptor.AbstractCacheInvoker.doGet(AbstractCacheInvoker.java:73) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.cache.interceptor.CacheAspectSupport.findInCaches(CacheAspectSupport.java:554) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.cache.interceptor.CacheAspectSupport.findCachedItem(CacheAspectSupport.java:519) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:401) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:345) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at com.example.service.OrderService$$EnhancerBySpringCGLIB$fc6ad4.byId(<generated>) ~[classes/:na]
    at com.example.RedisApplication.lambda(RedisApplication.java:97) [classes/:na]
    at com.example.RedisApplication.measure(RedisApplication.java:89) [classes/:na]
    at com.example.RedisApplication.lambda(RedisApplication.java:98) [classes/:na]
    at com.example.RedisApplication.lambda[=12=](RedisApplication.java:57) [classes/:na]
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:804) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    ... 5 common frames omitted
Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is org.springframework.core.NestedIOException: Failed to deserialize object type; nested exception is java.lang.ClassNotFoundException: com.example.Order
    at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:78) ~[spring-core-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:36) ~[spring-core-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:82) ~[spring-data-redis-2.1.2.RELEASE.jar:2.1.2.RELEASE]
    ... 24 common frames omitted
Caused by: org.springframework.core.NestedIOException: Failed to deserialize object type; nested exception is java.lang.ClassNotFoundException: com.example.Order
    at org.springframework.core.serializer.DefaultDeserializer.deserialize(DefaultDeserializer.java:75) ~[spring-core-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:73) ~[spring-core-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    ... 26 common frames omitted
Caused by: java.lang.ClassNotFoundException: com.example.Order
    at java.net.URLClassLoader.findClass(Unknown Source) ~[na:1.8.0_151]
    at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_151]
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) ~[na:1.8.0_151]
    at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_151]
    at java.lang.Class.forName0(Native Method) ~[na:1.8.0_151]
    at java.lang.Class.forName(Unknown Source) ~[na:1.8.0_151]
    at java.io.ObjectInputStream.resolveClass(Unknown Source) ~[na:1.8.0_151]
    at org.springframework.core.ConfigurableObjectInputStream.resolveClass(ConfigurableObjectInputStream.java:80) ~[spring-core-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) ~[na:1.8.0_151]
    at java.io.ObjectInputStream.readClassDesc(Unknown Source) ~[na:1.8.0_151]
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) ~[na:1.8.0_151]
    at java.io.ObjectInputStream.readObject0(Unknown Source) ~[na:1.8.0_151]
    at java.io.ObjectInputStream.readObject(Unknown Source) ~[na:1.8.0_151]
    at org.springframework.core.serializer.DefaultDeserializer.deserialize(DefaultDeserializer.java:72) ~[spring-core-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    ... 27 common frames omitted

ShoppingCart.java

public class ShoppingCart implements Serializable{
    private static final long serialVersionUID = 1L;

    private final Collection<Order> orders = new ArrayList<>();

    public void addOrder(Order order) {
        this.orders.add(order);
    }

    public Collection<Order> getOrders(){
        return this.orders;
    }
}

CartSessionController.java

@Log
@Controller
@SessionAttributes("cart")
public class CartSessionController {

    private final AtomicLong ids = new AtomicLong();

    @ModelAttribute("cart")
    ShoppingCart cart() {
        log.info("Creating new cart");
        return new ShoppingCart();
    }

    @GetMapping("/orders")
    String Order(@ModelAttribute("cart") ShoppingCart cart, Model model) {
        cart.addOrder(new Order(ids.incrementAndGet(), new Date(), Collections.emptyList()));
        model.addAttribute("orders", cart.getOrders());
        return "orders";
    }
}

Order.java

@Data
@AllArgsConstructor
@NoArgsConstructor
@RedisHash("orders")
public class Order implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    private Long Id;

    @Indexed
    private Date when;

    @Reference
    private List<LineItem> lineItems;
}

LineItem.java

@Data
@AllArgsConstructor
@NoArgsConstructor
@RedisHash("lineItems")
public class LineItem implements Serializable {
    private static final long serialVersionUID = 1L;

    @Indexed
    private Long orderId;

    @Id
    private Long id;

    private String description;
}

RedisApplication.java

@Log
@SpringBootApplication
@EnableRedisHttpSession
@EnableCaching
public class RedisApplication {

    private final String TOPIC = "Chat";
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private LineItemRepository lineItemRepository;
    @Autowired
    private OrderService OrderService;

    private ApplicationRunner titleRunner(String title, ApplicationRunner rr) {
        return args -> {
            log.info(title.toUpperCase() + ":");
            rr.run(args);
        };
    }

    @Bean
    ApplicationRunner geography(RedisTemplate<String, String> rt) {
        return titleRunner("geography", args -> {
            GeoOperations<String, String> geo = rt.opsForGeo();
            geo.add("Sicily", new Point(13.361389, 38.155556), "Arigento");
            geo.add("Ramesh", new Point(15.087269, 37.502669), "Catania");
            geo.add("Anup", new Point(13.583333, 37.316667), "Palermo");

            Circle circle = new Circle(new Point(13.583333, 37.316667),
                    new Distance(100, RedisGeoCommands.DistanceUnit.KILOMETERS));

            GeoResults<GeoLocation<String>> radius = geo.radius("Sicily", circle);
            radius.getContent().forEach(c -> log.info(c.toString()));
        });
    }

    public static void main(String[] args) {
        SpringApplication.run(RedisApplication.class, args);
    }

    //#####################
    @Bean
    CacheManager redisCache(RedisConnectionFactory connectionFactory) {
        return RedisCacheManager.builder(connectionFactory).build();
    }

    private long measure(Runnable r) {
        long start = System.currentTimeMillis();
        r.run();
        long stop = System.currentTimeMillis();
        return start - stop;
    }

    @Bean
    ApplicationRunner cache() {
        return titleRunner("caching", a ->{
            Runnable measure = () -> OrderService.byId(1L);
            log.info("first  "+measure(measure));
            log.info("two  "+measure(measure));
            log.info("three  "+measure(measure));
        });
    }

    //#####################


    @Bean
    ApplicationRunner repositories() {
        return titleRunner("repositories", args -> {
            Long orderId = generateId();

            List<LineItem> itemsList = Arrays.asList(
                        new LineItem(orderId, generateId(), "plunger"),
                        new LineItem(orderId, generateId(), "soup"), 
                        new LineItem(orderId, generateId(), "cofee mug"));

            itemsList.stream().map(lineItemRepository::save).forEach(li -> log.info(li.toString()));

            Order order = new Order(orderId, new Date(), itemsList);
            orderRepository.save(order);

            Collection<Order> found = orderRepository.findByWhen(order.getWhen());
            found.forEach(o -> log.info("found : " + o.toString()));
        });
    }

    private Long generateId() {
        long tmp = new Random().nextLong();
        return Math.max(tmp, tmp * -1);
    }

    @Bean
    ApplicationRunner pubSub(RedisTemplate<String, String> rt) {
        return titleRunner("publish/subscribe", args ->{
            rt.convertAndSend(TOPIC, "Hello World @ "+Instant.now().toString());
        });
    }

    @Bean
    RedisMessageListenerContainer listener(RedisConnectionFactory rcf) {
        MessageListener ml = (message, pattern) -> {
            String str = new String(message.getBody());
            log.info("message from ' " + TOPIC + "':'" + str);
        };

        RedisMessageListenerContainer mlc = new RedisMessageListenerContainer();
        mlc.setConnectionFactory(rcf);
        mlc.addMessageListener(ml, new PatternTopic(TOPIC));
        return mlc;
    }
}

我按照 @Arnaud 的建议使用 >FLUSHALL 刷新了 Redis 数据库,然后它工作正常。即使是现在,我也可以看到 SessionAttributesSessionExpire 等的详细信息都保存在缓存中。

127.0.0.1:6379> KEYS *
 1) "lineItems:3544713235909729939:idx"
 2) "order-by-id::1"
 3) "lineItems:orderId:4510658827505526003"
 4) "Sicily"
 5) "spring:session:expirations:1541668980000"
 6) "lineItems:6802678421112514562"
 7) "lineItems:4083773252419547322:idx"
 8) "lineItems:4083773252419547322"
 9) "lineItems:6802678421112514562:idx"
10) "spring:session:sessions:expires:ea0c3a35-b821-461b-8568-1cf972ba99cb"
11) "Anup"
12) "lineItems:3544713235909729939"
13) "orders:4510658827505526003:idx"
14) "orders:4510658827505526003"
15) "orders:when:1541667065759"
16) "Ramesh"
17) "lineItems"
18) "spring:session:sessions:ea0c3a35-b821-461b-8568-1cf972ba99cb"
19) "orders"
127.0.0.1:6379>

我想你可以尝试不同的 serialVersion