Spring会话Redis序列化程序序列化异常

jogvjijk  于 2023-02-18  发布在  Spring
关注(0)|答案(4)|浏览(200)

为了给我现有的应用程序外化Tomcat会话,我尝试了Spring Session Redis解决方案,按照以下步骤在pom.xml中包含必要的依赖项:

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
            <version>1.2.1.RELEASE</version>
        </dependency>

在web.xml中添加springSessionRepositoryFilter,如下所示:

<filter>
        <filter-name>springSessionRepositoryFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSessionRepositoryFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

并在Spring XML配置中添加以下内容

<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>

<context:property-placeholder location="classpath:application.properties"/>

<bean class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:port="${spring.redis.port}"/>

并构建和部署到Tomcat上,这是我得到的错误:

org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException: com.sun.jersey.client.apache.ApacheHttpClient

任何建议或帮助是非常感谢。谢谢!!也附上了我的pom.xml条目:pom.xml entries

d5vmydt9

d5vmydt91#

在您的异常中,com.sun.jersey.client.apache.ApacheHttpClient是不可序列化的,因为它没有实现java.io.Serializable。

您需要以其他方式序列化ApacheHttpClient,因为它是第三方库。

您可以使用Jackson库中的org.codehaus.jackson.map.ObjectMapper来实现这一点。
请参考此example
您还可以尝试使用HttpClient附带的SerializableEntity类。

httpost.setEntity(new SerializableEntity(mySerializableObj, false));

下面是使类可序列化的通用方法。

  • 如果类是你的,让它成为Serializable(这是不是你的情况)
  • 如果类是第三方,但不需要序列化形式,请将字段标记为transient
  • 如果您需要它的数据和它的第三方,请考虑其他序列化方法,如JSON、XML、BSON、MessagePack等,在这些方法中,您可以在不修改第三方对象定义的情况下将其序列化。
guicsvcw

guicsvcw2#

这里只想说明一种可能的解决方案。为了简洁起见,我假设您使用的是spring-boot。
本质上,当你用@EnableRedisHttpSession注解你的应用程序时,spring Boot 自动配置在RedisHttpSessionConfiguration类中定义的bean。在自动配置的bean中,sessionRedisTemplate是你想要定制的序列化器。下面的代码显示了RedisHttpSessionConfiguration提供的默认bean定义。

@Bean
public RedisTemplate<Object, Object> sessionRedisTemplate(
        RedisConnectionFactory connectionFactory) {
    RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
    template.setKeySerializer(new StringRedisSerializer());
    template.setHashKeySerializer(new StringRedisSerializer());
    if (this.defaultRedisSerializer != null) {
        template.setDefaultSerializer(this.defaultRedisSerializer);
    }
    template.setConnectionFactory(connectionFactory);
    return template;
}

要覆盖这个bean配置,只需在@Configuration类中声明一个名为sessionRedisTemplate的bean(例如,HttpSessionConfig),Spring-boot就会神奇地覆盖它的默认设置。

@Configuration
public class HttpSessionConfig {

@Bean
public RedisTemplate<Object, Object> sessionRedisTemplate(
        RedisConnectionFactory connectionFactory) {
    RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
    template.setKeySerializer(new StringRedisSerializer());
    template.setHashKeySerializer(new StringRedisSerializer());

    template.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());

    template.setConnectionFactory(connectionFactory);
    return template;
}
}
l3zydbqr

l3zydbqr3#

我也有同样的问题,创建类Serializable解决了我的问题。

lc8prwob

lc8prwob4#

我通过将Serializable添加到我的实体来解决,如下所示:

public class YourEntity implements Serializable{}

相关问题