From 04686974b1ea3d42e815c7e44e9b35672da5b978 Mon Sep 17 00:00:00 2001 From: xiao Date: Tue, 3 Sep 2024 17:31:04 +0800 Subject: [PATCH] Optimize the usage of JacksonMongoSessionConverter to prevent duplicate MongoSession Document saves when a custom ObjectMapper is provided.https://github.com/spring-projects/spring-session/issues/3185 --- .../mongo/JacksonMongoSessionConverter.java | 35 ++++++++++++------- .../session/data/mongo/MongoSession.java | 16 ++++----- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/spring-session-data-mongodb/src/main/java/org/springframework/session/data/mongo/JacksonMongoSessionConverter.java b/spring-session-data-mongodb/src/main/java/org/springframework/session/data/mongo/JacksonMongoSessionConverter.java index 986634200..d87d9e1c0 100644 --- a/spring-session-data-mongodb/src/main/java/org/springframework/session/data/mongo/JacksonMongoSessionConverter.java +++ b/spring-session-data-mongodb/src/main/java/org/springframework/session/data/mongo/JacksonMongoSessionConverter.java @@ -16,11 +16,6 @@ package org.springframework.session.data.mongo; -import java.io.IOException; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; - import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -37,7 +32,6 @@ import org.bson.Document; import org.bson.json.JsonMode; import org.bson.json.JsonWriterSettings; - import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.lang.Nullable; @@ -45,12 +39,18 @@ import org.springframework.session.FindByIndexNameSessionRepository; import org.springframework.util.Assert; +import java.io.IOException; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; + /** * {@code AbstractMongoSessionConverter} implementation using Jackson. * * @author Jakub Kubrynski * @author Greg Turnquist * @author Michael Ruf + * @author TiQuan Hu * @since 1.2 */ public class JacksonMongoSessionConverter extends AbstractMongoSessionConverter { @@ -70,17 +70,27 @@ public JacksonMongoSessionConverter() { } public JacksonMongoSessionConverter(Iterable modules) { - this.objectMapper = buildObjectMapper(); this.objectMapper.registerModules(modules); } public JacksonMongoSessionConverter(ObjectMapper objectMapper) { - - Assert.notNull(objectMapper, "ObjectMapper can NOT be null!"); + Assert.notNull(objectMapper, "ObjectMapper can not be null!"); this.objectMapper = objectMapper; } + public JacksonMongoSessionConverter(ObjectMapper objectMapper, boolean copyToUse) { + Assert.notNull(objectMapper, "ObjectMapper can not be null!"); + if (!copyToUse) { + configureObjectMapper(objectMapper); + this.objectMapper = objectMapper; + return; + } + var objectMapperCopy = objectMapper.copy(); + configureObjectMapper(objectMapperCopy); + this.objectMapper = objectMapperCopy; + } + @Nullable protected Query getQueryForIndex(String indexName, Object indexValue) { @@ -93,9 +103,12 @@ protected Query getQueryForIndex(String indexName, Object indexValue) { } private ObjectMapper buildObjectMapper() { - ObjectMapper objectMapper = new ObjectMapper(); + this.configureObjectMapper(objectMapper); + return objectMapper; + } + private void configureObjectMapper(ObjectMapper objectMapper) { // serialize fields instead of properties objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); @@ -108,8 +121,6 @@ private ObjectMapper buildObjectMapper() { objectMapper.registerModules(SecurityJackson2Modules.getModules(getClass().getClassLoader())); objectMapper.addMixIn(MongoSession.class, MongoSessionMixin.class); objectMapper.addMixIn(HashMap.class, HashMapMixin.class); - - return objectMapper; } @Override diff --git a/spring-session-data-mongodb/src/main/java/org/springframework/session/data/mongo/MongoSession.java b/spring-session-data-mongodb/src/main/java/org/springframework/session/data/mongo/MongoSession.java index d3bb813e8..3272f9a7c 100644 --- a/spring-session-data-mongodb/src/main/java/org/springframework/session/data/mongo/MongoSession.java +++ b/spring-session-data-mongodb/src/main/java/org/springframework/session/data/mongo/MongoSession.java @@ -16,15 +16,6 @@ package org.springframework.session.data.mongo; -import java.time.Duration; -import java.time.Instant; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; - import org.springframework.lang.Nullable; import org.springframework.session.MapSession; import org.springframework.session.Session; @@ -32,6 +23,11 @@ import org.springframework.session.UuidSessionIdGenerator; import org.springframework.util.Assert; +import java.time.Duration; +import java.time.Instant; +import java.util.*; +import java.util.stream.Collectors; + /** * Session object providing additional information about the datetime of expiration. * @@ -39,7 +35,7 @@ * @author Greg Turnquist * @since 1.2 */ -class MongoSession implements Session { +public class MongoSession implements Session { /** * Mongo doesn't support {@literal dot} in field names. We replace it with a unicode