mb_language("uni"); mb_internal_encoding("utf-8"); mb_http_input("auto"); mb_http_output("utf-8"); ?>
前回は、やわらかいデータベースに焦点を当てて、データベースのスキーマ変更に対して柔軟に対応できるというXprioriの特徴を、RDBと比較して紹介しました。Xprioriがスキーマ変更に柔軟に対応できるつくりになっていることを理解していただけたのではないでしょうか。今回と次回では、今まで作ってきた住所録アプリケーションにスキーマ変更を行うことで、Xprioriを利用したアプリケーションではどのような対応が必要かを紹介します。前回紹介したように、変更要求は「住所アイテムに電話番号という項目を登録できるようにする」というものです。RDBの場合はアプリケーションの修正を行う前に現在利用しているテーブルに対してフィールドの追加を行う必要がありますが、Xprioriでは現在格納されているデータに対しては何も修正を加えずにアプリケーション側での修正を行うことができます。なお、今回の記事ではアイテム登録に必要な修正を紹介します。
アプリケーション側で行う修正は幾つかありますが、まずはクラスに対する修正を行います。修正が必要なクラスは以下のとおりです。
● ItemBeanクラス
住所アイテムそのものを扱うItemBeanクラスには、メンバ変数に電話番号を追加し、電話番号を設定/取得するためのsetTel/getTel関数を追加します。また、コンストラクタも修正し、インスタンス時に引数として受け取るNodeからtel要素を取得できるようにします。ただし、tel要素を持っていないアイテムも存在するのでNodeから取得する前にtel要素が存在するかどうかのチェックを行います。
public ItemBean(Node itemnode) { if(itemnode != null && itemnode.getNodeName().equals("item")){ // IDを取得 this.setID(XMLEncoder.xmlUnencode(itemnode.getAttributes() .getNamedItem("id").getNodeValue())); // 名前を取得 this.setName(XMLEncoder.xmlUnencode(AddressbookUtils .getChildNodeByTagName(itemnode,"name").getFirstChild().getNodeValue())); // 郵便番号を取得 this.setZip(XMLEncoder.xmlUnencode(AddressbookUtils .getChildNodeByTagName(itemnode,"zip").getFirstChild().getNodeValue())); // 住所を取得 this.setAddress(XMLEncoder.xmlUnencode(AddressbookUtils .getChildNodeByTagName(itemnode,"address").getFirstChild().getNodeValue())); // 電話番号を取得 if(AddressbookUtils.getChildNodeByTagName(itemnode,"tel") != null ){ //tel要素が存在するかどうかをチェックする this.setTel(XMLEncoder.xmlUnencode(AddressbookUtils .getChildNodeByTagName(itemnode,"tel").getFirstChild().getNodeValue())); } } } |
さらに、アイテムのXMLを取得する関数であるgetItemXML関数を修正し、tel要素を含んだitem要素を返すようにします。
public String getItemXML() { String itemXML = "<item id=\"" + XMLEncoder.xmlEncode(this.getID()) + "\">" + "<name>" + XMLEncoder.xmlEncode(this.getName()) + "</name>" + "<zip>" + XMLEncoder.xmlEncode(this.getZip()) + "</zip>" + "<address>" + XMLEncoder.xmlEncode(this.getAddress()) + "</address>" + "<tel>" + XMLEncoder.xmlEncode(this.getTel()) + "</tel>" + "</item>"; return itemXML; } |
● ParamBeanクラス
パラメータを扱うParamBeanクラスには、電話番号のパラメータtelをメンバ変数として追加し、電話番号を設定/取得するためのsetTel/getTel関数を追加します。
● CheckBeanクラス
パラメータのチェックを行うCheckBeanクラスには、電話番号チェックのためcheckTel関数を作成します。電話番号形式は様々なパターンがありますが、ここでは簡易的に引数の文字列が半角数字とハイフン(-)を組み合わせ、10桁以上15桁であるかどうかを正規表現でチェックします。
そして、アイテム情報のパラメータチェックを行うcheckItemParam関数にcheckTelを加えます。
public void checkTel(String str){ Pattern pattern = Pattern.compile("^[0-9-]{10,15}"); Matcher matcher = pattern.matcher(str); if(!matcher.matches()){ this.errflg = true; this.errmsg += "<br><font color=\"red\">電話番号は半角数字とハイフン(-) で入力してください。<br>(例:0000-00-0000 または 090-0000-0000)</font>"; } } |
● SearchAddressbookBeanクラス
SearchAddressbookBeanクラスがもつ、パラメータからアイテムオブジェクトを作るgetItemByParam関数を電話番号も追加できるように修正します。
public ItemBean getItemByParam(ParamBean param) { ItemBean item = new ItemBean(); // パラメータの情報をアイテムに設定する item.setID(param.getId()); item.setName(param.getName()); item.setZip(param.getZip()); item.setAddress(param.getAddress()); item.setTel(param.getTel()); // 追加部分 return item; } |
上記の修正を各クラスに行った後、JSP側を修正します。
アイテム登録のためにJSP側で行う修正は、telパラメータの取得や電話番号の表示部の追加となります。各画面に対して行った修正を以下に示します。
● アイテム入力画面(inputitem.jsp)
アイテム入力画面では、telパラメータを取得できるようにsetPropertyタグを追加し、電話番号を入力できるテキストボックスを追加します。
・・・ <jsp:setProperty name="param" property="tel" param="tel" /> ・・・ <tr><th>電話番号</th><td><input type="text" name="tel" value="<%= AddressbookUtils.htmlEncode (input_item.getTel()) %>" ></td></tr> ・・・ |
● アイテム確認画面(confirmitem.jsp)
アイテム確認画面では、入力画面と同様にtelパラメータを取得できるようにsetPropertyタグを追加します。さらに、入力エラーが発生し入力画面に戻るときに電話番号をパラメータとして追加し、確認用に表示するアイテム情報としての電話番号と、hidden値としての電話番号を出力できるようにします。
・・・ <jsp:setProperty name="param" property="tel" param="tel" /> ・・・ <jsp:param name="tel" value="<%= param.getTel() %>" /> ・・・ <%-- ItemBeanから、アイテム情報の電話番号をテーブル内に追加し、hidden値にも追加する --%> <table width="100%" border="1" cellspacing="0" cellpadding="3"> <tr><th>ID</th><td><%= AddressbookUtils.htmlEncode(confirm_item.getID()) %></td></tr> <tr><th>名前</th><td><%= AddressbookUtils.htmlEncode(confirm_item.getName()) %></td></tr> <tr><th>郵便番号</th><td><%= AddressbookUtils.htmlEncode(confirm_item.getZip()) %></td></tr> <tr><th>住所</th><td><%= AddressbookUtils.htmlEncode(confirm_item.getAddress()) %></td></tr> <tr><th>電話番号</th><td><%= AddressbookUtils.htmlEncode(confirm_item.getTel()) %></td></tr> <tr><td colspan="2" align="center"> <input type="hidden" name="id" value="<%= AddressbookUtils.htmlEncode(confirm_item.getID()) %>"> <input type="hidden" name="name" value="<%= AddressbookUtils.htmlEncode(confirm_item.getName()) %>"> <input type="hidden" name="zip" value="<%= AddressbookUtils.htmlEncode(confirm_item.getZip()) %>"> <input type="hidden" name="address" value="<%= AddressbookUtils.htmlEncode(confirm_item.getAddress()) %>"> <input type="hidden" name="tel" value="<%= AddressbookUtils.htmlEncode(confirm_item.getTel()) %>"> <input type="hidden" name="mode" value="<%= param.getMode() %>"> <input type="submit" value="実行"> </td></tr> </table> ・・・ |
● アイテム登録(runitem.jsp)
アイテム登録画面では、アイテム確認画面と同様にtelパラメータを取得できるようにsetPropertyタグを追加し、入力エラーが発生し入力画面に戻るときに電話番号をパラメータとして渡します。実際に新規登録する部分には修正を行う必要はありません。これは、登録するXMLを取得するためのItemBeanのgetItemXML関数が新しい形式のXMLを返すためです。
・・・ <jsp:setProperty name="param" property="tel" param="tel" /> ・・・ <jsp:param name="tel" value="<%= param.getTel() %>" /> ・・・ |
今回の修正で、新たに住所アイテムを追加する際に電話番号も登録できるようになりました。各クラスとJSPに対して行う修正箇所を紹介していきましたが、機能的な修正は幾つかあったものの、実際にXprioriに接続する部分での修正はItemBeanクラスのインスタンス部ぐらいであり、スキーマ変更が及ぼすアプリケーション側での影響範囲は少ないといえるでしょう。ただ、現状のままでは、既に登録済みでtel要素を持っていないアイテムを編集するとエラーが発生し、編集内容が反映されません。次回は、既に登録済みでtel要素を持っていないアイテムを編集する際に必要な修正内容と、アイテムの閲覧部分を紹介します。
今回作成したjavaクラス・jspファイルはこちらからダウンロードすることができます。
・ jspファイルはWebアプリケーションフォルダのaddress_book/WebContentに配置してください。
・ javaファイルはWebアプリケーションフォルダのaddress_book/WebContent/WEB-INF/srcに配置してください。
また、ご自分でクラスを新規作成する場合はEclipseのメニューバーより、[ファイル]→[新規]→[クラス]を選択し、[次へ]を押してください。
次の画面で[ソースフォルダ]に「address_book/src」、[パッケージ]に「addressbook」を入力し、[名前]に適切なクラス名を入力し、[終了]を押すことで、新規のクラスを作成することができます。
▲このページのTOPへ