【问题标题】:Using JSON format with Spring Session JDBC在 Spring Session JDBC 中使用 JSON 格式
【发布时间】:2019-02-08 14:20:19
【问题描述】:

当您使用 spring-session-jdbc 时,会话在 DB 中被序列化为字节,这意味着每次将 Spring 升级到 Session.serialVersionUUID 不兼容的版本时,您都必须删除所有会话。

我想以 JSON 格式存储会话,但经过一番谷歌搜索后,似乎没有人这样做过。

考虑到使用 JSON 在 Redis 中存储会话是一种常见做法,这很奇怪。

为什么没有标准的方法来以 JSON 格式在 JDBC 中存储会话?而这又是如何实现的呢?

【问题讨论】:

    标签: java json jdbc spring-session


    【解决方案1】:

    JSON 的主要问题是对象类型:您可以轻松地将对象序列化为 JSON,但在反序列化时 - 您永远无法知道这个 JSON 代表什么类型的对象。

    我也遇到过同样的问题。但对我来说,只解析来自外部源的会话的 JSON 数据部分就足够了。我的解决方案是创建org.springframework.core.convert.converter.Converter 接口的两个新实现——一个用于序列化(Objectbyte[]),一个用于反序列化(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 字符串,并在反序列化步骤中反序列化为该类型。 希望这可能会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-06
      • 2017-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-15
      • 2021-07-21
      • 1970-01-01
      相关资源
      最近更新 更多