SpringのCreditCardNumberアノテーションを完全解説!初心者でもわかるクレジットカード番号の入力チェック
生徒
「Spring Bootの入力フォームで、クレジットカード番号が正しい形式かどうかを簡単にチェックする方法はありますか?」
先生
「Hibernate Validatorが提供する@CreditCardNumberアノテーションを使うと、クレジットカード番号として入力された数字がLuhnアルゴリズムによる検査を通るか確認できます。」
生徒
「そのアノテーションを付ければ、本当に使えるカードかどうかまで分かるんですか?」
先生
「そこは大切な違いです。番号の計算上の整合性を確認するための機能なので、カードが実在するか、利用できる状態かまでは判断できません。基本から順番に見ていきましょう。」
1. CreditCardNumberアノテーションとは?
Spring Bootでフォーム入力のバリデーションを実装するときは、Jakarta ValidationとHibernate Validatorを利用する方法が一般的です。@CreditCardNumberは、Hibernate Validatorが用意しているクレジットカード番号向けの制約アノテーションです。フォームやリクエストで受け取った文字列が、クレジットカード番号として計算上妥当な並びになっているかを検証できます。
このアノテーションの特徴は、単に数字の桁数を見るだけではなく、Luhnアルゴリズムと呼ばれるチェック方式を利用することです。Luhnアルゴリズムは、カード番号などで入力ミスを検出するために使われる仕組みです。数字を一定の規則で計算し、最後に条件を満たしているかを確認します。そのため、適当に並べた数字の多くはバリデーションエラーになります。
@CreditCardNumberはJakarta Validationの標準アノテーションではなく、Hibernate Validatorが提供するアノテーションです。Spring BootでHibernate Validatorを利用している環境では、入力チェックの一つとして利用できます。
初心者が最初に覚えておきたいのは、このアノテーションが決済処理そのものを行う機能ではないことです。クレジットカード会社へ問い合わせたり、利用可能額を確認したり、カードの有効期限を確認したりするものではありません。入力された番号がLuhnチェックを通過するかを確認するためのバリデーション機能として理解すると分かりやすいでしょう。
2. Spring Bootで使うための基本設定
Spring Bootで@CreditCardNumberを利用するには、バリデーション機能が利用できるように依存関係を追加します。Mavenを利用しているプロジェクトでは、spring-boot-starter-validationを追加する方法が分かりやすいです。このスターターを利用すると、Spring MVCのフォーム入力やリクエストデータに対する入力チェックを実装しやすくなります。
実際のJavaクラスでは、クレジットカード番号を受け取るフィールドにアノテーションを付けます。Spring Bootの新しい環境ではJakarta Validationのアノテーションと組み合わせて利用することが多く、@NotBlankなどと併用すると、未入力と番号形式の不正をそれぞれチェックできます。
import org.hibernate.validator.constraints.CreditCardNumber;
public class PaymentForm {
@CreditCardNumber
private String cardNumber;
public String getCardNumber() {
return cardNumber;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
}
この例では、cardNumberフィールドにCreditCardNumberアノテーションを付けています。Springのバリデーションが実行されると、このフィールドに入力された値が検証対象になります。書き方自体はシンプルなので、メールアドレスを検証する@Emailや文字数を検証する@Sizeを使ったことがある人なら同じ感覚で利用できます。
ただし、アノテーションをフィールドへ付けるだけでは、すべての場面で自動的に検証されるわけではありません。Spring MVCのControllerでフォームを受け取る場合は、@Validや@Validatedを使ってバリデーションを実行する必要があります。
3. Luhnアルゴリズムで何をチェックしている?
CreditCardNumberアノテーションを正しく理解するには、Luhnアルゴリズムが何のために使われるのかを知っておくことが大切です。Luhnアルゴリズムは、入力された数字列に対して決められた計算を行い、チェック用の数字との整合性を確認する方法です。クレジットカード番号の入力間違いを検出する目的などで利用されています。
たとえば、利用者がカード番号の一部を打ち間違えた場合、数字の並びがLuhnチェックの規則を満たさなくなることがあります。CreditCardNumberアノテーションはこの計算を自分でJavaコードとして実装しなくても、アノテーションを付けるだけで確認できる点が便利です。
一方で、Luhnチェックを通過したからといって、その番号のクレジットカードが実際に発行されているとは限りません。また、カードが停止されていないか、有効期限が切れていないか、決済できる残高や利用可能枠があるかといった情報も分かりません。あくまで番号の構造上のチェックであり、実際のカード認証とは別の処理です。
この違いを理解しておくと、Spring Bootでバリデーションを設計するときの役割分担が分かりやすくなります。入力画面では形式上の明らかな誤りを早めに利用者へ知らせ、実際のカード利用可否は決済サービス側で確認するというように処理を分けます。
4. NotBlankと組み合わせて未入力もチェックする
クレジットカード番号を必須入力にしたい場合は、CreditCardNumberアノテーションだけではなく@NotBlankなどを併用する方法が重要です。バリデーション用の制約アノテーションには、それぞれ担当する役割があります。番号の妥当性を検証する制約と、未入力を禁止する制約は分けて考えると設計しやすくなります。
フォーム画面でカード番号が必須なのに、空の値を通したくない場合は次のように記述できます。エラーメッセージも指定しておくと、利用者が何を修正すればよいのか理解しやすくなります。
import jakarta.validation.constraints.NotBlank;
import org.hibernate.validator.constraints.CreditCardNumber;
public class PaymentForm {
@NotBlank(message = "カード番号を入力してください")
@CreditCardNumber(message = "カード番号の形式を確認してください")
private String cardNumber;
public String getCardNumber() {
return cardNumber;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
}
この例では、未入力の検証とクレジットカード番号の検証を別々に指定しています。入力が空ならNotBlankによるエラーを表示し、値が入力されていても番号の計算上の条件を満たさなければCreditCardNumberによるエラーを表示できます。
Spring Bootの入力チェックでは、一つのアノテーションにすべての役割を求めるのではなく、必要な制約を組み合わせる考え方が基本です。名前ならNotBlank、文字数ならSize、メールアドレスならEmail、数値の範囲ならMinやMaxというように、入力項目の条件に合わせて適切なアノテーションを選びます。
5. ハイフンや空白を含むカード番号を扱う方法
実際の入力フォームでは、利用者がカード番号を数字だけで入力するとは限りません。読みやすくするために空白を入れたり、区切りとしてハイフンを入力したりする場合があります。CreditCardNumberアノテーションには、数字以外の文字を無視してLuhnチェックを行うための設定があります。
ignoreNonDigitCharactersを有効にすると、数字ではない文字を検証時に無視してカード番号のチェックを行えます。利用者が区切り文字を含めて入力する可能性がある画面では、この設定を検討できます。
import jakarta.validation.constraints.NotBlank;
import org.hibernate.validator.constraints.CreditCardNumber;
public class CardInputForm {
@NotBlank(message = "カード番号を入力してください")
@CreditCardNumber(
ignoreNonDigitCharacters = true,
message = "カード番号を確認してください"
)
private String cardNumber;
public String getCardNumber() {
return cardNumber;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
}
この設定を利用すると、利用者にとって入力しやすいフォームを作りやすくなります。ただし、数字以外の文字を無視する設定を使う場合は、アプリケーション内部でどのような形式に統一して扱うのかも決めておくことが大切です。保存や外部サービスへの送信が必要な場合には、入力値をそのまま利用するのではなく、安全な決済サービスの仕様に合わせて処理します。
また、入力欄の見た目を整える目的でJavaScriptを使って一定の桁ごとに空白を表示する方法もあります。その場合でも、画面側だけに検証を任せず、Spring Bootのサーバー側でもバリデーションを実行します。ブラウザ側のチェックは利用者の操作を助けるためのものであり、サーバー側の入力検証を省略する理由にはなりません。
6. Controllerでバリデーションを実行する方法
フォームクラスにCreditCardNumberアノテーションを付けたら、Spring MVCのControllerでバリデーションを実行します。フォームを受け取る引数に@Validを付け、続けてBindingResultを受け取る方法が初心者にも分かりやすい書き方です。
バリデーションエラーがある場合は入力画面へ戻し、問題がなければ次の処理へ進めます。これにより、Controllerの中で自分でカード番号の計算処理を書く必要がなくなり、入力チェックと本来の業務処理を分けやすくなります。
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class PaymentController {
@GetMapping("/payment")
public String showForm(PaymentForm form) {
return "payment";
}
@PostMapping("/payment")
public String payment(
@Valid PaymentForm form,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "payment";
}
return "payment-confirm";
}
}
この例では、POSTリクエストでPaymentFormを受け取るときにValidを指定しています。Springはフォームの各フィールドに設定されている制約を確認し、問題があればBindingResultへエラー情報を格納します。ControllerではhasErrorsを確認するだけで、入力エラーが存在するか判断できます。
初心者が間違えやすい点として、BindingResultは検証対象のフォーム引数の直後に配置する書き方を意識するとよいでしょう。エラーがある場合に例外として処理を終えるのではなく、同じ入力画面へ戻してメッセージを表示することで、利用者が入力内容を修正しやすくなります。
7. Thymeleafのフォームでエラーメッセージを表示する
Spring BootとThymeleafを組み合わせている場合は、CreditCardNumberによるバリデーションエラーをHTML画面へ表示できます。入力欄にth:fieldを指定し、th:errorsを使うと、Java側のアノテーションで指定したメッセージを画面に表示できます。
利用者が誤ったカード番号を入力したときに、単に処理が止まるだけでは何を修正すればよいのか分かりません。入力欄の近くに具体的なメッセージを表示すると、初心者にも使いやすいフォームになります。
<form th:action="@{/payment}" th:object="${paymentForm}" method="post">
<div class="mb-3">
<label for="cardNumber" class="form-label">カード番号</label>
<input
type="text"
id="cardNumber"
th:field="*{cardNumber}"
class="form-control">
<div
class="text-danger mt-1"
th:if="${#fields.hasErrors('cardNumber')}"
th:errors="*{cardNumber}">
</div>
</div>
<button type="submit" class="btn btn-primary">確認する</button>
</form>
このHTMLでは、カード番号にバリデーションエラーがある場合だけエラーメッセージを表示します。Spring BootのController、フォームクラス、Thymeleafの三つを組み合わせることで、入力、検証、エラー表示という一連の流れを作れます。
実務では、エラー時に利用者が入力したカード番号をどのように再表示するかについても慎重に考える必要があります。クレジットカード情報は非常に重要な情報なので、通常の名前や住所と同じ感覚で画面やログへ出力しないことが大切です。特にログファイルへカード番号全体を書き出さないように注意します。
8. CreditCardNumberを使うときの注意点と実務での考え方
CreditCardNumberアノテーションは、Spring Bootでクレジットカード番号の入力チェックを簡潔に実装できる便利な機能ですが、実際の決済システムを安全に作るには、このアノテーションだけでは不十分です。Luhnチェックは入力された番号の計算上の整合性を確認するものであり、カード所有者の本人確認や利用可能状態の確認を行うものではありません。
そのため、本番のWebサービスでクレジットカード決済を導入するときは、信頼できる決済サービスが提供する仕組みを利用する方法が基本です。アプリケーション側でカード番号を長期間保存する設計は避け、可能であれば決済サービスが発行するトークンなどを利用して処理します。カード情報を扱う範囲を小さくすることは、セキュリティ上とても重要です。
また、カード番号をデバッグログやアクセスログへ出力しないようにします。開発中に確認しやすいからという理由でSystem.out.printlnなどを使ってカード番号全体を表示すると、ログファイルに重要な情報が残る危険があります。エラー調査で識別情報が必要な場合でも、末尾の一部だけを利用するなど、安全性を考えた設計が必要です。
Springのバリデーションとして考えると、CreditCardNumberは入力値の早期チェックを担当します。未入力ならNotBlank、番号のLuhnチェックならCreditCardNumber、有効期限なら別の項目として確認するというように、役割を分けて設計します。この考え方はクレジットカード番号だけでなく、会員登録フォームや注文フォームなど、Spring Bootでさまざまな入力チェックを作るときにも役立ちます。
JavaとSpring Bootを学び始めた段階では、まずフォームクラスにCreditCardNumberを付け、ControllerでValidを使い、BindingResultでエラーを確認する一連の流れを試してみると理解しやすいでしょう。そのあとでNotBlankとの組み合わせ、エラーメッセージの変更、Thymeleafでの表示、数字以外の文字を扱う設定などを追加すると、Spring ValidationとHibernate Validatorの使い方を段階的に学べます。
CreditCardNumberアノテーションを使いこなすためには、アノテーションの書き方だけではなく、何を検証できて何を検証できないのかを理解することが大切です。Spring Bootの入力チェックでは、入力ミスを早い段階で見つけるバリデーションと、実際の決済処理やセキュリティ対策を明確に分けることで、安全で保守しやすいWebアプリケーションにつながります。
まとめ
Spring Bootでクレジットカード番号の入力チェックを実装するときは、Hibernate Validatorが提供する@CreditCardNumberアノテーションを利用すると、Luhnアルゴリズムに基づいた検証を簡潔に記述できます。フォームクラスのフィールドへアノテーションを付けるだけで、番号の並びが計算上の条件を満たしているか確認できるため、Controllerの中に独自の判定処理を大量に書く必要がありません。
ただし、CreditCardNumberアノテーションが確認するのは、クレジットカード番号としての計算上の整合性です。実際にそのカードが発行されているか、現在利用できる状態なのか、利用可能額が残っているか、有効期限が切れていないかまでは判断できません。Springのバリデーションと実際の決済処理は役割が異なるため、この違いを理解しておくことが重要です。
CreditCardNumberアノテーションの役割を整理しよう
CreditCardNumberアノテーションは、Jakarta Validationの標準アノテーションではなく、Hibernate Validatorが提供する制約アノテーションです。Spring Bootではバリデーション機能と組み合わせて利用しやすく、クレジットカード番号を受け取るフォームクラスやリクエスト用クラスに設定できます。
たとえば、支払いフォームのカード番号フィールドへCreditCardNumberを付けると、その値がLuhnチェックを通過するかどうかを検証できます。Luhnアルゴリズムは、数字列に一定の計算を行い、入力間違いを検出しやすくする仕組みです。数字を一つ打ち間違えた場合など、番号の規則から外れた入力を早い段階で発見するために役立ちます。
import org.hibernate.validator.constraints.CreditCardNumber;
public class PaymentForm {
@CreditCardNumber(message = "カード番号を確認してください")
private String cardNumber;
public String getCardNumber() {
return cardNumber;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
}
このようにアノテーションを利用すると、カード番号の検証ルールがフィールドの近くに書かれるため、どの項目にどの制約が設定されているのか分かりやすくなります。Spring Bootのフォームバリデーションでは、入力項目ごとに制約を定義し、Controllerでは検証結果を受け取るという形にすると、処理の役割を整理しやすくなります。
未入力チェックにはNotBlankを組み合わせる
CreditCardNumberアノテーションを使うときは、カード番号の妥当性チェックと未入力チェックを分けて考えることも大切です。カード番号を必須入力にしたい場合は、@NotBlankなどの制約と組み合わせます。これにより、何も入力されていない場合と、値は入力されているものの番号の形式が正しくない場合を分けて検証できます。
import jakarta.validation.constraints.NotBlank;
import org.hibernate.validator.constraints.CreditCardNumber;
public class CardForm {
@NotBlank(message = "カード番号を入力してください")
@CreditCardNumber(message = "カード番号の形式を確認してください")
private String cardNumber;
public String getCardNumber() {
return cardNumber;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
}
Spring Validationでは、一つのアノテーションですべてを確認しようとするのではなく、それぞれのアノテーションに役割を持たせる考え方が基本です。未入力ならNotBlank、メールアドレスならEmail、文字数ならSize、数値の範囲ならMinやMaxというように、入力項目の条件に合わせて組み合わせます。CreditCardNumberも同じように、カード番号のLuhnチェックを担当する制約として考えると分かりやすいでしょう。
空白やハイフンを含む入力を扱う方法
クレジットカード番号は、利用者が読みやすいように空白やハイフンを入れて入力することがあります。そのような入力を許可したい場合は、CreditCardNumberアノテーションのignoreNonDigitCharactersを利用できます。この設定を有効にすると、数字以外の文字を無視したうえでLuhnチェックを行います。
ただし、画面上でどの形式を許可するかと、アプリケーション内部でどの形式に統一するかは別に考える必要があります。入力時には区切り文字を許可しても、内部処理では数字だけの形式へそろえるなど、システム全体で扱い方を決めておくと保守しやすくなります。
import jakarta.validation.constraints.NotBlank;
import org.hibernate.validator.constraints.CreditCardNumber;
public class CardInputForm {
@NotBlank(message = "カード番号を入力してください")
@CreditCardNumber(
ignoreNonDigitCharacters = true,
message = "カード番号を確認してください"
)
private String cardNumber;
public String getCardNumber() {
return cardNumber;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
}
ブラウザ側でJavaScriptを使い、数桁ごとに空白を入れて見やすくする実装もあります。しかし、ブラウザ側の入力チェックだけに依存してはいけません。送信内容は利用者側で変更できるため、Spring Bootのサーバー側でも必ずバリデーションを実行します。画面側は入力しやすくするため、サーバー側は受け取った値を安全に検証するためという役割分担を意識しましょう。
ControllerではValidとBindingResultを使う
フォームクラスへCreditCardNumberを付けただけでは、Spring MVCのすべての処理で自動的に検証されるわけではありません。Controllerでフォームを受け取るときに@Validを付けることで、フォームクラスに設定したバリデーションを実行できます。検証結果はBindingResultで受け取ることができます。
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class PaymentController {
@PostMapping("/payment")
public String payment(
@Valid PaymentForm form,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "payment";
}
return "payment-confirm";
}
}
この処理では、PaymentFormのバリデーションを実行し、問題があれば入力画面へ戻しています。Controllerの中でLuhnアルゴリズムを直接実装する必要はありません。入力値の検証はフォームクラス、画面遷移や業務処理はControllerというように分けることで、Spring Bootのコードが読みやすくなります。
BindingResultを使う場合は、検証対象となるフォーム引数の直後に配置する書き方を覚えておくとよいでしょう。バリデーションエラーを画面へ返せるようにしておけば、利用者は入力内容を修正して再送信できます。
Thymeleafでは入力欄の近くにエラーを表示する
Spring BootとThymeleafを組み合わせている場合は、Java側で指定したバリデーションメッセージを入力画面へ表示できます。th:fieldでフォームのフィールドと入力欄を結び付け、th:errorsを使うと、カード番号に問題がある場合だけエラーメッセージを表示できます。
入力エラーが発生したときは、利用者に何が間違っているのか分かる表示にすることが大切です。単に処理を停止するのではなく、カード番号を確認してくださいなどのメッセージを入力欄の近くへ表示すると、修正する場所が分かりやすくなります。
<form th:action="@{/payment}" th:object="${paymentForm}" method="post">
<div class="mb-3">
<label for="cardNumber" class="form-label">カード番号</label>
<input
type="text"
id="cardNumber"
th:field="*{cardNumber}"
class="form-control">
<div
class="text-danger mt-1"
th:if="${#fields.hasErrors('cardNumber')}"
th:errors="*{cardNumber}">
</div>
</div>
<button type="submit" class="btn btn-primary">確認する</button>
</form>
この流れを整理すると、フォームクラスで入力ルールを定義し、ControllerでValidを使って検証し、BindingResultでエラーを確認し、Thymeleafで利用者へメッセージを表示します。Spring Bootのバリデーションでは、この一連の流れを理解すると、会員登録、注文、問い合わせ、予約などさまざまなフォームへ応用できます。
Luhnチェックと実際の決済処理を混同しない
CreditCardNumberアノテーションで特に注意したいのは、検証に成功した番号を実在するクレジットカードだと判断しないことです。Luhnチェックに成功する数字列を作ること自体は可能であり、その番号が実際に発行済みかどうかは分かりません。カード所有者本人が入力しているかどうかも判断できません。
実際の支払い処理では、利用する決済サービスの仕組みに従ってカードの認証や決済を行います。Spring Boot側のCreditCardNumberは、入力時点で明らかな番号ミスを検出するための補助的なバリデーションとして利用します。フォームの入力チェックと決済サービスによる確認を分けて考えることが、安全なシステム設計につながります。
カード番号を安易に保存したりログへ出力しない
クレジットカード番号は重要な情報なので、通常のフォーム項目と同じ感覚で扱わないことが大切です。開発中に確認したいという理由でカード番号全体をログへ出力すると、ログファイルに重要な情報が残ってしまいます。デバッグ用の出力や例外メッセージにカード番号を含めないように注意します。
また、独自のデータベースへカード番号を保存する設計も慎重に考える必要があります。実際の決済システムでは、利用する決済サービスが提供するトークンなどを活用し、アプリケーションがカード番号そのものを扱う範囲をできるだけ小さくする考え方が重要です。カード情報を扱う場合は、決済サービスの仕様や必要なセキュリティ要件に従います。
Spring Validationの基本として理解しておこう
CreditCardNumberアノテーションを学ぶことは、Spring Bootのバリデーション全体を理解することにもつながります。フォームの項目にはそれぞれ異なる入力条件があるため、必要な制約を組み合わせて利用します。カード番号ならCreditCardNumber、必須入力ならNotBlank、メールアドレスならEmail、文字数ならSizeというように役割を分けると、入力ルールが明確になります。
JavaとSpring Bootを学び始めた初心者は、まずフォームクラスへアノテーションを付け、ControllerでValidとBindingResultを使い、Thymeleafでエラーを表示するところまで試してみるとよいでしょう。そのあとで、独自メッセージ、複数項目の検証、バリデーショングループなどへ進むと、Spring MVCの入力チェックを段階的に理解できます。
CreditCardNumberは短い記述で使える便利なアノテーションですが、本当に大切なのは何を検証しているのかを理解することです。Luhnチェックによる番号の整合性確認、未入力チェック、Controllerでの検証実行、画面へのエラー表示、実際の決済処理、カード情報の安全な管理をそれぞれ分けて考えることで、保守しやすく安全性を意識したSpring Bootアプリケーションを作りやすくなります。
生徒
「CreditCardNumberアノテーションを付けると、クレジットカード番号の入力チェックを簡単に書けるんですね。」
先生
「そうです。Hibernate Validatorが提供するアノテーションで、Luhnアルゴリズムを使った番号の整合性チェックを行えます。自分で計算処理を書く必要がないので、フォームクラスの入力ルールを分かりやすくできます。」
生徒
「CreditCardNumberを付けておけば、カード番号が未入力の場合も全部チェックできますか?」
先生
「未入力を禁止したい場合はNotBlankなどを組み合わせるのが分かりやすいです。番号のLuhnチェックと必須入力チェックは役割を分けて考えましょう。」
生徒
「フォームクラスにアノテーションを書いたら、それだけでControllerでもチェックされるんですか?」
先生
「Spring MVCでは、フォームを受け取る引数にValidなどを指定してバリデーションを実行します。BindingResultを使えばエラーの有無を確認し、問題があれば入力画面へ戻すことができます。」
生徒
「Thymeleafの画面にもJava側で指定したメッセージを表示できるんですね。」
先生
「はい。フォームクラス、Controller、Thymeleafを連携させることで、入力、検証、エラー表示までを一つの流れとして作れます。これはSpring Bootのフォーム処理でよく使う基本パターンです。」
生徒
「Luhnチェックを通ったら、そのカードは実際に決済できると考えていいですか?」
先生
「そこは分けて考える必要があります。CreditCardNumberで分かるのは番号が計算上の条件を満たしているかどうかです。カードが実在するか、利用可能か、本人のカードかといったことは判断できません。」
生徒
「実際の決済は決済サービスへ任せて、CreditCardNumberは入力ミスを見つけるために使うイメージですね。」
先生
「その考え方が大切です。さらにカード番号をログへ出力したり安易に保存したりしないことも覚えておきましょう。バリデーションとセキュリティの両方を意識すると、より安全なSpring Bootのフォームを作れます。」