From ba7de8ed345dc08348644a4ca548c2c9c0810c03 Mon Sep 17 00:00:00 2001 From: Yanming Zhou Date: Thu, 23 Feb 2023 10:01:23 +0800 Subject: [PATCH] Provide Session Id Generation Strategy Fix GH-11 --- .../springframework/session/MapSession.java | 15 ++++-- .../session/SessionIdGenerator.java | 42 +++++++++++++++ .../session/SessionIdGeneratorTests.java | 51 +++++++++++++++++++ ...springframework.session.SessionIdGenerator | 1 + 4 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 spring-session-core/src/main/java/org/springframework/session/SessionIdGenerator.java create mode 100644 spring-session-core/src/test/java/org/springframework/session/SessionIdGeneratorTests.java create mode 100644 spring-session-core/src/test/resources/META-INF/services/org.springframework.session.SessionIdGenerator diff --git a/spring-session-core/src/main/java/org/springframework/session/MapSession.java b/spring-session-core/src/main/java/org/springframework/session/MapSession.java index bd2413575..3536b8e0d 100644 --- a/spring-session-core/src/main/java/org/springframework/session/MapSession.java +++ b/spring-session-core/src/main/java/org/springframework/session/MapSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2022 the original author or authors. + * Copyright 2014-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,9 +21,10 @@ import java.time.Instant; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.Map; +import java.util.ServiceLoader; import java.util.Set; -import java.util.UUID; /** *

@@ -44,6 +45,7 @@ * * @author Rob Winch * @author Vedran Pavic + * @author Yanming Zhou * @since 1.0 */ public final class MapSession implements Session, Serializable { @@ -229,7 +231,14 @@ public int hashCode() { } private static String generateId() { - return UUID.randomUUID().toString(); + return sessionIdGenerator.generateId(); + } + + private static final SessionIdGenerator sessionIdGenerator; + + static { + Iterator generators = ServiceLoader.load(SessionIdGenerator.class).iterator(); + sessionIdGenerator = generators.hasNext() ? generators.next() : SessionIdGenerator.DEFAULT; } private static final long serialVersionUID = 7160779239673823561L; diff --git a/spring-session-core/src/main/java/org/springframework/session/SessionIdGenerator.java b/spring-session-core/src/main/java/org/springframework/session/SessionIdGenerator.java new file mode 100644 index 000000000..399eb36bf --- /dev/null +++ b/spring-session-core/src/main/java/org/springframework/session/SessionIdGenerator.java @@ -0,0 +1,42 @@ +/* + * Copyright 2014-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.session; + +import java.util.UUID; + +/** + *

+ * Id generator for creating new session. + *

+ * + * @author Yanming Zhou + */ +@FunctionalInterface +public interface SessionIdGenerator { + + /** + * Using random UUID as default id generator. + */ + SessionIdGenerator DEFAULT = () -> UUID.randomUUID().toString(); + + /** + * Generate and return a new session identifier. + * @return the newly generated session id + */ + String generateId(); + +} diff --git a/spring-session-core/src/test/java/org/springframework/session/SessionIdGeneratorTests.java b/spring-session-core/src/test/java/org/springframework/session/SessionIdGeneratorTests.java new file mode 100644 index 000000000..313276f2d --- /dev/null +++ b/spring-session-core/src/test/java/org/springframework/session/SessionIdGeneratorTests.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.session; + +import java.util.concurrent.atomic.AtomicLong; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Yanming Zhou + */ +class SessionIdGeneratorTests { + + static final String prefix = "sessionid-"; + + @Test + void sessionIdShouldStartsWithCustomizedPrefix() { + MapSession session = new MapSession(); + assertThat(session.getId()).startsWith(prefix); + session.changeSessionId(); + assertThat(session.getId()).startsWith(prefix); + } + + public static class MySessionIdGenerator implements SessionIdGenerator { + + private final AtomicLong counter = new AtomicLong(); + + @Override + public String generateId() { + return prefix + this.counter.incrementAndGet(); + } + + } + +} diff --git a/spring-session-core/src/test/resources/META-INF/services/org.springframework.session.SessionIdGenerator b/spring-session-core/src/test/resources/META-INF/services/org.springframework.session.SessionIdGenerator new file mode 100644 index 000000000..4a8fd337c --- /dev/null +++ b/spring-session-core/src/test/resources/META-INF/services/org.springframework.session.SessionIdGenerator @@ -0,0 +1 @@ +org.springframework.session.SessionIdGeneratorTests$MySessionIdGenerator \ No newline at end of file