はじめに
こんにちは。
プログラミング初心者wakinozaと申します。
Java勉強中に調べたことを記事にまとめています。
十分気をつけて執筆していますが、なにぶん初心者が書いた記事なので、理解が浅い点などあるかと思います。
間違い等あれば、指摘いただけると助かります。
記事を参考にされる方は、初心者の記事であることを念頭において、お読みいただけると幸いです。
対象読者
- Javaを勉強中の方
- HTMLファイルのフォームと、Java言語のサーブレットでリクエストパラメータ処理について知りたい方
動作環境
- MacBook(Intel CPU 搭載)
- Oracle Java 21
- eclipse 2023
記事のテーマ
- Servlet/JSPのフォーム処理について勉強しました。この記事では、HTMLファイルでのフォームの書き方と、フォームの情報をサーブレットクラスでどのようにして受け取るかを説明します
- Servlet/JSPの概論については、以下の記事でまとめています
目次
1. リクエストパラメータとは
2. HTMLファイルのフォームの基本
3. サーブレットでのリクエストパラメータの取得方法
4. フォームの種類
本文
1. リクエストパラメータとは
1. リクエストパラメータ
ユーザーがWebページを閲覧したい場合に、ブラウザがWebサーバに送る要求を「リクエスト」と言います。
「リクエスト」は内部に、リクエストの方法(GETやPOST)・使用するプロトコル等の情報を含んでいますが、ユーザーが入力した情報を含めることもできます。
この付加されたユーザー入力情報を「リクエストパラメータ」と言います。
入力フォームや検索フォームでの入力情報は、「リクエストパラメータ」として、アプリケーションサーバに送信されます。
そして、Servlet/JSPなどのサーバサイドプログラムは、送信されたリクエストパラメータから入力情報を取得します。
2. GETとPOST
ブラウザとWebサーバ間の通信は「HTTP」というプロトコルに基づいて行われています。
「HTTP」のリクエスト方法はいくつかありますが、代表的なのが「GETリクエスト」と「POSTリクエスト」です。
ユーザ入力情報をリクエストパラメータとして送信する場合も、リクエスト方式が「GETリクエスト」か「POSTリクエスト」かによって、挙動が異なってきます。
そのため、「GETリクエスト」と「POSTリクエスト」それぞれの特性を理解しておくことが重要です。
まず、「GETリクエスト」は、新しい情報を取得する場合に用いられるリクエスト方式です。検索結果画面を表示する場合などに用いられます。
何度実行しても結果が変わらない性質(冪等性)が求められる場合に適しています。
また、「GETリクエスト」は、 URLの末尾にクエリパラメーターとしてリクエストパラメータを付加します。そのため、URLにリクエストパラメータの情報が表示されます。
多くのブラウザでURLの長さに制限があるため、「GETリクエスト」で送信できるデータ量は少なくなります。
また、URLは、ブラウザ・通信機器・Webサーバのログに記録されるので、後から不特定多数の人が閲覧できてしまいます。
そのため、パスワード等の機密情報を送信する場合には不向きです。
もう一つの「POSTリクエスト」はデータを作成・更新する場合に用いられるリクエスト方式です。フォーム情報の送信・ログイン処理・データベースへの処理などに用いられます。
サーバ側の状態を変化させる処理に適しています。
「POSTリクエスト」は、リクエストパラメータをメッセージボディ内に格納して送信します。 そのため、URLにデータは表示されません。URLにデータが表示されないため、送れるデータ量の制限も受けにくく、大容量のデータを送信することが可能です。
パスワード等の機密情報を送信する場合に向いていると言えます。
2. HTMLファイルのフォームの基本
この節では、HTMLファイルのフォーム作成の基本について説明します。
まず、ユーザーが情報を入力するためのフォームは、HTMLのタグを使って作成します。
最低限必要なのは3つ、<form>タグ・データ入力のタグ・送信の<input>タグです。
個別に見ていきましょう。
2.1. <form>タグ
<form>タグで、送信する情報の範囲・送信先・リクエスト方式を指定します。
フォームを作成する場合は、<form>タグの中に<input>タグを記述します。<form>タグの外側に<input>タグを記述しても、その情報は送信されないため、注意が必要です。
また、<form>開始タグ内に、action属性とmethod属性を記述します。
action属性は、フォーム情報の送信先を表します。送信先がサーブレットクラスの場合は、URLパターンを、JSPファイルの場合はwebappからのパスを指定します。
method属性は、リクエスト方式を表します。GETリクエストの場合は「get」を、POSTリクエストの場合は「post」を指定します。
method属性は記述を省略することもできます。省略した場合は、GETリクエストとなります。
それでは、属性を利用した簡単なコード例を見てみましょう。
FormServletクラスにPOSTリクエストを送るフォームを作成すると、コードは以下のようになります。
<form action="FormServlet" method="post">
<!-- <input>タグをここに記述 -->
</form>
余談ですが、公式レファレンスを確認すると、<form>タグにはフォームの名前を指定するname属性があります。name属性は、JavaScriptなどでフォームを識別するために使われますが、一般的なWebアプリケーションやServlet/JSPではあまり使われません。
WebアプリケーションやServlet/JSPでフォームを識別する場合は、後述する隠しフィールド(hidden)などを利用します。
2.2. データ入力のタグ
データ入力のタグには、<input>タグや<select>タグ、<textarea>タグなど様々な種類が用意されています。
それぞれの種類の特性や個別の記述方法は後ほど説明します。
ここでは、<input>タグを例にして、データ入力のタグに共通する記述方法を説明します。
データ入力タグに必要な指定は、type属性・name属性です。type属性によっては、value属性も必要になります。
type属性は、データ入力の形式を指定します。
<input>タグのデータ入力の形式は、テキスト入力、ラジオボタン、チェックボックスなど様々なものが用意されています。それらのうち、どの形式を使うのかをtype属性で指定します。
name属性は、データの識別のために付けられる「識別名」です。フォーム入力情報は、「識別名=値」という形でサーバサイドに送信されます。フォームに複数の入力項目がある場合は、識別名を頼りに、この値がどの<input>タグで入力された情報かを見分けます。
そのため、同じフォーム内の他の識別名と重複する名前を指定すると、データが正しく送信できない場合があります。
name属性は、同じフォーム内で重複しない識別名を指定する必要があります。
value属性は、「値」を指定しますが、役割はtype属性によって2つに分類されます。
1つ目は、type属性がテキストボックスやテキストエリアなど、ユーザーが入力した項目を値とする形式の場合は、value属性は「初期値」を示します。何もユーザーが入力を行わずに送信した場合は、value属性で指定した初期値が「値」として送信されます。一方、ユーザーが入力を行った場合、「値」はユーザーの入力情報となります。
2つ目は、type属性がラジオボタンやチェックボックスなど、ユーザーが選択肢の中から選択する形式の場合です。その場合、ユーザーが選択した項目のvalue属性が「値」として送信されます。
簡単なコード例を見てみましょう。
複数の選択肢から選ぶラジオボタン形式のコードは以下のようになります。
<form action="FormServlet" method="post">
性別:
男性<input type="radio" name="gender" value="male">
女性<input type="radio" name="gender" value="female">
その他<input type="radio" name="gender" value="other">
<!-- 送信の<input>タグをここに記述 -->
</form>
2.3. 送信の<input>タグ
送信のための<input>タグは、送信ボタンを生成するためのタグです。
フォームに必ず1つ必要です。
送信のための<input>タグは、2つの属性を指定する必要があります。
1つ目は、type属性です。送信ボタンのtype属性は"submit"を指定します。
2つ目は、value属性です。送信ボタンのvalue属性は、ボタンのラベルとして表示されるテキスト情報を指定します。
そのため通常、submitボタンのvalue属性は、サーバサイドでは参照されません。value属性がサーバサイドで利用されるのは、フォームに複数の送信ボタンがあり、どのボタンが押されたかをサーバサイドで判別が必要、などの一部のケースのみです。
簡単なコード例を見てみましょう。
先ほどのラジオボタンのコードに送信ボタンを付け加えると、以下のようになります。
<form action="FormServlet" method="post">
性別:
男性<input type="radio" name="gender" value="male">
女性<input type="radio" name="gender" value="female">
その他<input type="radio" name="gender" value="other"><br>
<input type="submit" value="送信">
</form>
3. サーブレットクラスでのリクエストの取得方法
この節ではサーブレットクラスでの、リクエストパラメータの取得方法について説明していきます。
先に説明した通り、フォームに入力したデータは「リクエストパラメータ」としてサーバサイドに送信されます。
サーブレットクラスで、リクエストパラメータを取得するには、2つの処理が必要です。
1つ目は、「文字エンコーディングの指定」です。
Javaの内部環境(JVMが管理する領域や処理)では、文字情報はUTF-16という文字コードで扱われています。しかし、外部環境(JVMの管理外にある領域、ネットワークなど)では、データはバイト列(8ビット単位)で取り扱われます。そのため、文字情報をサーバサイドに送信する際は、一旦、文字情報をバイト列に変換する必要があります。
この文字情報をバイト列に変換する作業を「エンコーディング(符号化)」といい、文字情報の符号化ルールを「文字コード」といいます。
ブラウザがリクエストパラメータを送信する際に使う「文字コード」と、サーブレット/JSPがリクエストパラメータを取得する際に使う「文字コード」が異なると、文字情報が全く異なる符号化ルールで復元されるため、意味不明な文字に変換される「文字化け」が発生します。
この「文字化け」を防ぐため、サーブレット/JSPでリクエストパラメータを取得する際は、適切な文字コードを指定します。
文字コードの指定には、HTTPServletRequestインターフェースのsetCharacterEncodingメソッドを利用します。
| メソッド | 説明 |
|---|---|
| void setCharacterEncoding(String env) | リクエストパラメータを取得する際の文字コードを指定します |
2つ目は、リクエストパラメータの取得です。
リクエストパラメータの取得には、HTTPServletRequestインターフェースのメソッドを利用します。
| メソッド | 説明 |
|---|---|
| String getParameter(String name) | 引数で指定したリクエストパラメータを取得します。指定した名前が存在しない場合は、nullを返します |
| String[] getParameterValues(String name) | 引数で指定したリクエストパラメータに複数の値がある場合は、このメソッドを利用します。指定した名前が存在しない場合は、nullを返します |
Enumeration<String> getParameterNames() |
リクエストパラメータの名前の一覧を取得します |
getParameterメソッドとgetParameterValuesメソッドの引数には、HTMLの<input>タグのname属性で指定した「識別名」を指定します。
また、注意しなければならないのが、これらのメソッドの戻り値がすべてStringクラスであるということです。リクエストパラメータとして送信された情報が整数情報であったとしても、これらのメソッドで取得した時点でStringクラスになります。
もし値を整数として利用したい場合は、型変換が必要です。
また、サーブレットクラスは、GETリクエストを受け取った場合と、POSTリクエストを受け取った場合とでは、呼び出されるメソッドが異なります。
HTMLの<form>タグのmethod属性で「get」を指定した場合、サーブレットクラスの「doGetメソッド」にリクエストパラメータ取得の処理を記載する必要があります。method属性の記述を省略した場合も、同様に「doGetメソッド」でリクエストパラメータ取得します。
一方、method属性で「post」を指定した場合は、サーブレットクラスの「doPostメソッド」にリクエストパラメータ取得の処理を記載する必要があります。
文字コードの指定と、リクエストパラメータを取得するコード例は、以下のとおりです。
package servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/FormServlet")
public class FormServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
//<form>タグのmethod属性でpostを指定したので、doPostメソッドにリクエストパラメータ処理を記載する
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//文字コードを指定する
request.setCharacterEncoding("UTF-8");
//リクエストパラメータを取得する
String gender = request.getParameter("gender");
}
}
4.データ入力の種類
この節では、データ入力の種類ごとの特性とHTMLのコード例を紹介していきます。
4.1.text
<input>タグの「text」タイプは、単一行のテキスト入力欄です。一行の短いテキストデータを入力するために使われます。
改行は自動的に入力値から取り除かれます。
フォームが送信されると、name属性が「識別名」として、ユーザーが入力した内容が「値」として、サーバサイドに送信されます。
使用用途は、氏名・ユーザー名・住所など、1行で入力できる短い文字列の入力に用いられます。
<form action="FormServlet" method="post">
<label>ユーザー名:</label>
<input type="text" name="userName">
<input type="submit" value="送信">
</form>
4.2.radio
<input>タグの「radio」タイプは、排他的な単一選択欄です。
複数の選択肢の中から、必ず一つだけを選ばせラジオボタンを実現します。
フォームが送信されると、name属性が「識別名」として、ユーザーが選んだ選択肢のvalue属性が「値」として、サーバサイドに送信されます。
複数のラジオボタンを一つの選択肢グループとして機能させるために、すべてのボタンに同じname属性を設定する必要があります。同じnameを持つグループ内で、ユーザーは一つしか選択できません。
選択肢型の<input>タグは、選択されたものの識別名が送信される仕組みとなっています。
そのため、どの選択肢も選ばずに送信した場合、その識別名に対するリクエストパラメータは送られず、サーブレットクラスで値を取得しても「null」となります。
使用用途は、性別選択や、Yes/Noなど、1つの選択肢を選ぶ必要がある問いに用いられます。
<form action="FormServlet" method="post">
<p>性別を選んでください:</p>
<input type="radio" name="gender" value="male" checked>
<label >男性</label><br>
<input type="radio" name="gender" value="female">
<label >女性</label><br>
<input type="radio" name="gender" value="other">
<label>その他</label><br>
</form>
値がnullである可能性があるため、リクエストを受け取ったサーブレットクラスではnullチェックをする必要があります。
request.setCharacterEncoding("UTF-8");
String gender = request.getParameter("gender");
if (gender == null) {
System.out.println("何も選択されませんでした。");
}
4.3.checkbox
<input>タグの「checkbox」は、選択肢の中から0以上の任意の数を選択できるチェックボタンを実現します。
フォームが送信されると、name属性が「識別名」として、ユーザーが選んだ選択肢のvalue属性が「値」として、サーバサイドに送信されます。
複数のボタンを一つの選択肢グループとして機能させるために、すべてのボタンに同じname属性を設定する必要があります。
選択肢型の<input>タグは、選択されたものの識別名が送信される仕組みとなっています。
そのため、どの選択肢も選ばずに送信した場合、その識別名に対するリクエストパラメータは送られず、サーブレットクラスで値を取得しても「null」となります。
使用用途は、オプション選択など、複数項目を選択してもらう場合に用いられます。
<form action="FormServlet" method="post">
<p>趣味を選択してください(複数選択可):</p>
<input type="checkbox" name="hobbies" value="reading">
<label >読書</label><br>
<input type="checkbox" name="hobbies" value="travel" checked>
<label>旅行</label><br>
<input type="checkbox" name="hobbies" value="cooking">
<label >料理</label><br>
<input type="checkbox" name="hobbies" value="sports">
<label >スポーツ</label><br>
<input type="submit" value="送信">
</form>
チェックボタンでは、複数の値が送信される可能性があるため、複数の値を取得できるgetParameterValuesメソッドを利用します。
もちろん、nullチェックも必要です。
request.setCharacterEncoding("UTF-8");
String[] hobbies = request.getParameterValues("hobbies");
if (hobbies == null) {
System.out.println("何も選択されませんでした。");
}
4.4.password
<input>タグの「password」タイプは、textと同様の単一行のテキスト入力欄ですが、入力されたテキストが読み取られることがないように、入力情報がアスタリスク ("*") やドット ("•") などの記号に置き換えられることが特徴です。
フォームが送信されると、name属性が「識別名」として、ユーザーが入力した内容が「値」として、サーバサイドに送信されます。
使用用途は、ユーザー認証やパスワードなど、機密性の高い情報を入力する場合の用いられます。
<form action="FormServlet" method="post">
<label>ユーザー名:</label>
<input type="text"name="userName"><br>
<label>パスワード:</label>
<input type="password"name="userPassword">
<br>
<input type="submit" value="ログイン">
</form>
実際に、パスワード情報をフォームで送信する場合は、<input>タグをpasswordタイプに指定するだけでは不十分です。
具体的には以下の対応が必要です。
- GETリクエストではリクエストパラメータがURLに表示されてしまうので、POSTリクエストを選択する
- 通信経路全体をHTTPS (SSL/TLS) にして、暗号化する
- サーバー側で取得した後も、パスワードをそのままデータベースに保存せず、ハッシュ化する
4.5.email
<input>タグの「email」タイプは、textと同様の単一行のテキスト入力欄ですが、ブラウザ側で基本的な形式チェック(@記号が含まれているかなど)を行う機能がある点が特徴です。
フォームが送信されると、name属性が「識別名」として、ユーザーが入力した内容が「値」として、サーバサイドに送信されます。
<form action="FormServlet" method="post">
<label>ユーザー名:</label>
<input type="text" name="userName"><br>
<label>メールアドレス:</label>
<input type="email" name="userEmail">
<br>
<input type="submit" value="送信">
</form>
4.6.number
<input>タグの「number」タイプは、textと同様の単一行のテキスト入力欄ですが、ブラウザ側で入力値が数値であることを確認する機能がある点が特徴です。
フォームが送信されると、name属性が「識別名」として、ユーザーが入力した内容が「値」として、サーバサイドに送信されます。
min属性やmax属性で入力できる数値の範囲を指定することもできます。
使用用途は、年齢や金額など、数値のみを入力する項目に用いられます。
<form action="FormServlet" method="post">
<label>注文数量 (1〜10個):</label>
<input type="number" name="orderQuantity" min="1" max="10" >
<br>
<input type="submit" value="送信">
</form>
フォームで入力したのが数値だったとしても、リクエストパラメータで取得するとStringクラスになります。そのため、値をサーバサイドで数値として利用したい場合は、型変換が必要です。
request.setCharacterEncoding("UTF-8");
String quantityString = request.getParameter("orderQuantity");
int orderQuantity = 0;
String message = "";
//nullチェック
if (quantityString != null && !quantityString.isEmpty()) {
try {
// Stringをint型に変換
orderQuantity = Integer.parseInt(quantityString);
message = "注文数量: " + orderQuantity + "個。合計金額は " + (orderQuantity * 1500) + "円です。";
// サーバー側での入力値チェック
if (orderQuantity < 1 || orderQuantity > 10) {
message = "エラー: 数量は1から10の範囲でなければなりません。";
}
} catch (NumberFormatException e) {
message = "エラー: 無効な数値が入力されました。";
}
} else {
message = "エラー: 注文数量が指定されていません。";
}
4.7.date,month,week,time,datetime-local
<input>タグの「date」「month」「week」「time」「datetime-local」タイプは、日時情報を入力する欄です。対応しているブラウザでは、カレンダー表示など日時情報を選択しやすいユーザーインターフェースが表示されます。非対応のブラウザでは、type="text"と同等の機能になります。
フォームが送信されると、name属性が「識別名」として、ユーザーが入力した内容が指定の形式の値として、サーバサイドに送信されます。
| type | 内容 | 値の形式 | 使用用途 |
|---|---|---|---|
| date | 年月日 | YYYY-MM-DD (例: 2025-10-16) | 生年月日、予約日、イベント開催日など、特定の日付の入力。 |
| month | 年月 | YYYY-MM (例: 2025-10) | 有効期限、会計期間、卒業時期など、月単位の入力。 |
| week | 年と週番号 | YYYY-WXX (例: 2025-W42) | スケジュール管理、納期管理など、週単位の入力。 |
| time | 時分秒 | hh:mm または hh |
開始時刻、終了時刻、会議の時間など、時刻のみの入力。 |
| datetime-local | 年月日時分秒 | YYYY-MM-DDThh:mm (例: 2025-10-16T14:59) | タイムゾーン情報を含まない、ローカルな日時(PCの設定に基づく)の入力。 |
<form action="FormServlet" method="post">
<label>予約日:</label>
<input type="date" name="reserveDate" required><br><br>
<label>開始時刻:</label>
<input type="time" name="startTime" step="60" required><br><br>
<label>会議日時:</label>
<input type="datetime-local" name="meetingDateTime"><br><br>
<label >有効期限:</label>
<input type="month" name="expireMonth"><br><br>
<label >納品週:</label>
<input type="week" name="deliveryWeek"><br><br>
<input type="submit" value="送信">
</form>
UIを表示すると以下のようになりました。
4.8.hidden
<input>タグの「hidden」タイプは、ユーザーの画面上には表示されず、入力もできないフィールドです。ユーザーに見えない場所で、サーバに送りたいデータを保持するために使用されます。
フォームが送信されると、name属性が「識別名」として、value属性が「値」として、サーバサイドに送信されます。
セッションID、トークン(CSRF対策など)、ユーザーID、処理のステータスなど、ユーザーが意識せずとも、アプリケーションのロジックで必要な情報をサーバに送り返すために使用されます。
<form action="FormServlet" method="post">
<h2>ご注文内容</h2>
<p>商品名: プレミアムコーヒー豆 (数量: 1)</p>
<input type="hidden" name="productId" value="P1234">
<input type="hidden" name="sessionId" value="abc123456">
<input type="submit" value="注文を確定する">
</form>
上のように、ブラウザ上にhiddenタイプは表示されません。
4.9.textarea
<textarea>タグは、複数行のテキスト入力欄です。複数行にわたる長いテキスト情報を入力するのに用いられます。
フォームが送信されると、name属性が「識別名」として、ユーザーが入力した内容が「値」として、サーバサイドに送信されます。
rows属性で行数を、cols属性で列数を指定できます。
<form action="FormServlet" method="post">
<p>メッセージを記載してください</p>
<textarea name="messageContent" rows="5" cols="40" >
初期値があればここに記述します。
</textarea>
<br>
<input type="submit" value="送信する">
</form>
4.10.select
<select>タグは、<option>タグと組み合わせることで、指定した項目の中から任意の数をユーザーに選択してもらうドロップダウンリストを実現できます。
デフォルトは単一選択ですが、<select>タグにmultiple属性を追加することで複数選択が可能になります。
任意の項目を選択するという点では、<input>タグのradioタイプやcheckboxタイプと同様の機能です。selectタグの長所は、折りたたみできるドロップダウンリストに選択肢を格納できるという点です。選択肢が多い場合、一覧表示しかない<input>タグのradioタイプやcheckboxタグでは表示に広い面積が必要になります。一方、selectタグでは選択肢を出したり折りたたんだりと表示形式を変更できます。選択肢の多い項目が多数あるフォームでは、ドロップダウンリスト表示の方が、狭い範囲に多くの項目を表示させることができます。
フォームが送信されると、name属性が「識別名」として、ユーザーが選んだ選択肢のvalue属性が「値」として、サーバサイドに送信されます。
<form action="FormServlet" method="post">
<label>好きな食べ物:</label>
<select name="favoriteFood">
<option value="">選択してください</option>
<option value="sushi">寿司</option>
<option value="curry">カレーライス</option>
<option value="ramen">ラーメン</option>
<option value="hamburgerSteak">ハンバーグ</option>
<option value="oyakodon">親子丼</option>
<option value="tempura">天ぷら</option>
<option value="friedChicken">唐揚げ</option>
<option value="udon">うどん</option>
<option value="misoSoup">味噌汁</option>
<option value="steak">ステーキ</option>
</select>
<br>
<input type="submit" value="送信">
</form>
ドロップダウンリストを開くと以下のように表示されます。
まとめ
-
リクエストパラメータは、Webページでユーザーが入力した情報が、HTTPリクエストに付加されてサーバサイドに送信されるデータです
-
フォームを実装するには、HTMLで
<form>タグ、データ入力タグ(例:<input>)、送信ボタンの3つが最低限必要です -
<form>タグのmethod属性で、GET(URLに付加)とPOST(メッセージボディに格納)のリクエスト方式を選択します。機密情報はPOSTを推奨します -
サーブレットクラスでは、request.setCharacterEncoding()で文字コードを指定した後、request.getParameter()やrequest.getParameterValues()**メソッドでリクエストパラメータを取得します
-
フォームのデータ入力には、テキスト、ラジオボタン、チェックボックス、パスワード、日付など、用途に応じた様々な
<input>タイプや<textarea>、<select>タグを使い分けます
記事は以上です。
最後までお読みいただき、ありがとうございました。
参考情報一覧
この記事は以下の情報を参考にして執筆しました。
- [スッキリわかるサーブレット&JSP入門 第4版]
- [基礎からのサーブレット/JSP 第5版]
- [一冊で全て身につくHTML&CSSとWebデザイン 入門講座 第2版]
- MDN公式ドキュメント (参照 2025-10-13)












