【问题标题】:Spring Session Redis serializer SerializationExceptionSpring Session Redis 序列化器 SerializationException
【发布时间】:2016-11-26 17:30:53
【问题描述】:

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

【问题讨论】:

  • 你能发布异常的完整堆栈跟踪吗?
  • java.io.NotSerializableException 我猜你试图保存为会话状态的任何对象都是不可序列化的。发布有关保存会话状态的机制的更多详细信息

标签: spring tomcat redis spring-session


【解决方案1】:

我也遇到了同样的问题,上课 Serializable 解决了我的问题。

【讨论】:

  • 我认为这里的重要说明是导致OP序列化异常的类来自外部库,因此不能简单地更新为serializable
【解决方案2】:

只是想在这里说明一种可能的解决方案。为简洁起见,我假设您使用的是 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 类(例如 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;
}
}

【讨论】:

    【解决方案3】:

    从您的异常来看,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));
    

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

    • 如果该类是您的,则使其可序列化(这不是您的情况)
    • 如果类是3rd party,但序列化形式不需要,将该字段标记为transient
    • 如果您需要它的数据并且它是第三方的,请考虑 其他序列化方式,如 JSON、XML、BSON、MessagePack 等。 您可以在不修改的情况下序列化 3rd 方对象 他们的定义。

    【讨论】:

    • 在尝试了您的建议后,现在我收到以下错误/异常...我想知道我是否遇到了与 Spring Session 的兼容性问题...'code' org.springframework.data.redis .serializer.SerializationException:无法序列化;嵌套异常是 org.springframework.core.serializer.support.SerializationFailedException: 无法使用 DefaultSerializer 序列化对象;嵌套异常是 java.io.NotSerializableException: org.springframework.context.support.ReloadableResourceBundleMessageSource
    猜你喜欢
    • 2017-02-15
    • 2021-12-14
    • 2021-09-13
    • 2019-02-12
    • 1970-01-01
    • 2017-07-21
    • 2018-10-06
    • 2016-02-19
    • 1970-01-01
    相关资源
    最近更新 更多