当您使用spring-session-jdbc时,会话在DB中以字节序列化,这意味着每次将Spring升级到具有不兼容的Session.serialVersionUUID的版本时都必须删除所有会话。
我想以JSON格式存储会话,但经过一些谷歌搜索后似乎没有人这样做过。
当您考虑使用JSON在Redis中存储会话是常见做法时,这很奇怪。
为什么没有一种标准方法以JSON格式在JDBC中存储会话?这怎么可能实现?
JSON的主要问题是对象类型:您可以轻松地将对象序列化为JSON,但是当涉及反序列化时 - 您永远不会知道此JSON所呈现的对象类型。
我遇到过同样的问题。但是我只能解析JSON数据的一部分,这些数据来自外部源的会话。我的解决方案是创建org.springframework.core.convert.converter.Converter
接口的两个新实现 - 一个用于序列化(Object
到byte[]
)和一个用于反序列化(byte[]
到Object
),然后将它们注册为Spring的转换器。 org.springframework.session.jdbc.JdbcOperationsSessionRepository
使用此转换器来存储/读取会话属性字节。你可以像这样创建你的实现(使用Jackson库来使用JSON):
JsonSerializingConverter
@Component
public class JsonSerializingConverter implements Converter<Object, byte[]> {
@Override
public byte[] convert(Object source) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return objectMapper.writeValueAsBytes(source);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
JsonDeserializingConverter
@Component
public class JsonDeserializingConverter implements Converter<byte[], Object> {
@Override
public Object convert(byte[] source) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return objectMapper.readValue(source, Object.class);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
接下来你应该注册它们:
@Configuration
public class ConversionServiceConfiguration
{
@Bean
public ConversionServiceFactoryBean conversionService()
{
ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean();
bean.setConverters(getConverters());
return bean;
}
private Set<Converter> getConverters()
{
Set<Converter> converters = new HashSet<>();
converters.add(new JsonDeserializingConverter());
converters.add(new JsonSerializingConverter());
return converters;
}
}
除非您不需要将JSON数据与对象绑定(例如CsrfToken
对象),否则它将正常工作。在这种情况下,您可以在序列化步骤中使用目标类型注释JSON字符串,并在反序列化步骤中反序列化为该类型。希望这可能有所帮助。