Spring Session JDBC的使用 - javadevjournal

banq發表於2020-06-11

在本文中,我們將看到如何將Spring Session與JDBC一起使用。Spring Session提供了一種透明的方法來解決HTTP會話的限制。它提供了中央會話管理,而不必依賴於特定於容器或伺服器的解決方案(例如Tomcat,Jetty等)。它提供了不同的選項來儲存和管理會話資訊。在本文中,我們將逐步完成將JDBC與Spring Session整合的步驟。
如果您使用的是Spring Boot,則需要在應用程式的pom.xml檔案中新增以下依賴項:

<dependencies>
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-jdbc</artifactId>
    </dependency>
    <!-- Adding this to  have datasource and other feature available to us -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>


我們不需要為Spring會話新增依賴項,因為Spring Boot會自動啟用的。基於以上配置,Spring Boot自動配置將為我們處理其餘配置。作為最後一步,我們需要通知Spring Boot使用jdbc來儲存會話資訊。在application.properties檔案中新增以下屬性:

spring.session.store-type=jdbc # Session store type.


如果僅使用單個會話模組,則可以從application.properties檔案中省略上述屬性。Spring Boot自動使用預設jdbc儲存實現。如果有一個以上的實現,則必須指定上述屬性。

在使用JDBC支援的spring會話之前,我們需要在應用程式中新增一些屬性。屬性檔案:

spring.datasource.url=jdbc:mysql://localhost:3306/spring-session-jdbc
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver


為了使Spring會話能夠使用我們的JDBC配置,它需要在資料庫中建立一個特定的表,我們可以在以下屬性的幫助下啟用此功能:

spring.session.jdbc.initialize-schema=always


啟用這些屬性後,如果我們指定spring.session.jdbc.initialize-schema=never,則需要手動建立會話表。Spring會話JDBC jar包含用於建立所需架構的SQL指令碼。您可以在org.springframework.session.jdbc軟體包中發現並檢查jar包。
這是MySQL資料庫的表結構:

CREATE TABLE SPRING_SESSION (
    PRIMARY_ID CHAR(36) NOT NULL,
    SESSION_ID CHAR(36) NOT NULL,
    CREATION_TIME BIGINT NOT NULL,
    LAST_ACCESS_TIME BIGINT NOT NULL,
    MAX_INACTIVE_INTERVAL INT NOT NULL,
    EXPIRY_TIME BIGINT NOT NULL,
    PRINCIPAL_NAME VARCHAR(100),
    CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;

CREATE UNIQUE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (EXPIRY_TIME);
CREATE INDEX SPRING_SESSION_IX3 ON SPRING_SESSION (PRINCIPAL_NAME);

CREATE TABLE SPRING_SESSION_ATTRIBUTES (
    SESSION_PRIMARY_ID CHAR(36) NOT NULL,
    ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
    ATTRIBUTE_BYTES BLOB NOT NULL,
    CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
    CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;


如果您使用  @EnableJdbcHttpSession,則上述資料表配置將不起作用。這意味著我們正在顯式配置Spring Session,因此Spring Boot不會自動建立這個表。為了處理這個用例,我們有以下兩種選擇。
  • 不要使用  @EnableJdbcHttpSessionSpring Boot,透過自動配置來處理它。
  • 如果繼續使用@EnableJdbcHttpSession註釋,請手動建立表結構。

讓我們建立一個簡單的REST控制器來檢視實際的會話處理:

@RestController
public class GreetingController {

    @GetMapping("/")
    public @ResponseBody ResponseEntity<List> getMessage(Model model, HttpSession session) {
        List greetings = (List) session.getAttribute("GREETING_MESSAGES");
        if(greetings == null) {
            greetings = new ArrayList<>();
        }

        return new ResponseEntity<List>(greetings,HttpStatus.OK);
    }

    @PostMapping("/messages")
    public @ResponseBody ResponseEntity<List> saveMessage(@RequestParam("message") String greeting, HttpServletRequest request)
    {
        List greetings = (List) request.getSession().getAttribute("GREETING_MESSAGES");
        if(greetings == null) {
            greetings = new ArrayList<>();
            request.getSession().setAttribute("GREETING_MESSAGES", greetings);
        }
        greetings.add(greeting);
        return new ResponseEntity<List>(greetings,HttpStatus.OK);
    }
}


主類:

@SpringBootApplication
@EnableJdbcHttpSession
public class SpringSessionWithJdbcApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringSessionWithJdbcApplication.class, args);
    }
}

唯一有趣的一點是@EnableJdbcHttpSession註釋。

如果我們執行應用程式並訪問端點。具有JDBC配置的Spring Session將透明地處理會話管理。Spring會話透明地處理這個問題。@EnableJdbcHttpSession註釋建立了一個Spring Bean,其名稱springSessionRepositoryFilter實現了Filter。該過濾器負責替換由Spring Session支援的HttpSession實現。
 

相關文章