我有一个与spring security集成的应用程序。我将此应用程序分离为两个应用程序,因此我希望使用Redis配置spring会话,以便在这两个应用程序之间进行集中身份验证。我已经配置了Redis但是当我想登录时,会引发以下异常:
引起: org.springframework.core.serializer.support.SerializationFailedException: 无法使用DefaultSerializer序列化对象;嵌套异常 是java.io.NotSerializableException: org.springframework.dao.support.PersistenceExceptionTranslationInterceptor 在 org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:68) 〜[spring-core-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:35) 〜[spring-core-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:90) 〜[spring-data-redis-1.7.2.RELEASE.jar:na] ... 35个常见帧 省略 引起:java.io.NotSerializableException:org.springframework.dao.support.PersistenceExceptionTranslationInterceptor 在java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)〜[na:1.8.0_111] 在java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)〜[na:1.8.0_111]
RedisConfig:
@Configuration
@EnableRedisHttpSession
public class RedisConfig implements BeanClassLoaderAware {
private ClassLoader loader;
@Bean
@Primary
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
redisTemplate.setConnectionFactory(cf);
redisTemplate.setKeySerializer(redisTemplate.getStringSerializer());
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(Object.class));
return redisTemplate;
}
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("JSESSIONID"); // <1>
serializer.setCookiePath("/"); // <2>
serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$"); // <3>
return serializer;
}
@Bean
public HttpSessionStrategy httpSessionStrategy() {
return new HeaderHttpSessionStrategy();
}
@Bean
public LettuceConnectionFactory connectionFactory() {
return new LettuceConnectionFactory();
}
ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModules(SecurityJackson2Modules.getModules(this.loader));
return mapper;
}
public void setBeanClassLoader(ClassLoader classLoader) {
this.loader = classLoader;
}
}
和这个配置:
public class SafeDeserializationRepository<S extends ExpiringSession> implements SessionRepository<S> {
private final SessionRepository<S> delegate;
private final RedisTemplate<Object, Object> redisTemplate;
private static final String BOUNDED_HASH_KEY_PREFIX = "spring:session:sessions:";
// private static final Logger logger =
// getLogger(SafeDeserializationRepository.class);
public SafeDeserializationRepository(SessionRepository<S> delegate, RedisTemplate<Object, Object> redisTemplate) {
this.delegate = delegate;
this.redisTemplate = redisTemplate;
}
@Override
public S createSession() {
return delegate.createSession();
}
@Override
public void save(S session) {
delegate.save(session);
}
@Override
public S getSession(String id) {
try {
return delegate.getSession(id);
} catch (SerializationException e) {
// logger.info("Deleting non-deserializable session with key {}",
// id);
redisTemplate.delete(BOUNDED_HASH_KEY_PREFIX + id);
return null;
}
}
@Override
public void delete(String id) {
delegate.delete(id);
}
}
和RedisSessionConfig:
@Configuration
public class RedisSessionConfig extends RedisHttpSessionConfiguration {
@Autowired
RedisTemplate<Object, Object> redisTemplate;
@Bean
@Override
public <S extends ExpiringSession> SessionRepositoryFilter<? extends ExpiringSession> springSessionRepositoryFilter(SessionRepository<S> sessionRepository) {
return super.springSessionRepositoryFilter(new SafeDeserializationRepository<>(sessionRepository, redisTemplate));
}
}
有什么问题?
我很困惑
感谢您的帮助。
答案 0 :(得分:0)
implements Serializable
用于这些类。当类不是Serializable时遇到问题。另请查看Jackson注释,以便您可以选择如何序列化对象。