JDBCとのSpringセッション

1概要

このクイックチュートリアルでは、SpringセッションJDBCを使用してセッション情報をデータベースに永続化する方法を学習します。

デモンストレーション目的で、インメモリH2データベースを使用します。

2設定オプション

私たちのサンプルプロジェクトを作成する最も簡単で最速の方法は Spring Boot を使うことです。ただし、設定を行うための起動以外の方法も示します。

したがって、あなたはセクション3と4の両方を完成する必要はありません。私たちが Spring Session を設定するために Spring Boot を使っているかどうかに応じて一つを選んでください。

3スプリングブート設定

まず、Spring Session JDBCに必要な設定を見てみましょう。

3.1. Mavenの依存関係

まず、これらの依存関係をプロジェクトに追加する必要があります。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.197</version>
    <scope>runtime</scope>
</dependency>

私たちのアプリケーションは Spring Boot で動いています、そして、親 pom.xml は各エントリーのためのバージョンを提供します。それぞれの依存関係の最新版はここで見つけることができます:https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.boot%22%20AND%20a%3A%22spring- boot-starter-web%22[spring-boot-starter-web]、https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.boot%22%20AND% 20a%3A%22spring-boot-starter-test%22[spring-boot-starter-test、] https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework。 session%22%20AND%20a%3A%22spring-session-jdbc%22[spring-session-jdbc]、およびh2。

驚くべきことに、リレーショナルデータベースによって支えられたSpring Sessionを有効にするために 必要な唯一の設定プロパティは application.properties :

spring.session.store-type=jdbc

4標準スプリング設定(スプリングブートなし)

Spring Bootを使用せずにSpringセッションを統合および構成する方法についても説明します。通常のSpringを使用した場合だけです。

4.1. Mavenの依存関係

まず、標準のSpringプロジェクトに spring-session-jdbc を追加する場合は、https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframeworkを追加する必要があります。 .session%22%20AND%20a%3A%22spring-session-jdbc%22[spring-session-jdbc]およびhttps://search.maven.org/classic/#search%7C1%7Cg%3A%22com .h2database%22%20AND%20a%3A%22h2%22[h2]から pom.xml へ(前のセクションのスニペットからの最後の2つの依存関係)。

4.2. Springセッション構成

それでは、 Spring Session JDBC の設定クラスを追加しましょう。

@Configuration
@EnableJdbcHttpSession
public class Config
  extends AbstractHttpSessionApplicationInitializer {

    @Bean
    public EmbeddedDatabase dataSource() {
        return new EmbeddedDatabaseBuilder()
          .setType(EmbeddedDatabaseType.H2)
          .addScript("org/springframework/session/jdbc/schema-h2.sql").build();
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

ご覧のとおり、違いはごくわずかです。今度は EmbeddedDatabase __PlatformTransactionManager __beansを明示的に定義する必要があります - Spring Bootは以前の設定でそれを行います。

上記は、 springSessionRepositoryFilter という名前のSpring Beanがすべてのリクエストに対して Servlet Container に登録されることを保証します。

5簡単なアプリ

それでは、セッションの永続性を実証するための簡単なREST APIを見てみましょう。 __

5.1. コントローラ

まず、 HttpSession に情報を格納および表示するための Controller クラスを追加しましょう。

@Controller
public class SpringSessionJdbcController {

    @GetMapping("/")
    public String index(Model model, HttpSession session) {
        List<String> favoriteColors = getFavColors(session);
        model.addAttribute("favoriteColors", favoriteColors);
        model.addAttribute("sessionId", session.getId());
        return "index";
    }

    @PostMapping("/saveColor")
    public String saveMessage
      (@RequestParam("color") String color,
      HttpServletRequest request) {

        List<String> favoriteColors
          = getFavColors(request.getSession());
        if (!StringUtils.isEmpty(color)) {
            favoriteColors.add(color);
            request.getSession().
              setAttribute("favoriteColors", favoriteColors);
        }
        return "redirect:/";
    }

    private List<String> getFavColors(HttpSession session) {
        List<String> favoriteColors = (List<String>) session
          .getAttribute("favoriteColors");

        if (favoriteColors == null) {
            favoriteColors = new ArrayList<>();
        }
        return favoriteColors;
    }
}

6. 実装のテスト

GETメソッドとPOSTメソッドを持つAPIができたので、次に両方のメソッドを呼び出すテストを書きましょう。

いずれの場合も、セッション情報がデータベースに保持されていることを表明できます。これを確認するには、セッションデータベースに直接問い合わせます。

最初に設定しましょう。

@RunWith(SpringRunner.class)
@SpringBootTest(
  webEnvironment = SpringBootTest.WebEnvironment.RANDOM__PORT)
@FixMethodOrder(MethodSorters.NAME__ASCENDING)
public class SpringSessionJdbcApplicationTests {

    @LocalServerPort
    private int port;

    @Autowired
    private TestRestTemplate testRestTemplate;

    private List<String> getSessionIdsFromDatabase()
      throws SQLException {

        List<String> result = new ArrayList<>();
        ResultSet rs = getResultSet(
          "SELECT **  FROM SPRING__SESSION");

        while (rs.next()) {
            result.add(rs.getString("SESSION__ID"));
        }
        return result;
    }

    private List<byte[]> getSessionAttributeBytesFromDb()
      throws SQLException {

        List<byte[]> result = new ArrayList<>();
        ResultSet rs = getResultSet(
          "SELECT **  FROM SPRING__SESSION__ATTRIBUTES");

        while (rs.next()) {
            result.add(rs.getBytes("ATTRIBUTE__BYTES"));
        }
        return result;
    }

    private ResultSet getResultSet(String sql)
      throws SQLException {

        Connection conn = DriverManager
          .getConnection("jdbc:h2:mem:testdb", "sa", "");
        Statement stat = conn.createStatement();
        return stat.executeQuery(sql);
    }
}

テストケースの実行順序を制御するための @ FixMethodOrder(MethodSorters.NAME ASCENDING) の使用に注意してください。 __詳しくはhttps://www.baeldung.com/junit-5-test-order[こちら]をご覧ください。

データベースのセッションテーブルが空であることを表明することから始めましょう。

@Test
public void whenH2DbIsQueried__thenSessionInfoIsEmpty()
  throws SQLException {

    assertEquals(
      0, getSessionIdsFromDatabase().size());
    assertEquals(
      0, getSessionAttributeBytesFromDatabase().size());
}

次に、GETエンドポイントをテストします。

@Test
public void whenH2DbIsQueried__thenOneSessionIsCreated()
  throws SQLException {

    assertThat(this.testRestTemplate.getForObject(
      "http://localhost:" + port + "/", String.class))
      .isNotEmpty();
    assertEquals(1, getSessionIdsFromDatabase().size());
}

APIが初めて呼び出されると、セッションが作成されてデータベースに保持されます。ご覧のとおり、この時点で __SPRING SESSION ____テーブルには1行しかありません。

最後に、好みの色を指定してPOSTエンドポイントをテストします。

@Test
public void whenH2DbIsQueried__thenSessionAttributeIsRetrieved()
  throws Exception {

    MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
    map.add("color", "red");
    this.testRestTemplate.postForObject(
      "http://localhost:" + port + "/saveColor", map, String.class);
    List<byte[]> queryResponse = getSessionAttributeBytesFromDatabase();

    assertEquals(1, queryResponse.size());
    ObjectInput in = new ObjectInputStream(
      new ByteArrayInputStream(queryResponse.get(0)));
    List<String> obj = (List<String>) in.readObject();
    assertEquals("red", obj.get(0));
}

予想通り、 __ SPRING SESSION ATTRIBUTES tableはお気に入りの色を保持します。 Springはデータベースにセッション属性を永続化するときにオブジェクトの直列化を行うので、 ATTRIBUTE BYTES __の内容を String__オブジェクトのリストに逆シリアル化する必要があることに注意してください。

7. どのように動作しますか?

コントローラを見ると、データベースがセッション情報を保持していることを示すものはありません。すべての魔法は、私たちが application.properties に追加した1行で行われています。

つまり、** 背後で spring.session.store-type = jdbc、 を指定すると、Spring Bootは @ EnableJdbcHttpSession アノテーションを手動で追加するのと同じ設定を適用します。

これは、SessionRepositoryFilterを実装するs __pringSessionRepositoryFilter __という名前のSpring Beanを作成します。

もう1つの重要な点は、フィルタがすべての HttpServletRequest をインターセプトし、それを SessionRepositoryRequestWrapper にラップすることです。

セッション情報を永続化するために commitSession メソッドも呼び出します。

8 H2データベースに保存されたセッション情報

以下のプロパティを追加することで、セッション情報がURL(http://localhost:8080/h2-console/)から格納されているテーブルを見ることができます。

spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

9.まとめ

Spring Sessionは分散システムアーキテクチャでHTTPセッションを管理するための強力なツールです。 Springは、最小限の設定で事前定義されたスキーマを提供することによって、単純なユースケースの重い負担を軽減します。同時に、セッション情報をどのように格納したいのかという私たちの設計を思いつくための柔軟性を提供します。

最後に、Spring Sessionを使って認証情報を管理するには、この記事 - Spring Sessionのガイド - を参照してください。

いつものように、あなたはソースコードhttps://github.com/eugenp/tutorials/tree/master/spring-session/spring-session-jdbc[Githubで動く]を見つけることができます。