---
title: RestTemplate非推奨化に備えよう！RestClient入門、そしてリニューアルされたSpring Retryでリトライして、WireMockでテストする。 #jjug_ccc
tags:  #java #spring #spring-boot  
author: [tada](https://image.docswell.com/user/MasatoshiTada)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/LE3WVWXGE5.jpg?width=480
description: JJUG CCC 2026 Springの資料です。
published: May 30, 26
canonical: https://image.docswell.com/s/MasatoshiTada/K1QXMG-restclient-retry-wiremock
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/LE3WVWXGE5.jpg)

RestTemplate非推奨化に備えよう！
RestClient入門、
そしてリニューアルされた
Spring Retryでリトライして、
WireMockでテストする。
JJUG CCC 2026 Spring
2026年5月30日
多田真敏
1


# Page. 2

![Page Image](https://bcdn.docswell.com/page/8EDK8K2N7G.jpg)

このセッションについて
◆RestTemplateは、Springで外部Web APIにアクセスする際に
よく使われてきたクラスです。
◆しかしSpring公式から、RestTemplateはSpring 7.1で非推奨化
・Spring 8.0で削除されると発表されました。
◆このセッションでは、RestTemplateの代替であるRestClientの使い方を
紹介します。
◆加えて、Spring Framework 7でリニューアルされたSpring Retryを利用して、
RestClientと組み合わせてHTTPリクエストのリトライする方法を紹介します。
◆最後に、WireMockでモックサーバーを作成して、RestClientやリトライを
どのようにテストするかご紹介します。
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/V7PK8K1NJ8.jpg)

必要な前提知識
◆このセッションを理解するには、以下の前提知識が必要です
◆Spring DI・Spring MVCの利用経験
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/2JVVNVYYJQ.jpg)

前提知識を学べる資料
ハッシュタグ
書きました！
#つくまなBoot
6月発売予定
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/5EGLKL9WJL.jpg)

自己紹介
◆多田真敏（@suke_masa）
◆JJUG・JSUGスタッフ
◆クレジットカード会社で
社内システムの内製化＋AWS化
◆OSSドキュメントの和訳
◆Thymeleaf・Resilience4j
◆櫻坂46、北海道日本ハムファイターズ、
DB.スターマン、ゴジラ、英語学習
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/4JQYNYWQ7P.jpg)

対象バージョン
◆JDK 25
◆Spring Boot 4.1
バージョンが異なる場合、
この資料の説明が正しくない
可能性があります
◆Spring Boot利用前提で解説しています
◆Spring Bootを利用していない場合、
この資料では解説していない設定を追加する必要があります
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/K74WGWKYE1.jpg)

目次
① RestClientの使い方
② Spring Retryによるリトライ
③ WireMockを利用したRestClientのテスト
④ お知らせ
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/LJ1YDYXNEG.jpg)

目次
① RestClientの使い方
② Spring Retryによるリトライ
③ WireMockを利用したRestClientのテスト
④ お知らせ
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/GJWGYGKM72.jpg)

質問：HTTPクライアントは何を使ってますか？
◆RestTemplate？
◆RestClient？
◆WebClient？
◆その他？
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/4EZLXLZM73.jpg)

RestTemplateは将来的に非推奨＋削除
Spring 7.1で非推奨化
Spring 8で削除
https://spring.io/blog/2025/09/30/the-state-of-http-clients-in-spring
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/Y76W4WZ57V.jpg)

サンプルWeb API
◆複数件検索
GET /api/todos?keyword=a
200 OK
[{
&quot;id&quot;: 2,
&quot;description&quot;: &quot;Example 2&quot;,
&quot;completed&quot;: false,
&quot;deadline&quot;: &quot;2025-10-02T12:00:00&quot;,
&quot;createdAt&quot;: &quot;2025-09-02T12:00:00&quot;
}, {
&quot;id&quot;: 1,
&quot;description&quot;: &quot;Example 1&quot;,
&quot;completed&quot;: true,
&quot;deadline&quot;: &quot;2025-10-01T12:00:00&quot;,
&quot;createdAt&quot;: &quot;2025-09-01T12:00:00&quot;
}]
◆単一検索
GET /api/todos/1
200 OK
{
&quot;id&quot;: 1,
&quot;description&quot;: &quot;Example 1&quot;,
&quot;completed&quot;: true,
&quot;deadline&quot;: &quot;2025-10-01T12:00:00&quot;,
&quot;createdAt&quot;: &quot;2025-09-01T12:00:00&quot;
}
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/G75MQMWG74.jpg)

サンプルWeb API
◆追加
◆更新
POST /api/todos
{
&quot;description&quot;: &quot;Example 1&quot;,
&quot;deadline&quot;: &quot;2025-10-01T12:00:00&quot;,
}
PUT /api/todos/1
{
&quot;description&quot;: &quot;Example 1&quot;,
&quot;completed&quot;: true,
&quot;deadline&quot;: &quot;2025-10-01T12:00:00&quot;,
}
201 Created
Location: /api/todos/4
200 OK
◆完了
◆削除
PATCH /api/todos/1/done
DELETE /api/todos/1
200 OK
204 No Content
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/9J29P9QDER.jpg)

RestClientの生成
@Component
public class TodoClient {
private final RestClient restClient;
ビルダーが
Auto Configurationで
Bean定義済み
（スコープはprototype）
public RestClientTodoClient(
RestClient.Builder restClientBuilder,
@Value(&quot;${todo-service.base-url}&quot;) String baseUrl
) {
this.restClient = restClientBuilder.baseUrl(baseUrl)
.build();
}
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/DEY454WMJM.jpg)

application.properties
# 接続タイムアウト
spring.http.clients.connect-timeout=1s
# 読み取りタイムアウト
spring.http.clients.read-timeout=1s
# ClientHttpRequestFactory実装（後述）
spring.http.clients.imperative.factory=jdk
# リダイレクトに付いていくか否か
spring.http.clients.redirects=follow
# Cookieの扱い方法
spring.http.clients.cookie-handling=enable
# 利用するSSLバンドル
spring.http.clients.ssl.bundle=xxx
特にタイムアウト設定は
忘れずに
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/VJNYNY9378.jpg)

GET（単一検索）
public TodoResponse getById(Integer id) {
TodoResponse todoResponse = restClient.get()
.uri(&quot;/api/todos/&quot; + id)
.retrieve()
.body(TodoResponse.class);
return todoResponse;
}
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/YE9PRP2PJ3.jpg)

GET（複数件検索）
public List&lt;TodoResponse&gt; getByKeyword(String keyword) {
List&lt;TodoResponse&gt; todoResponseList = restClient.get()
.uri(&quot;/api/todos?keyword=&quot; + keyword)
.retrieve()
.body(new ParameterizedTypeReference&lt;&gt;(){});
return todoResponseList;
}
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/GE8DWD5XED.jpg)

POST
public URI register(TodoRequest request) {
ResponseEntity&lt;Void&gt; responseEntity = restClient.post()
.uri(&quot;/api/todos&quot;)
.body(request)
.retrieve()
.toBodilessEntity();
URI location = responseEntity.getHeaders().getLocation();
return location;
}
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/LELMNMYN7R.jpg)

PUT
public void update(Integer id, TodoRequest request) {
restClient.put()
.uri(&quot;/api/todos/&quot; + id)
.body(request)
.retrieve()
.toBodilessEntity();
}
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/4JMYXYNQJW.jpg)

DELETE
public void delete(Integer id) {
restClient.delete()
.uri(&quot;/api/todos/&quot; + id)
.retrieve()
.toBodilessEntity();
}
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/PJR9N9DK79.jpg)

PATCH
public void patch(Integer id) {
restClient.patch()
.uri(&quot;/api/todos/&quot; + id + &quot;/done&quot;)
.retrieve()
.toBodilessEntity();
}
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/PEXQNQ15JX.jpg)

レスポンスが4xx・5xxの場合
◆デフォルトでは即座に例外
◆各ステータスコードでの挙動はdefaultStatusHandler()で
変更可能
// 4xx・5xxでも例外を発生させない例
this.restClient = restClientBuilder.baseUrl(baseUrl)
.defaultStatusHandler(
status -&gt; true,
(request, response) -&gt; {
// 何もしない
}
).build();
21


# Page. 22

![Page Image](https://bcdn.docswell.com/page/3EK9N92RED.jpg)

RestClientで発生する例外
タイムアウト等
RestClientException
ResourceAccess
Exception
RestClientResponse
Exception
HttpStatusCodeException
4xx
例外
HttpClientErrorException
NotFound
TooMany
Requests
・・・
5xx
例外
UnknownContentType
Exception
UnknownHttpStatusCodeException
HttpServerErrorException
InternalServerError
・・・
22


# Page. 23

![Page Image](https://bcdn.docswell.com/page/L73WVW4G75.jpg)

ResClientの中を見てみよう
◆RestClientはインタフェース
→ 実装クラスはDefaultRestClient
◆https://github.com/spring-projects/springframework/blob/main/spring-
web/src/main/java/org/springframework/web/client/DefaultR
estClient.java
23


# Page. 24

![Page Image](https://bcdn.docswell.com/page/87DK8KQNJG.jpg)

RestClientの登場人物
◆ClientHttpRequest / ClientHttpResponse
◆リクエスト・レスポンスを表すインタフェース
◆ClientHttpRequestFactory
◆ClientHttpRequestを生成するインタフェース
◆HttpMessageConverter
◆クラスとHTTPボディ（JSON・XMLなど）の相互変換を行う
インタフェース
24


# Page. 25

![Page Image](https://bcdn.docswell.com/page/VJPK8KLNE8.jpg)

ざっくりとしたシーケンス図
外部システム
25


# Page. 26

![Page Image](https://bcdn.docswell.com/page/2EVVNVQYEQ.jpg)

ClientHttpRequestFactory実装一覧
◆JdkClientHttpRequestFactory（デフォルト）
◆java.net.http.HttpClientを利用
◆HttpComponentsClientHttpRequestFactory
◆Apache HttpComponentsを利用
◆JettyClientHttpRequestFactory
◆Jettyを利用
◆ReactorClientHttpRequestFactory
◆Reactor Nettyを利用
◆SimpleClientHttpRequestFactory
◆java.net.HttpURLConnectionを利用（PATCHができない制限あり）
26


# Page. 27

![Page Image](https://bcdn.docswell.com/page/57GLKLWWEL.jpg)

ClientHttpRequestFactory実装の指定
◆application.propertiesで指定
◆ライブラリの依存関係でHttpComponentsなどが含まれる
可能性もあるため、明示的に指定したほうが安全
27


# Page. 28

![Page Image](https://bcdn.docswell.com/page/4EQYNY3QJP.jpg)

まとめ
◆RestTemplateがSpring 7.1で非推奨化、
Spring 8.0で削除予定 → RestClientに移行しましょう！
◆RestClientはメソッドチェーンで書く！
◆例外や内部実装などをしっかり押さえよう！
28


# Page. 29

![Page Image](https://bcdn.docswell.com/page/KJ4WGW1Y71.jpg)

目次
① RestClientの使い方
② Spring Retryによるリトライ
③ WireMockを利用したRestClientのテスト
④ お知らせ
29


# Page. 30

![Page Image](https://bcdn.docswell.com/page/LE1YDYGN7G.jpg)

リトライの重要性
◆ネットワーク越しに別システムにアクセスする際は、
様々な理由でタイムアウトが起こったりする
◆クラウド環境では、瞬間的なネットワークの不調が
たまに起こったりする
◆クラウドのオートスケールの力で、数秒後には相手システムが
復旧しているかもしれない
同じリクエストをもう一度送信（＝リトライ）すれば、
問題が解決しているかもしれない
30


# Page. 31

![Page Image](https://bcdn.docswell.com/page/GEWGYG5MJ2.jpg)

Spring Retry
◆Spring Framework本体に含まれている、
リトライのためのAPI
◆かつては別のライブラリだったが、Spring Framework 7から
本体に再実装された
◆APIは微妙に変わっているので注意
31


# Page. 32

![Page Image](https://bcdn.docswell.com/page/47ZLXLNMJ3.jpg)

Spring Retryによるリトライ方法
① RetryTemplate
◆ラムダ式を利用してリトライを記述する
個人的には
こちらがおすすめ
◆Beanでなくてもリトライ可能
② AOP
◆AOPによる割り込み処理でリトライする
◆AOPを使うので、Beanに対してのみリトライ可能
◆RetryListenerを使えない制限あり
32


# Page. 33

![Page Image](https://bcdn.docswell.com/page/YJ6W4W85JV.jpg)

①RetryTemplate
◆RetryTemplateのインスタンス化
RetryPolicy retryPolicy = RetryPolicy.builder()
.delay(Duration.ofSeconds(1)) // リトライ間隔時間
.multiplier(1.0) // リトライ間隔時間を何倍ずつ増やすか
.maxRetries(2) // 最大リトライ回数
.includes( // リトライ対象の例外
HttpServerErrorException.class,
HttpClientErrorException.TooManyRequests.class)
.build();
RetryTemplate retryTemplate = new RetryTemplate(retryPolicy);
33


# Page. 34

![Page Image](https://bcdn.docswell.com/page/GJ5MQM9GJ4.jpg)

①RetryTemplate
◆RetryListenerの作成
public class LoggingRetryListener implements RetryListener {
/// 毎回の失敗した試行の後に呼び出されます。
@Override
public void onRetryFailure(RetryPolicy p, Retryable&lt;?&gt; r, Throwable th) {
logger.warn(&quot;試行に失敗しました。例外={}&quot;, th.getMessage());
}
/// 全試行が上限に達した場合に呼び出されます。
@Override
public void onRetryPolicyExhaustion(
RetryPolicy p, Retryable&lt;?&gt; r, RetryException e) {
logger.error(&quot;試行が上限に達しました。例外={}&quot;,
e.getLastException().getMessage());
}
}
34


# Page. 35

![Page Image](https://bcdn.docswell.com/page/9E29P92D7R.jpg)

①RetryTemplate
◆RetryListenerの設定
retryTemplate.setRetryListener(new LoggingRetryListener());
35


# Page. 36

![Page Image](https://bcdn.docswell.com/page/D7Y454YMEM.jpg)

①RetryTemplate
◆リトライの実装
リトライしたい処理を
引数のラムダ式で記述
try {
TodoResponse todoResponse = retryTemplate.execute(() -&gt;
restClient.get().uri(&quot;/api/todos/&quot; + id)
.retrieve().body(TodoResponse.class));
return todoResponse;
} catch (RetryException e) {
Throwable lastException = e.getLastException();
最大リトライ回数
if (lastException instanceof RestClientException rce) {
でも失敗すると
throw rce;
RetryException
} else {
最後にスローされた
(チェック例外)
throw new RuntimeException(e);
例外を取得
}
}
36


# Page. 37

![Page Image](https://bcdn.docswell.com/page/VENYNYP3J8.jpg)

②AOP
@Configuration
@EnableResilientMethods
public class AppConfig { ... }
リトライしたいメソッドに
@Component
アノテーションを付加
public class クラス名 {
@Retryable(
delay = 1_000,
multiplier = 1.0,
maxRetries = 2,
includes = {HogeException.class, FugaException.class}
)
public 戻り値の型 メソッド名() {
// 処理
}
}
37


# Page. 38

![Page Image](https://bcdn.docswell.com/page/Y79PRP3PE3.jpg)

リトライする前に考えるべきこと
①リトライで問題が解決するのか？
◆リトライで解決する可能性がある異常
◆タイムアウト
◆ステータスコード5xx
◆ステータスコード429 Too Many Requests
◆リトライでは解決しない異常
◆429以外のステータスコード4xx
38


# Page. 39

![Page Image](https://bcdn.docswell.com/page/G78DWDMX7D.jpg)

リトライする前に考えるべきこと
②クライアントをどれだけ待たせられるか？
◆リトライするとクライアントの待ち時間が長くなる
◆場合によってはリトライしないことも考慮に入れる
◆リトライ間の待ち時間（＝バックオフ）を決める
◆固定バックオフ、指数関数的バックオフ、ランダムバックオフなどが
ある
◆最大リトライ回数を決める
39


# Page. 40

![Page Image](https://bcdn.docswell.com/page/L7LMNM3NJR.jpg)

リトライする前に考えるべきこと
③リトライして問題にならないか？
◆GET・PUT・DELETEなどは冪等 → 考慮は不要
◆POST・PATCHは冪等でない
→ Idempotency-KeyリクエストヘッダーにUUIDなどを
設定することで、同一のリクエストかどうかを判断して
データの2重登録などを防ぐ
◆詳細はMDNを参照 → https://developer.mozilla.org/enUS/docs/Web/HTTP/Reference/Headers/Idempotency-Key
40


# Page. 41

![Page Image](https://bcdn.docswell.com/page/4EMYXYDQEW.jpg)

まとめ
◆Spring Retryでリトライを実装できる！
◆リトライする前にいろいろ考えることがあります
41


# Page. 42

![Page Image](https://bcdn.docswell.com/page/PER9N94KJ9.jpg)

目次
① RestClientの使い方
② Spring Retryによるリトライ
③ WireMockを利用したRestClientのテスト
④ お知らせ
42


# Page. 43

![Page Image](https://bcdn.docswell.com/page/P7XQNQ25EX.jpg)

テスト用モックサーバー、どれ使う？
◆MockRestServiceServer
◆Spring謹製。実際にサーバーは起動しない
◆WireMock
◆OSSのモックサーバー
◆MockServer
◆ここしばらく開発が止まっている → 2026年5月から活動再開
43


# Page. 44

![Page Image](https://bcdn.docswell.com/page/37K9N9MR7D.jpg)

WireMockを使う
&lt;dependencies&gt;
...
&lt;dependency&gt;
&lt;groupId&gt;org.wiremock&lt;/groupId&gt;
&lt;artifactId&gt;wiremock-standalone&lt;/artifactId&gt;
&lt;version&gt;3.13.2&lt;/version&gt;
&lt;scope&gt;test&lt;/scope&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
44


# Page. 45

![Page Image](https://bcdn.docswell.com/page/LJ3WVWYGJ5.jpg)

WireMockでテスト
@SpringBootTest
public class TodoClientTest {
@Autowired
TodoClient todoClient;
@RegisterExtension
static WireMockExtension wireMock = WireMockExtension.newInstance()
.options(wireMockConfig()
.http2PlainDisabled(true)
HTTP2無効化＋ポート番号指定
.port(9999))
.build();
// 次のスライドへ
45


# Page. 46

![Page Image](https://bcdn.docswell.com/page/8JDK8K5NEG.jpg)

調査したけどよく分かっていないこと
◆HTTP2を有効化していると、なぜか一部のテストが落ちる
◆@ExtendWith(WireMockExtension.class)だと、
なぜか一部のテストが落ちる
◆見識をお持ちの方、ぜひ教えてください・・・
46


# Page. 47

![Page Image](https://bcdn.docswell.com/page/VEPK8KGN78.jpg)

WireMockでテスト
①正常時
@Test @DisplayName(&quot;IDを指定すると、該当するTODOを取得できる&quot;)
void success() {
// WireMockの設定
wireMock.stubFor(get(&quot;/api/todos/1&quot;)
.willReturn(okJson(&quot;&quot;&quot;
{&quot;id&quot;: 1, &quot;description&quot;: &quot;Example 1&quot;,&quot;completed&quot;: true,
&quot;deadline&quot;: &quot;2025-10-01T12:00:00&quot;,
&quot;createdAt&quot;: &quot;2025-09-01T12:00:00&quot;}&quot;&quot;&quot;)));
// テストの実行
TodoResponse actual = todoClient.getById(1);
// 結果の検証
assertEquals(
new TodoResponse(1, &quot;Example 1&quot;, true,
LocalDateTime.parse(&quot;2025-10-01T12:00:00&quot;),
LocalDateTime.parse(&quot;2025-09-01T12:00:00&quot;)
), actual);
}
47


# Page. 48

![Page Image](https://bcdn.docswell.com/page/27VVNV6Y7Q.jpg)

WireMockでテスト
②異常時
@Test @DisplayName(&quot;該当するIDのTODOがない場合は、例外が発生する&quot;)
void empty() {
// WireMockの設定
wireMock.stubFor(get(&quot;/api/todos/999&quot;)
.willReturn(notFound().withBody(&quot;&quot;&quot;
{
&quot;type&quot;: &quot;about:blank&quot;,
&quot;status&quot;: 404,
&quot;title&quot;: &quot;Not Found&quot;,
&quot;detail&quot;: &quot;該当するTODOが見つかりません。&quot;,
&quot;instance&quot;: &quot;/api/todos/999&quot;,
}
&quot;&quot;&quot;)));
// テストの実行と例外の検証
assertThrows(HttpClientErrorException.NotFound.class,
() -&gt; todoClient.getById(999)
);
}
48


# Page. 49

![Page Image](https://bcdn.docswell.com/page/5JGLKLNW7L.jpg)

WireMockでテスト
③リトライ
@Test
@DisplayName(&quot;500-&gt;500-&gt;200とレスポンスされると、指定したID該当するTODOを取得できる&quot;)
void retrySuccess() {
// 1回目は500
wireMock.stubFor(get(&quot;/api/todos/1&quot;)
.inScenario(&quot;TODO&quot;).whenScenarioStateIs(Scenario.STARTED)
.willReturn(serverError().withBody(&quot;&lt;エラー時のレスポンスボディ&gt;&quot;))
.willSetStateTo(&quot;SECOND&quot;));
// 2回目も500
wireMock.stubFor(get(&quot;/api/todos/1&quot;)
.inScenario(&quot;TODO&quot;).whenScenarioStateIs(&quot;SECOND&quot;)
.willReturn(serverError().withBody(&quot;&lt;エラー時のレスポンスボディ&gt;&quot;))
.willSetStateTo(&quot;THIRD&quot;));
// 3回目は200
wireMock.stubFor(get(&quot;/api/todos/1&quot;)
.inScenario(&quot;TODO&quot;).whenScenarioStateIs(&quot;THIRD&quot;)
.willReturn(okJson(&quot;&lt;正常なレスポンスボディ&gt;&quot;)));
// 次頁に続く
49


# Page. 50

![Page Image](https://bcdn.docswell.com/page/47QYNYQQEP.jpg)

WireMockでテスト
③リトライ
// 時間の計測開始（org.springframework.util.StopWatchクラス）
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// テストの実行
TodoResponse actual = todoClient.getById(1);
// 時間の計測終了
stopWatch.stop();
int seconds = (int) stopWatch.getTotalTimeSeconds();
// 結果の検証
assertAll(
() -&gt; assertEquals(new TodoResponse(...), actual),
() -&gt; assertEquals(2, seconds)
リトライした分だけの時間がかかっているか
);
も
}
検証したほうがいい
（たまにちゃんとリトライできてないことが
ある）
50


# Page. 51

![Page Image](https://bcdn.docswell.com/page/KE4WGWNYJ1.jpg)

まとめ
◆Wiremockてテスト用モックサーバーを作れる！
◆リトライのテストもできる！
51


# Page. 52

![Page Image](https://bcdn.docswell.com/page/L71YDY5NJG.jpg)

目次
① RestClientの使い方
② Spring Retryによるリトライ
③ WireMockを利用したRestClientのテスト
④ お知らせ
52


# Page. 53

![Page Image](https://bcdn.docswell.com/page/G7WGYGWME2.jpg)

Jakarta EEの勉強会やります！
◆日時: 2026-06-22(月) 19:00-21:00
◆場所: 恵比寿のRed Hat様セミナールーム
◆テーマ
◆Jakarta EE 12 が変えるデータアクセスの新仕様：Data, NoSQL,
Query 解説（by 景井さん）
◆ついにMVCがJakarta EEに。その歴史・機能・アーキテクチャを知ろ
う
（by 多田）
53


# Page. 54

![Page Image](https://bcdn.docswell.com/page/4JZLXL5ME3.jpg)

頑張って書いたので買ってください
ハッシュタグ
書きました！
#つくまなBoot
6月発売予定
54


# Page. 55

![Page Image](https://bcdn.docswell.com/page/YE6W4W95EV.jpg)

ご清聴ありがとうございました！
◆よいSpringライフを！
55


