JavaBeans/Tomcat/Eclipse (Debian11.4.0)
2022/7/30
方針
Java言語で記述した再利用可能なコンポーネントでありMVCのM(Model)を担当する。
パッケージ名はxxxxBean,xxxxBeansにすることが多い。
- 引数のないコンストラクタが存在する
public宣言したクラスとコンストラクタ
- メソッドの命名規則に従う
getter,setterメソッドが必要
- シリアライズ可能である
java.io.Serializableを実装
ここではつぎのことを目指す。
- index.htmlで入力したリクエストパラメータをMyservlet経由でMyBeansに渡す。
- MyBeansでリクエストパラメータを加工して、MyJSPで表示する。
Myservletを理解するにはJava言語,HTMLの2つの知識が必要である。
Myservletには
1.Java言語によるプログラム
2.HTMLによるブラウザ指向出力
が混在しており、コード全体を理解しなければHTML部分の修正さえできない。
今後ここにcss+javascript言語+SQLを追加しようとしている。いつ破綻してもおかしくない。
・Java言語に関する部分はJava言語に集中し(HTMLは極力減らす)、
・HTMLに関する部分はHTML(+css+javascript言語)に集中させる。
Myservlet内で行った処理をMyBeansに任せることで、Myservletは「パラメータの受け取り」に専念する。
index.htmlを修正
ここからはmethod="post"だけを扱う。index.htmlを修正しよう。

MyBeansをつくる
新しいクラスとしてMyBeansをつくる。

名前をMyBeansにする。
「スーパークラスからのコンストラクタ」に
をつける。
(
をつけなくてもよい。あとから3行タイプすればよい。)

コンストラクタMyBeans()が生成されている。初期化が必要な場合はこのあたりに記述する。

リクエストパラメータを扱うプロパティとしてtel,room,submitを宣言する。
telは整数型(Integer)、root,submitは文字列(String)にする。
tel,room,submitに対してgetterとsetterをつくる。

いまから追記するコードをどこに入れるかは「挿入ポイント」に指示する。どこでもいいが「最後のメンバー」にした。
ソート順はほぼ好みによる。「getter/setterの対のフィールド」にすると、telに関して「getTel()」「setTel()」が続く。getterだけ(setterだけ)集めることもできる。

getterとsetterが追記された。
基本的にはこれでいいが、実はちょっとした不具合がある。不具合は後ほど修正する。

Myservletを修正
MyBeansができたので、MyservletからMyBeansへ値を渡す。
さきほどのMyservlet.javaはほとんど書き直すことになる。
受け取るリクエストパラメータはtel,room,submitに限定する。
もはや原型をとどめていない。doPost()メソッドだけにする。doGet()メソッド、makeHTML()メソッド、showMyParameter()メソッドは全部削除する。
package myapp;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class Myservlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
MyBeans mybeans = new MyBeans();
mybeans.setRoom(req.getParameter("room"));
mybeans.setSubmit(req.getParameter("submit"));
mybeans.setTel(req.getParameter("tel"));
//MyBeansクラスをリクエスト属性にセット
req.setAttribute("MyBeans", mybeans);
//つづきはmyjsp.jspへ
this.getServletContext().getRequestDispatcher("/myjsp.jsp").forward(req, resp);
}
}
myjsp.jspを修正
myjsp.jspも修正する。
myjsp.jspはMyBeansから値を取得し、表示する。
<%@ page contentType="text/html; charset=utf-8" %>
<jsp:useBean id="MyBeans" class="myapp.MyBeans" scope="request" />
<html>
<head>
<title>myjsp</title>
</head>
<body>
<h1>JSPで表示</h1>
<table border="1">
<tr>
<td>tel</td> <td><jsp:getProperty name="MyBeans" property="tel" /> </td></tr>
<td>room</td> <td><jsp:getProperty name="MyBeans" property="room" /> </td></tr>
<td>submit</td><td><jsp:getProperty name="MyBeans" property="submit" /></td></tr>
</table>
</body>
</html>
動作確認
きっとMyservlet.java中の mybeans.setTel(req.getParameter("tel")); でエラーが出ていると思う。
「setTel()メソッドで値をmybeansに渡そうとしたが、『数値じゃないからイヤ』と拒否された」と言っている。
MyBeans的に電話番号は番号だし整数だと信じている。だが、HTMLから渡されるリクエストパラメータは文字列なのだ。
対策はつぎのいずれかだろう。
- サーブレットが文字列(電話番号)を数値に変換する。
サーブレットがリクエストパラメータの正当性を確認するのでセキュリティ対策を施しやすい。
MyBeansは修正しない。
- MyBeansで文字列(電話番号)を受け取れるようにする。
サーブレットは修正しない。
MyBeans内で数値に変換する。バラメータの正当性確認や適切な置換等もMyBeans内で処理する。
サーブレットは修正せず、MyBeans側で対処してみよう。
具体的には、引数がStringである新しいsetterをつくる。現在あるsetterはそのままにする。さらにリクエストパラメータtelが数値でない場合はtelを0にするように処理しよう。
public void setTel(String tel) {//setTel(Integer tel){....}はそのままにする
try {this.tel = Integer.parseInt(tel);}
catch (Exception ex) {//電話番号が数値ではありません
this.tel=0;
}
}
こんどはどうだろう。
電話番号で検索するとtel,submitに値が入っている。 roomはnullになっている。 | | 部屋で検索するとroom,submitに値が入っている。 telはnullではなく0になっている。 |
 | |  |
 | |
 |
nullはちょっとイヤなので、(空欄)と表示したい。
setRoom()セッターを修正しよう。
簡易デバッグ用として各セッター中にSystem.out.println(...)を追加した。もちろん、開発が完了する際には削除しなくてはならない。
実行中にプロパティを監視することができる。(デバッガーを使うのが正しい方法なのだが・・・)
コンソールにリクエストパラメータ(受け取った直後の値)を表示している。roomがnullだったら文字列"(空欄)"、そうでなければroomをthis.room(MyBeansのroom)に渡している。
一応、MVCで動作できるようになった。しかしこのアプリは不完全過ぎる。
なぜか?
「電話番号で検索」したら部屋名を表示してほしい。
「部屋名で検索」したら電話番号を表示してほしい。
そのようなことを期待している。
どうすればよいだろうか?