Spring Session Redis序列化程序SerializationException

问题描述 投票:2回答:2

为了尝试外部化我现有应用程序的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

spring tomcat redis spring-session
2个回答
1
投票

从您的例外情况来看,com.sun.jersey.client.apache.ApacheHttpClient不可序列化,因为它没有实现java.io.Serializable。

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

您可以使用杰克逊图书馆的org.codehaus.jackson.map.ObjectMapper来实现这一目标。

请参考这个example

您也可以尝试使用HttpClient附带的SerializableEntity类。

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

以下是使类可序列化的一般方法。

  • 如果这个类是你的,那就把它变成Serializable(这不是你的情况)
  • 如果该类是第三方,但您不需要序列化形式,请将该字段标记为瞬态
  • 如果您需要其数据及其第三方,请考虑其他序列化方法,如JSON,XML,BSON,MessagePack等,您可以在不修改其定义的情况下序列化第三方对象。

0
投票

只是想在这里说明一种可能的解决方案。为简洁起见,我假设您使用的是spring-boot。

基本上,当您使用RedisHttpSessionConfiguration注释应用程序时,spring boot会自动配置@EnableRedisHttpSession类中定义的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类(例如,HttpSessionConfig)中声明一个名为sessionRedisTemplate的bean,Spring-boot将完成覆盖其默认设置的魔力。在这里,我用GenericJackson2JsonSerializer演示它。

@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;
}
}
© www.soinside.com 2019 - 2024. All rights reserved.