Использование формата JSON с Spring Session JDBC - PullRequest
0 голосов
/ 08 февраля 2019

Когда вы используете spring-session-jdbc, сеансы сериализуются в БД в виде байтов, что означает, что вам нужно отбрасывать все сеансы каждый раз, когда вы обновляете Spring до версии с несовместимым Session.serialVersionUUID.

Iхотел сохранить сеанс в формате JSON, но после некоторого поиска в Google кажется, что никто никогда не делал этого.

Это странно, если учесть, что хранение сеансов в Redis с использованием JSON является обычной практикой.

Почему не существует стандартного способа хранения сессий в JDBC в формате JSON?И как этого достичь?

1 Ответ

0 голосов
/ 02 апреля 2019

Основная проблема с JSON - это типы объектов: вы можете легко сериализовать объекты как JSON, но когда дело доходит до десериализации - вы никогда не сможете узнать, какой тип объекта представляет этот JSON.

Я сталкивался свроде такая же проблема.Но мне было достаточно разобрать только ту часть данных JSON, которая поступает в сеанс из внешнего источника.Мое решение состояло в том, чтобы создать две новые реализации интерфейса org.springframework.core.convert.converter.Converter - одну для сериализации (Object до byte[]) и одну для десериализации (byte[] до Object), а затем зарегистрировать их как конвертеры для Spring.Эти конвертеры используются org.springframework.session.jdbc.JdbcOperationsSessionRepository для хранения / чтения байтов атрибутов сеанса.Вы можете создавать свои реализации следующим образом (для работы с JSON используется библиотека Jackson ):

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 целевым типом на этапе сериализации и десериализовать в этот тип на этапе десериализации.Надеюсь, это поможет.

...