SAP BTP 学習日記 Day5 —— CAP Java Handler 入門:@Before・@After イベントでビジネスロジックを実装
今日の学習内容
今日から CAP Java の学習を始めました。今まで Node.js 版で学んできた CAP の知識を活かしながら、Java ならではのビジネスロジック実装方法を学びました。
① 環境セットアップ(Java 21 + Maven)
# Java 21 インストール
sudo apt install -y openjdk-21-jdk
# Maven インストール
sudo apt install -y maven
# バージョン確認
java --version
mvn --version② CAP Java プロジェクトの作成
Maven の archetype を使って CAP Java プロジェクトを作成します。
mvn -B archetype:generate -DarchetypeArtifactId=cds-services-archetype -DarchetypeGroupId=com.sap.cds -DarchetypeVersion=RELEASE -DgroupId=com.example -DartifactId=my-cap-java -Dpackage=com.example.bookshop作成されるプロジェクト構造:
my-cap-java/
├── db/ ← CDS データモデル
├── srv/ ← CDS サービス + Java Handler
│ └── src/main/java/
│ └── com/example/bookshop/
│ └── Application.java
├── pom.xml ← Maven 設定
└── package.json③ gen/ フォルダの仕組み
CAP Java の重要な概念として、CDS ファイルから Java クラスが自動生成されます。
db/schema.cds + srv/cat-service.cds
↓ mvn compile
srv/src/gen/java/cds/gen/
├── catalogservice/
│ ├── Books.java ← getter/setter 付きデータクラス
│ ├── Books_.java ← メタ情報(CDS_NAME など)
│ └── CatalogService_.java
└── my/bookshop/
└── Books.java⚠️ 重要:
gen/フォルダは絶対に手動で編集しないこと!mvn compileするたびに上書きされます。
④ Java Handler の実装
CAP Java では Handler クラスを作成してビジネスロジックを実装します。イベントには @Before・@On・@After の3種類があります。
| アノテーション | タイミング | 主な用途 |
|---|---|---|
@Before | DB 保存の前 | バリデーション・データ加工 |
@On | DB 保存の代わり | 完全カスタムロジック |
@After | DB 保存の後 | ログ・通知・後処理 |
実装したコード
@Component
@ServiceName(CatalogService_.CDS_NAME)
public class CatalogServiceHandler implements EventHandler {
// ① Before:登録前のバリデーション
@Before(event = CqnService.EVENT_CREATE, entity = Books_.CDS_NAME)
public void beforeCreateBooks(List<Books> books) {
for (Books book : books) {
if (book.getStock() != null && book.getStock() < 0) {
throw new IllegalArgumentException(
"在庫数は0以上でなければなりません。"
);
}
if (book.getPrice() != null && book.getPrice().signum() <= 0) {
throw new IllegalArgumentException(
"価格は0より大きくなければなりません。"
);
}
}
}
// ② After:登録後のログ出力
@After(event = CqnService.EVENT_CREATE, entity = Books_.CDS_NAME)
public void afterCreateBooks(List<Books> books) {
for (Books book : books) {
System.out.println(
"✅ 新しい本が登録されました: [ID=" + book.getId() +
", タイトル=" + book.getTitle() +
", 在庫=" + book.getStock() + "]"
);
}
}
// ③ After READ:在庫切れ警告
@After(event = CqnService.EVENT_READ, entity = Books_.CDS_NAME)
public void afterReadBooks(List<Books> books) {
for (Books book : books) {
if (book.getStock() != null && book.getStock() == 0) {
System.out.println(
"⚠️ 在庫切れ: [ID=" + book.getId() +
", タイトル=" + book.getTitle() + "]"
);
}
}
}
}⑤ 動作確認
CAP Java は Spring Boot で起動するため、ポートが Node.js 版と異なります。
| CAP Node.js | CAP Java | |
|---|---|---|
| 起動コマンド | cds watch | mvn spring-boot:run |
| ポート | 4004 | 8080 |
| サービスパス | /odata/v4/catalog | /odata/v4/CatalogService |
バリデーションテスト(在庫 -1 でエラー):
POST http://localhost:8080/odata/v4/CatalogService/Books
{
"ID": 2,
"title": "Invalid Book",
"stock": -1,
"price": 4800.00
}
→ {"error":{"code":"500","message":"在庫数は0以上でなければなりません。"}}イベント処理の流れ
リクエスト受信
↓
@Before ← バリデーション・データ加工
↓
@On ← DB操作(省略時は CAP が自動処理)
↓
@After ← ログ・通知・後処理
↓
レスポンス返却この記事は「SAP BTP 学習」シリーズの第5回です。6ヶ月間の独学で SAP BTP 開発へのキャリアチェンジを目指しています。
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 TKblog
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果