【发布时间】:2018-09-17 10:37:30
【问题描述】:
我正在按照本教程将 spring 会话(通过 redis)添加到我的应用程序中。 http://www.baeldung.com/spring-session
我添加依赖项
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
</dependency>
和 SessionConfig.java 类
@Configuration
@EnableRedisHttpSession
public class SessionConfig extends AbstractHttpSessionApplicationInitializer {
}
我在一个空白项目上完成了这项工作,效果很好。但是我当前的项目有一些带有自定义 UserDetailsService 的自定义用户对象,这就是问题所在。
Sat Apr 07 11:21:49 EDT 2018
There was an unexpected error (type=Internal Server Error, status=500).
Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException: com.kreyzon.dollar.entity.User
现在,我环顾四周,找到了实现此功能的建议:
@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;
}
这不起作用(甚至似乎都没有被识别)。我也试过这个
@Bean(name = {"defaultRedisSerializer", "springSessionDefaultRedisSerializer"})
RedisSerializer<Object> defaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
现在,这实际上做了一些事情,但仍然导致错误
Sat Apr 07 11:39:21 EDT 2018
There was an unexpected error (type=Internal Server Error, status=500).
Could not read JSON: Can not construct instance of org.springframework.security.authentication.UsernamePasswordAuthenticationToken: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?) at [Source: [B@4dc133; line: 1, column: 184] (through reference chain: org.springframework.security.core.context.SecurityContextImpl["authentication"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of org.springframework.security.authentication.UsernamePasswordAuthenticationToken: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?) at [Source: [B@4dc133; line: 1, column: 184] (through reference chain: org.springframework.security.core.context.SecurityContextImpl["authentication"])
我还探索了其他序列化程序,例如 Jackson2JsonRedisSerializer 和 GenericJackson2JsonRedisSerializer,但得到了相同的错误..
感谢所有帮助,谢谢。
更新:
我也试过添加这个自定义序列化程序
public class CustomRedisSerializer implements RedisSerializer<Object> {
private Converter<Object, byte[]> serializer = new SerializingConverter();
private Converter<byte[], Object> deserializer = new DeserializingConverter();
static final byte[] EMPTY_ARRAY = new byte[0];
public Object deserialize(byte[] bytes) {
if (isEmpty(bytes)) {
return null;
}
try {
return deserializer.convert(bytes);
} catch (Exception ex) {
throw new SerializationException("Cannot deserialize", ex);
}
}
public byte[] serialize(Object object) {
if (object == null) {
return EMPTY_ARRAY;
}
try {
return serializer.convert(object);
} catch (Exception ex) {
return EMPTY_ARRAY;
//TODO add logic here to only return EMPTY_ARRAY for known conditions
// else throw the SerializationException
// throw new SerializationException("Cannot serialize", ex);
}
}
private boolean isEmpty(byte[] data) {
return (data == null || data.length == 0);
}
}
第二次更新:
所以我将implements Serializable 添加到我的所有自定义对象中。这工作,去图! (由于某种原因,我发现没有一篇关于该主题的帖子表明)
现在,我的上一个问题仍然存在。我正在使用LDAP进行身份验证,如果身份验证失败,它会返回一个对象LdapCtx,该对象不可序列化并引发错误
Sat Apr 07 12:35:14 EDT 2018
There was an unexpected error (type=Internal Server Error, status=500).
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.jndi.ldap.LdapCtx
有没有办法强制这个类是可序列化的?
更新(2018 年 10 月 22 日):
此问题已解决 https://github.com/spring-projects/spring-security/issues/5378
【问题讨论】:
标签: java spring spring-boot redis spring-session