Spring Session für Web-Anwendungen mit Zuständen

Web-Anwendungen mit Zuständen sind häufig aufgrund der benötigten Session kein leichtes Thema. Daher gibt es im Spring Framework das Projekt Spring Session, welches uns ohne großen Aufwand die Daten der Session vom Application Server auslagert, so dass wir unsere Web-Anwendung clustern können. Hier werde ich zeigen, wie einfach ihr Spring Session in eurer Spring Boot Projekt einbinden könnt.


Spring Session in Spring Boot Projekten integrieren

In einem anderen Blog-Artikel habe ich eine Web-Anwendung mit Thymeleaf gebaut. In dieser Anwendung wurde die Session bisher weder benutzt noch persistiert, so dass die Daten des Benutzers nach einem Anwendungsneustart oder Serverwechsel im Cluster weg waren.

Spring Boot ermöglicht uns dank vorbereiteter Default-Konfiguration das Integrieren einer persistenten Session in 2 Schritten. Diese werde ich euch hier mit MongoDB als Datenbank zum Persistieren der Session zeigen. Neben der MongoDB kann die Session auch in einer JDBC basierten Datenbank, Redis oder weiteren Alternativen gespeichert werden, weitere Details findet ihr hier:
https://spring.io/projects/spring-session 

Wie man eine MongoDB einfach mit Docker startet, habe ich in diesem Artikel gezeigt.

1. Spring Session Maven Dependency

Die Maven oder Gradle Konfiguration unseres Spring Boot Projektes muss um eine Spring Session Dependency erweitert werden. In unserem Beispiel mit MongoDB sieht das so aus:

    <dependency>
        <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-mongodb</artifactId>
    </dependency>
  • spring-boot-starter-data-mongodb wird für den Zugriff auf die MongoDB benötigt. Das kennen wir aber schon aus anderen Spring Boot Projekten, die auch eine Mongo Datenbank verwenden.
  • spring-session-data-mongodb kümmert sich für uns um das Persistieren der Session in der MongoDB. Wenn ihr statt MongoDB eine JDBC Datenbank oder Redis verwendet, würdet ihr diese Bibliotheken zum Persistieren der Session nutzen:
    • JDBC Alternative: spring-session-jdbc
    • Redis Alternative: spring-session-data-redis

2. Spring Boot Projekt Session Store Konfiguration

Jetzt fehlt nur noch eine Konfigurationszeile in der application.properties Datei, die festlegt, dass die Session im einer MongoDB gespeichert wird:

    spring.data.mongodb.uri=mongodb://localhost:27017/local
    spring.session.store-type=mongodb

Neben dem store-type habe ich auch noch die uri zur MongoDB konfiguriert, da mein Thymeleaf Beispiel-Projekt vorher keine Datenbank benutzt hatte.
Das war es schon. Euer Spring Boot Projekt speichert jetzt die Session in der Datenbank.

Daten in der Session speichern

Das Schreiben und Lesen von Daten in der Session ändert sich nicht durch das Persistieren der Session in eine Datenbank. Dazu hier ein einfaches Beispiel:

@Autowired private HttpSession session;
private List readItemsFromSession() {
    if (session.getAttribute("ITEMS") instanceof List items)
        return items;
    return List.of();
}
private void createItemInSession(String name, String id) {
    var item = new Item();
    item.setId(id);
    item.setName(name);
    session.setAttribute("ITEMS", List.of(item));
}
  • Spring ermöglicht uns per Dependency Injection den Zugriff auf die Session bzw. eine Bean vom Typ HttpSession. In diesem Beispiel verwende ich die Spring Field Injection mit Hilfe der Annotation @Autowired.
  • Mit der Methode getAttribute des Interfaces HttpSession kann ein Wert bzw. Objekt aus der Session gelesen werden. Sollte kein Wert für dem übergebenen String-Parameter gefunden werden, wird null zurück gegeben. Das fange ich hier im Beispiel mit dem instanceof Operator ab. Das verwendete Pattern Matching erkläre ich in java-17-features.html.
  • Zum Schreiben in die Session gibt es die Methode setAttribute. Der erste String-Parameter ist der Wert unter dem ihr das Objekt in der Session speichert. Der zweite Parameter ist das eigentliche zu speichernde Objekt.
  • Wenn ein Objekt in die Session gespeichert wird, sollte die jeweilige Klasse das Interface Serializable implementieren. Das geht sehr leicht, da Serializable keine Methoden spezifiziert, die ihr implementieren müsst. Die dazu nötige Anpassung an der Item Klasse habe ich fett markiert:
    public class Item implements Serializable... 

    Fazit

    Wie hier gezeigt übernimmt Spring für uns das Persistieren der Session in einer Datenbank. Dieses Feature kann per Konfiguration aktiviert werden ohne das wir eine einzige Zeile Code schreiben müssen. Beim Verwenden der HttpSession Bean ändert sich dabei auch nichts - alles ist angenehm unkompliziert.

    Den kompletten Code zu diesem Blog-Artikel findet ihr in GitHub:
    https://github.com/elmar-brauch/thymeleaf

    Kommentare

    Beliebte Posts aus diesem Blog

    OpenID Connect mit Spring Boot 3

    Authentifizierung in Web-Anwendungen mit Spring Security 6

    Reaktive REST-Webservices mit Spring WebFlux