From 9014ac906026094131f42c61e1dc40f7f5ac515f Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Wed, 16 Mar 2016 16:11:17 +0100 Subject: [PATCH] JdkMongoSessionConverter supports custom ClassLoader Fixes gh-431 --- docs/src/docs/asciidoc/index.adoc | 2 ++ .../mongo/MongoRepositoryJacksonITests.java | 5 ++- .../data/mongo/JdkMongoSessionConverter.java | 35 +++++++++++-------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 7943ae923..ab667360f 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -337,6 +337,8 @@ You can explicitly register `JdkMongoSessionConverter` by defining it as a Bean. include::{docs-test-dir}docs/http/MongoJdkSessionConfiguration.java[tags=config] ---- +There is also a constructor taking `Serializer` and `Deserializer` objects, allowing you to pass custom implementations, which is especially important when you want to use non-default classloader. + ==== Using custom converters You can create your own session converter by extending `AbstractMongoSessionConverter` class. diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/mongo/MongoRepositoryJacksonITests.java b/spring-session/src/integration-test/java/org/springframework/session/data/mongo/MongoRepositoryJacksonITests.java index 7170bc12e..b24872fa8 100644 --- a/spring-session/src/integration-test/java/org/springframework/session/data/mongo/MongoRepositoryJacksonITests.java +++ b/spring-session/src/integration-test/java/org/springframework/session/data/mongo/MongoRepositoryJacksonITests.java @@ -16,14 +16,17 @@ package org.springframework.session.data.mongo; import java.net.UnknownHostException; +import java.util.Collections; import java.util.Map; import java.util.UUID; +import com.fasterxml.jackson.databind.Module; import com.mongodb.MongoClient; import org.junit.Test; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.data.geo.GeoModule; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.session.data.mongo.config.annotation.web.http.EnableMongoHttpSession; @@ -63,7 +66,7 @@ public MongoOperations mongoOperations() throws UnknownHostException { @Bean public AbstractMongoSessionConverter mongoSessionConverter() { - return new JacksonMongoSessionConverter(); + return new JacksonMongoSessionConverter(Collections.singletonList(new GeoModule())); } } diff --git a/spring-session/src/main/java/org/springframework/session/data/mongo/JdkMongoSessionConverter.java b/spring-session/src/main/java/org/springframework/session/data/mongo/JdkMongoSessionConverter.java index ad720bd9c..cc4ec8bed 100644 --- a/spring-session/src/main/java/org/springframework/session/data/mongo/JdkMongoSessionConverter.java +++ b/spring-session/src/main/java/org/springframework/session/data/mongo/JdkMongoSessionConverter.java @@ -18,8 +18,6 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -29,6 +27,10 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.core.serializer.DefaultDeserializer; +import org.springframework.core.serializer.DefaultSerializer; +import org.springframework.core.serializer.Deserializer; +import org.springframework.core.serializer.Serializer; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.session.FindByIndexNameSessionRepository; @@ -48,10 +50,22 @@ public class JdkMongoSessionConverter extends AbstractMongoSessionConverter { private static final String CREATION_TIME = "created"; private static final String LAST_ACCESSED_TIME = "accessed"; private static final String MAX_INTERVAL = "interval"; - private static final String ATTRIBUTES = "attr"; + static final String ATTRIBUTES = "attr"; private static final String PRINCIPAL_FIELD_NAME = "principal"; + private final Serializer serializer; + private final Deserializer deserializer; + + public JdkMongoSessionConverter() { + this(new DefaultSerializer(), new DefaultDeserializer()); + } + + public JdkMongoSessionConverter(Serializer serializer, Deserializer deserializer) { + this.serializer = serializer; + this.deserializer = deserializer; + } + @Override public Query getQueryForIndex(String indexName, Object indexValue) { if (FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME @@ -86,16 +100,15 @@ protected MongoExpiringSession convert(DBObject sessionWrapper) { return session; } + @SuppressWarnings("unchecked") private byte[] serializeAttributes(Session session) { try { ByteArrayOutputStream out = new ByteArrayOutputStream(); - ObjectOutputStream outputStream = new ObjectOutputStream(out); Map attributes = new HashMap(); for (String attrName : session.getAttributeNames()) { attributes.put(attrName, session.getAttribute(attrName)); } - outputStream.writeObject(attributes); - outputStream.flush(); + this.serializer.serialize(attributes, out); return out.toByteArray(); } catch (IOException e) { @@ -109,22 +122,16 @@ private void deserializeAttributes(DBObject sessionWrapper, Session session) { try { ByteArrayInputStream in = new ByteArrayInputStream( (byte[]) sessionWrapper.get(ATTRIBUTES)); - ObjectInputStream objectInputStream = new ObjectInputStream(in); - Map attributes = (Map) objectInputStream - .readObject(); + Map attributes = + (Map) this.deserializer.deserialize(in); for (Map.Entry entry : attributes.entrySet()) { session.setAttribute(entry.getKey(), entry.getValue()); } - objectInputStream.close(); } catch (IOException e) { LOG.error("Exception during session deserialization", e); throw new IllegalStateException("Cannot deserialize session", e); } - catch (ClassNotFoundException e) { - LOG.error("Exception during session deserialization", e); - throw new IllegalStateException("Cannot deserialize session", e); - } } }