Spring Boot Sample 032之spring-boot-session

一、环境
Idea 2020.1
JDK 1.8
maven
二、目的
spring boot 通过整合session的多种方式
gitHub地址: https://github.com/ouyushan/ouyushan-spring-boot-samples
三、步骤
3.1、点击File -> New Project -> Spring Initializer,点击next

3.2、在对应地方修改自己的项目信息

3.3、选择Web依赖,选中Spring Web、Spring Session、Spring Data JDBC、H2 DataBase、Spring Data Redis、Spring Data MongoDB、Spring Boot DevTools。可以选择Spring Boot版本,本次默认为2.3.0,点击Next

3.4、项目结构

四、添加文件

pom.xml文件


4.0.0

org.springframework.boot
spring-boot-starter-parent
2.3.0.RELEASE


org.ouyushan
spring-boot-session
0.0.1-SNAPSHOT
spring-boot-session
Session project for Spring Boot

<properties>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <!-- Compile -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!-- Test -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
<profiles>
    <profile>
        <id>redis</id>
        <dependencies>
            <dependency>
                <groupId>org.springframework.session</groupId>
                <artifactId>spring-session-data-redis</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
            </dependency>

        </dependencies>
    </profile>
    <profile>
        <id>jdbc</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <dependencies>
            <dependency>
                <groupId>org.springframework.session</groupId>
                <artifactId>spring-session-jdbc</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </dependency>
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
            </dependency>
        </dependencies>
    </profile>
    <profile>
        <id>hazelcast</id>
        <dependencies>
            <dependency>
                <groupId>org.springframework.session</groupId>
                <artifactId>spring-session-hazelcast</artifactId>
            </dependency>
            <dependency>
                <groupId>com.hazelcast</groupId>
                <artifactId>hazelcast</artifactId>
            </dependency>
        </dependencies>
    </profile>
    <profile>
        <id>mongodb</id>
        <dependencies>
            <dependency>
                <groupId>org.springframework.session</groupId>
                <artifactId>spring-session-data-mongodb</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-mongodb</artifactId>
            </dependency>
        </dependencies>
    </profile>
</profiles>

application.properties文件
spring.security.user.name=user
spring.security.user.password=password
management.endpoints.web.exposure.include=*

######## REDIS ########

Redis数据库索引(默认为0)

spring.redis.database=0

Redis服务器地址

spring.redis.host=127.0.0.1

Redis服务器连接端口

spring.redis.port=6379

Redis服务器连接密码(默认为空)

spring.redis.password=

连接超时时间(毫秒)

spring.redis.timeout=3000

连接池最大连接数(使用负值表示没有限制)

spring.redis.lettuce.pool.max-active=8

连接池最大阻塞等待时间(使用负值表示没有限制)

spring.redis.lettuce.pool.max-wait=-1

连接池中的最大空闲连接

spring.redis.lettuce.pool.max-idle=8

连接池中的最小空闲连接

spring.redis.lettuce.pool.min-idle=0

hazelcast.xml

<map name="spring:session:sessions">
    <attributes>
        <attribute extractor="org.springframework.session.hazelcast.PrincipalNameExtractor">principalName</attribute>
    </attributes>
    <indexes>
        <index>principalName</index>
    </indexes>
</map>

<network>
    <join>
        <multicast enabled="false"/>
    </join>
</network>

LettuceRedisConfig.java

package org.ouyushan.springboot.session.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import javax.annotation.Resource;

/**

  • @Description:
  • @Author: ouyushan
  • @Email: ouyushan@hotmail.com
  • @Date: 2020/5/11 9:55
    */

@Configuration
@EnableCaching
public class LettuceRedisConfig {

@Resource
private LettuceConnectionFactory lettuceConnectionFactory;


// 缓存管理器
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory lettuceConnectionFactory) {
    RedisCacheManager redisCacheManager = RedisCacheManager.builder(lettuceConnectionFactory).build();
    return redisCacheManager;
}


@Bean
public RedisTemplate<Object, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
    RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(lettuceConnectionFactory);
    // key序列化
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    // 使用Jackson ,将对象序列化为JSON
    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    //json 转对象类,不设置默认的会将json转成hashmap 报错:java.util.LinkedHashMap cannot be cast to XX
    ObjectMapper om = new ObjectMapper();
    om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
    jackson2JsonRedisSerializer.setObjectMapper(om);

    redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
    redisTemplate.afterPropertiesSet();
    return redisTemplate;
}

}

五、测试

SpringBootSessionApplicationTests.java

package org.ouyushan.springboot.session;

import org.junit.jupiter.api.Test;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.Base64;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest
class SpringBootSessionApplicationTests {

@Test
public void sessionExpiry() throws Exception {
    ConfigurableApplicationContext context = createContext();
    String port = context.getEnvironment().getProperty("local.server.port");
    URI uri = URI.create("http://localhost:" + port + "/");
    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<String> firstResponse = firstRequest(restTemplate, uri);
    String sessionId1 = firstResponse.getBody();
    String cookie = firstResponse.getHeaders().getFirst("Set-Cookie");
    String sessionId2 = nextRequest(restTemplate, uri, cookie).getBody();
    assertThat(sessionId1).isEqualTo(sessionId2);
    Thread.sleep(1000);
    String loginPage = nextRequest(restTemplate, uri, cookie).getBody();
    assertThat(loginPage).containsIgnoringCase("login");
}

private ConfigurableApplicationContext createContext() {
    ConfigurableApplicationContext context = new SpringApplicationBuilder().sources(SpringBootSessionApplication.class)
            .properties("server.port:0", "server.servlet.session.timeout:1")
            .initializers(new ServerPortInfoApplicationContextInitializer()).run();
    return context;
}

private ResponseEntity<String> firstRequest(RestTemplate restTemplate, URI uri) {
    HttpHeaders headers = new HttpHeaders();
    headers.set("Authorization", "Basic " + Base64.getEncoder().encodeToString("user:password".getBytes()));
    RequestEntity<Object> request = new RequestEntity<>(headers, HttpMethod.GET, uri);
    return restTemplate.exchange(request, String.class);
}

private ResponseEntity<String> nextRequest(RestTemplate restTemplate, URI uri, String cookie) {
    HttpHeaders headers = new HttpHeaders();
    headers.set("Cookie", cookie);
    RequestEntity<Object> request = new RequestEntity<>(headers, HttpMethod.GET, uri);
    return restTemplate.exchange(request, String.class);
}

}

posted @ 2020-11-15 14:28  欧虞山  阅读(106)  评论(0编辑  收藏  举报