1. Overzicht
In deze korte zelfstudie onderzoeken we hoe u de Spring Session kunt gebruiken die wordt ondersteund door MongoDB, zowel met als zonder Spring Boot.
Spring Session kan ook worden ondersteund met andere winkels zoals Redis en JDBC.
2. Spring Boot-configuratie
Laten we eerst eens kijken naar de afhankelijkheden en de configuratie die nodig zijn voor Spring Boot. Laten we om te beginnen de nieuwste versies van spring-session-data-mongodb toevoegen en spring-boot-starter-data-mongodb naar ons project:
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-mongodb</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
Om daarna de automatische configuratie van Spring Boot in te schakelen, moeten we het Spring Session-winkeltype toevoegen als mongodb in de application.properties :
spring.session.store-type=mongodb
3. Veerconfiguratie zonder veerboot
Laten we nu eens kijken naar de afhankelijkheden en de configuratie die nodig zijn om de Spring-sessie in MongoDB op te slaan zonder Spring Boot.
Net als bij de Spring Boot-configuratie hebben we de spring-session-data-mongodb nodig afhankelijkheid. Hier gebruiken we echter de spring-data-mongodb afhankelijkheid om toegang te krijgen tot onze MongoDB-database:
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-mongodb</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
Laten we tot slot eens kijken hoe we de applicatie kunnen configureren:
@EnableMongoHttpSession
public class HttpSessionConfig {
@Bean
public JdkMongoSessionConverter jdkMongoSessionConverter() {
return new JdkMongoSessionConverter(Duration.ofMinutes(30));
}
}
De @EnableMongoHttpSession annotatie maakt de configuratie mogelijk die nodig is om de sessiegegevens op te slaan in MongoDB .
Merk ook op dat de JdkMongoSessionConverter is verantwoordelijk voor het serialiseren en deserialiseren van de sessiegegevens.
4. Voorbeeldtoepassing
Laten we een applicatie maken om de configuraties te testen. We gaan Spring Boot gebruiken, omdat het sneller is en minder configuratie vereist.
We beginnen met het maken van de controller om verzoeken af te handelen:
@RestController
public class SpringSessionMongoDBController {
@GetMapping("/")
public ResponseEntity<Integer> count(HttpSession session) {
Integer counter = (Integer) session.getAttribute("count");
if (counter == null) {
counter = 1;
} else {
counter++;
}
session.setAttribute("count", counter);
return ResponseEntity.ok(counter);
}
}
Zoals we in dit voorbeeld kunnen zien, verhogen we teller bij elke treffer naar het eindpunt en de waarde ervan opslaan in een sessie-attribuut met de naam count .
5. De applicatie testen
Laten we de applicatie testen om te zien of we de sessiegegevens daadwerkelijk kunnen opslaan in MongoDB.
Om dit te doen, gaan we naar het eindpunt en inspecteren we de cookie die we ontvangen. Dit zal een sessie-ID bevatten.
Daarna zullen we de MongoDB-verzameling opvragen om de sessiegegevens op te halen met behulp van de sessie-ID:
@Test
public void
givenEndpointIsCalledTwiceAndResponseIsReturned_whenMongoDBIsQueriedForCount_thenCountMustBeSame() {
HttpEntity<String> response = restTemplate
.exchange("http://localhost:" + 8080, HttpMethod.GET, null, String.class);
HttpHeaders headers = response.getHeaders();
String set_cookie = headers.getFirst(HttpHeaders.SET_COOKIE);
Assert.assertEquals(response.getBody(),
repository.findById(getSessionId(set_cookie)).getAttribute("count").toString());
}
private String getSessionId(String cookie) {
return new String(Base64.getDecoder().decode(cookie.split(";")[0].split("=")[1]));
}
6. Hoe werkt het?
Laten we eens kijken wat er achter de schermen gebeurt tijdens de lentesessie.
Het SessionRepositoryFilter is verantwoordelijk voor het meeste werk:
- converteert de HttpSession in een MongoSession
- controleert of er een Cookie is aanwezig, en zo ja, laadt de sessiegegevens uit de winkel
- slaat de bijgewerkte sessiegegevens op in de winkel
- controleert de geldigheid van de sessie
Ook de SessionRepositoryFilter maakt een cookie aan met de naam SESSION dat is HttpOnly en veilig. Deze cookie bevat de sessie-ID, wat een Base64-gecodeerde waarde is.
Om de cookienaam of eigenschappen aan te passen, moeten we een springbean van het type DefaultCookieSerializer maken.
Hier schakelen we bijvoorbeeld de httponly . uit eigendom van de cookie:
@Bean
public DefaultCookieSerializer customCookieSerializer(){
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
cookieSerializer.setUseHttpOnlyCookie(false);
return cookieSerializer;
}
7. Sessiedetails opgeslagen in MongoDB
Laten we een query uitvoeren op onze sessieverzameling met behulp van de volgende opdracht in onze MongoDB-console:
db.sessions.findOne()
Als resultaat krijgen we een BSON-document dat lijkt op:
{
"_id" : "5d985be4-217c-472c-ae02-d6fca454662b",
"created" : ISODate("2019-05-14T16:45:41.021Z"),
"accessed" : ISODate("2019-05-14T17:18:59.118Z"),
"interval" : "PT30M",
"principal" : null,
"expireAt" : ISODate("2019-05-14T17:48:59.118Z"),
"attr" : BinData(0,"rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABdAAFY291bnRzcgARamF2YS5sYW5nLkludGVnZXIS4qCk94GHOAIAAUkABXZhbHVleHIAEGphdmEubGFuZy5OdW1iZXKGrJUdC5TgiwIAAHhwAAAAC3g=")
}
De _id is een UUID die wordt gecodeerd met Base64 door de DefaultCookieSerializer en ingesteld als een waarde in de SESSIE koekje. Merk ook op dat de attr attribuut bevat de werkelijke waarde van onze teller.