• 検索結果がありません。

データ構造とアルゴリズム論

N/A
N/A
Protected

Academic year: 2021

シェア "データ構造とアルゴリズム論"

Copied!
16
0
0

読み込み中.... (全文を見る)

全文

(1)

169

We

W

eb

b

【学習のねらい】

① Web アプリケーション上でデータベースを利用する方法を学習する。

<先週の復習>

講義で示された【基礎課題12-1】に解答して下さい。

12-1.データベース上のデータを表示する

Web アプリケーション

11-2 節では、テーブル「account」のデータを表示する Java アプリケーションを学習し ました。本節では、同様の処理をサーブレットから行う方法を学習します。Web アプリケ ーションの特徴に起因する違いはありますが、基本的な部分はJava アプリケーションの場 合と変わりません。 作成するのは、所定の URL に接続すると、次のように「account」のデータを表示する Web アプリケーションです。以下の手順にしたがって作成してください。 ① 「DBServlet.java」を第 11 章で作成したパッケージ「dbsample」内に下のように新 規作成してください。プログラムの内容は次ページの通りです。

(2)

170 package dbsample; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;

public class DBServlet extends HttpServlet { public void doGet(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

response.setContentType("text/plain;charset=Windows-31J"); PrintWriter out= response.getWriter();

String sql="select * from account"; Connection con=null; Statement smt=null; try { con=DBManager.getConnection(); smt=con.createStatement(); ResultSet rs=smt.executeQuery(sql); while(rs.next()) { out.println("ID="+rs.getInt("ID") +", 氏名="+rs.getString("Name") +", 貯蓄額="+rs.getInt("Money") ); } } catch(SQLException e) {

throw new ServletException(e); } finally {

if(smt != null) {

try{smt.close();} catch(SQLException ignore) {} }

if(con != null) {

try{con.close();} catch(SQLException ignore) {} }

} } }

(3)

171 【解説】 基本的には 11-2 節で学習した「DBOperate.java」と同じです。違いは、データ ベースと接続するために用意した Connection(コネクション)オブジェクトを、ク ライアントからのリクエスト毎に確実にクローズ(解放)している点です。その理由 を簡単に説明しましょう。 Java アプリケーションの場合は、データベースとの接続は(複数のデータベースを 同時利用するなどの特殊な用途を除いて)基本的に一つですが、Web アプリケーショ ンの場合、サーバに接続しているクライアントの数だけコネクション(接続)が発生 します。そのため、一つのクライアントがコネクションを維持してしまうと、サーバ が管理するコネクションの数が増大し、すぐに処理できなくなってしまいます。そこ で、クライアントからのリクエストが終了すると即座にコネクション(およびステー トメント)をクローズして(次の接続のために)解放する、という処理が必須になる のです。その解放処理を確実に行うため、try~catch~finally 文を用いています。 一般に try~catch~finally 文は次の形で記述します。 ここに、例外(エラー)とはデータベース接続時のエラーや接続後に SQL 文の記述ミ スなどで処理が中断してしまう場合を指します。そのような場合でも、コネクション (データベースへの接続)が実現していれば、finally 文の中で確実にクローズ(解 放)するようにします。最初は複雑に見えるかも知れませんが、これは Web アプリケ ーションでデータベースに接続する場合の決まり文句と思ってください。 ② サーブレットを作成したので、web.xml 文で当該サーブ レットを登録する必要があります。「WEB-INF」フォル ダ内に web.xml を新規作成(「新規」→「ファイル」と 選択)し、次ページのように記述してください。 try { 例外(エラー)が発生する可能性のある処理 } catch (例外クラス型 引数名) { 例外が発生した場合の処理 } finally { 最後に必ず実行する処理 }

(4)

172 作成したら、p.169 のように結果が表示されることを確認してください。 ※ Tomcat の起動を忘れないでください。 ※ また、p.153~154 で説明した通り、MySQL が Windows サービスとして起動してい るか確認し、もし停止状態だったら開始させてください。

【基礎課題 12-2】

この Web アプリケーションの URL は何ですか?空欄部分を記述して提出してください。

http://localhost:8080/

<補足> web.xml をきちんと記述しても 404 エラーが出る場合

Web アプリケーション「DBWeb」が Tomcat に認識されていない可能性があります。そ こで、パッケージエクスプローラ上で「DBweb」を右ボタンクリックし、「Tomcat プロジ ェクト」→「コンテキスト定義を更新」を選択してください。 web.xml になければ、その後所定の URL に接続するときちんと表示されるはずです。 <web-app> <servlet> <servlet-name>DBServlet</servlet-name> <servlet-class>dbsample.DBServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>DBServlet</servlet-name> <url-pattern>/DBServlet</url-pattern> </servlet-mapping> </web-app> <web.xml>

(5)

173

12-2.サーブレットと JSP の連携

前節では、テキスト形式でテーブルの内容(データ)を表 示しましたが、これを右のように HTML の表の形式で表示す るように改善しましょう。 これを、サーブレットの中で HTML 形式の文書を記述して も良いのですが、「第7章.サーブレット間の連携」で学習 した方法を用いて、出力を JSP ファイルで行うようにしま しょう。次の手順にしたがって、作成してください。 ① 「DBServlet.java」を次ページのように修正して「DBServlet2.java」と別名保 管してください。下線部が修正部分です(DBServlet.java の結果表示部分は削除さ れています)。リクエスト属性の forward 文による受け渡しについては、第7章で学 習しています。ここで新たに出てきた内容は※部分のみです。これについては、下の 【解説】を参照してください。 ② 次に、右のように「dbsample」というフォルダを作成しそ の中に「display.jsp」を作成し、p.175 のように記述し ます。これにより、結果が HTML 形式で表示されます。 ③ web.xml に DBServlet2.java に関する部分を、p.175 のように追加します。 【解説】「DBServlet2.java」の※部分について 要点を簡潔にまとめます。  ResultSet オ ブ ジ ェ ク ト を リ ク エ ス ト 属 性 に 保 管 し forward 文で JSP ファイルに転送する、ということが p.174 の「DBServlet2.java」のポイントです。  しかし、p.171 の解説で説明した通り、コネクションおよびステートメントオブジェ クトは、リクエストの終了と共に、つまり JSP ファイルへ転送する前にクローズしな ければなりません。  ResultSet オブジェクトは、「コネクション+ステートメント」オブジェクトがクロ ーズされると、自動的にクローズされてしまいます。つまり破棄されてしまいます。  そこで、ResultSet オブジェクトの中身を、“別の入れ物”に移し替える必要が生じ ます。その“入れ物”が、「CachedRowSetImpl」クラスのオブジェクトです。  プログラムでは、「CachedRowSetImpl」クラスのオブジェクト「crs」を用いて、 「crs.populate(rs);」としています。これにより、ResulSet オブジェクト「rs」 の内容が CachedRowSetImpl オブジェクト「crs」の中にコピーされます。  この「crs」は、コネクションをクローズしても残りますから、forward 文により JSP ファイルに転送することができます。

(6)

174 package dbsample; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.sun.rowset.CachedRowSetImpl;

public class DBServlet2 extends HttpServlet { public void doGet(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

response.setContentType("text/plain;charset=Windows-31J"); PrintWriter out= response.getWriter();

String sql="select * from account"; Connection con=null; Statement smt=null; try { con=DBManager.getConnection(); smt=con.createStatement(); ResultSet rs=smt.executeQuery(sql);

CachedRowSetImpl crs=new CachedRowSetImpl(); crs.populate(rs);

request.setAttribute("crs",crs); } catch(SQLException e) {

throw new ServletException(e); } finally {

if(smt != null) {

try{smt.close();} catch(SQLException ignore) {} }

if(con != null) {

try{con.close();} catch(SQLException ignore) {} } } RequestDispatcher dispatcher =request.getRequestDispatcher("/dbsample/display.jsp"); dispatcher.forward(request,response); } }

<DBServlet2.java>

(7)

175

<%@page contentType="text/html; charset=Windows-31J"%> <%@page import="java.sql.ResultSet" %> <HTML> <BODY> <TABLE BORDER="1"> <TR> <TH>ID<TH>氏名<TH>貯蓄金額 <%

ResultSet rs=(ResultSet) request.getAttribute("crs"); while(rs.next()) { %> <TR> <TD><%=rs.getInt("ID") %> <TD><%=rs.getString("Name") %> <TD><%=rs.getInt("Money") %> <% } %> </TABLE> </BODY> </HTML> <web-app> <servlet> <servlet-name>DBServlet</servlet-name> <servlet-class>dbsample.DBServlet</servlet-class> </servlet> <servlet> <servlet-name>DBServlet2</servlet-name> <servlet-class>dbsample.DBServlet2</servlet-class> </servlet> <servlet-mapping> <servlet-name>DBServlet</servlet-name> <url-pattern>/DBServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>DBServlet2</servlet-name> <url-pattern>/DBServlet2</url-pattern> </servlet-mapping> </web-app> <display.jsp> <web.xml> リ ク エ ス ト 属 性 に 保 管 し た ( CachedRowSetImpl ) オ ブ ジ ェ ク ト を ResultSet オブジェクトして受け取る。 追加部分

(8)

176

【基礎課題 12-3】

p.173 のように結果が表示されることを確認したら、「ResultSet オブジェクトを CachedRowSetImpl オブジェクトに詰め替えることにより、サーブレットから JSP へ ResulSet オブジェクトの中身を転送することができました。」と記述して提出してくださ い。

12-3.データベースへのデータの追加、検索および更新

前節までのプログラムを利用すれば、データベースの検索や更新等の操作は容易に行え ます。以下、順にデータの追加、検索、更新を行ってみましょう。

【基礎課題

12-4】 データの追加

以下のように、新たに口座を開設するページを作成しましょう。 次の手順にしたがって作成してください。 ① 「DBServlet2.java」を修正して次ページの様に記述し、「DBServletOpen.java」と別 名保管してください。下線部が修正部分です。また、氏名と金額は、JSP ファイルか ら受け取ることにしています。 ② 氏名と金額の入力画面を用意し、それらを上のサーブレット「DBServletOpen.java」 に受け渡すJSP ファイル「open.jsp」を p.178 のように記述してください。作成する 場所はフォルダ「dbsample」の中です。p.178 の図を確認してください。 所定のURL に接続し、氏名と振り込み金額を入力して[送信]ボタンをクリックすると、 新たに口座が開設(追加)され、全 データが表示される。 追加されたデータ

(9)

177 package dbsample;

import java.io.IOException; ・・・以下 import 文変更なし

public class DBServletOpen extends HttpServlet { public void doGet(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

response.setContentType("text/plain;charset=Windows-31J"); request.setCharacterEncoding("Windows-31J");

PrintWriter out= response.getWriter(); int ID=0;

String Shimei=request.getParameter("Shimei"); int Kingaku=

Integer.parseInt(request.getParameter("Kingaku")); String sql="select * from account";

Connection con=null; Statement smt=null; try { con=DBManager.getConnection(); smt=con.createStatement(); ResultSet rs=smt.executeQuery(sql); while(rs.next()) { ID=rs.getInt("ID"); } ID=ID+1;

String sql2="insert into account values("+ID +",'"+Shimei+"',"+Kingaku+")"; smt.executeUpdate(sql2);

rs=smt.executeQuery(sql);

CachedRowSetImpl crs=new CachedRowSetImpl(); crs.populate(rs);

request.setAttribute("crs",crs); } catch(SQLException e) {

throw new ServletException(e); } finally { ・・・ } RequestDispatcher dispatcher =request.getRequestDispatcher("/dbsample/display.jsp"); dispatcher.forward(request,response); } } <DBServletOpen.java>

データ挿入のため、「insert into account values(ID の値,氏名,金額)」という SQL 文を発行

(10)

178 open.jsp の作成場所は次の通りです。現時点でパッケー ジエクスプローラを見ると、右のようになっているはず です。 ③ 最後に、web.xml を下のように記述し、新たに作成した サーブレットを登録します。 作成したら、JSP「open.jsp」(下のURL)に接続して p.176 のように動作を確認してください。 http://localhost:8080/DBWeb/dbsample/open.jsp 新しい口座を追加できたら、「新たに口座をデータベースに 追加し、表示する事ができました。」記述して提出してくだ さい。 <web-app> ・・・ <servlet> <servlet-name>DBServletOpen</servlet-name> <servlet-class>dbsample.DBServletOpen</servlet-class> </servlet> ・・・ <servlet-mapping> <servlet-name>DBServletOpen</servlet-name> <url-pattern>/DBServletOpen</url-pattern> </servlet-mapping> </web-app>

<%@page contentType="text/html; charset=Windows-31J"%> <HTML>

<BODY>

<H2>口座開設</H2>

氏名と金額を入力して下さい。<BR> <FORM ACTION="../DBServletOpen">

氏名<INPUT TYPE="TEXT" NAME="Shimei"> 金額<INPUT TYPE="TEXT" NAME="Kingaku"> <INPUT TYPE="SUBMIT" VALUE="送信"> </FORM> </BODY> </HTML> <web.xml> <open.jsp> ※追加部分のみ記述しています。

(11)

179

【基礎課題

12-5】 データの検索

今度は、指定したID(口座番号)の氏名と貯蓄金額を表示するページを作成しましょう。 以下の手順にしたがって作成してください。 ① 「DBServletOpen.java」を次ページのように修正して、「DBServletSelect.java」と別 名保管してください。下線部が修正箇所です。 ② 次に、ID の入力画面を用意しその値をサーブレットに受け渡す JSP ファイル 「select.jsp」を p.181 のように記述してください。作成場所は、open.jsp と同じくフ ォルダ「dbsample」の中です。 ③ 最後に web.xml に p.181 のように新たに作成したサーブレット「DBServletSelect.java」 登録部分を追加します。 作成したら、指定したID の口座が表示されるかどうかを確認してください。確認できた ら「指定した ID の氏名と金額を表示させることを確認しました。」と記述して提出してく ださい。 ID を入力して[送信]ボタンをクリック すると・・・ 指定したID の氏名と貯蓄金額を表示 する。

(12)

180 package dbsample;

import java.io.IOException; ・・・import 文は変更なし

public class DBServletSelect extends HttpServlet { public void doGet(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

response.setContentType("text/plain;charset=Windows-31J"); request.setCharacterEncoding("Windows-31J");

PrintWriter out= response.getWriter();

int ID=Integer.parseInt(request.getParameter("ID")); String sql="select * from account";

Connection con=null; Statement smt=null; try { con=DBManager.getConnection(); smt=con.createStatement(); ResultSet rs;

sql="select * from account where ID="+ID; rs=smt.executeQuery(sql);

CachedRowSetImpl crs=new CachedRowSetImpl(); crs.populate(rs);

request.setAttribute("crs",crs); } catch(SQLException e) {

throw new ServletException(e); } finally { ・・・変更なし } RequestDispatcher dispatcher =request.getRequestDispatcher("/dbsample/display.jsp"); dispatcher.forward(request,response); } } <DBServletSelect.java>

(13)

181

<%@page contentType="text/html; charset=Windows-31J"%> <HTML>

<BODY>

<H2>口座確認</H2>

ID(口座番号)を入力して下さい。<BR> <FORM ACTION="../DBServletSelect">

ID<INPUT TYPE="TEXT" NAME="ID"> <INPUT TYPE="SUBMIT" VALUE="送信"> </FORM> </BODY> </HTML> <web-app> ・・・ <servlet> <servlet-name>DBServletSelect</servlet-name> <servlet-class>dbsample.DBServletSelect</servlet-class> </servlet> ・・・ <servlet-mapping> <servlet-name>DBServletSelect</servlet-name> <url-pattern>/DBServletSelect</url-pattern> </servlet-mapping> </web-app> <select.jsp> <web.xml> ※追加部分のみ記述しています。

(14)

182

【基礎課題

12-6】 データの更新

最後に、次のように口座への入金あるいは引き出しを行えるページを作成しましょう。 次の手順にしたがって、このページを作成してください。 ① DBServletSelect.java を次ページの様に修正し、DBServletUpdate.java と別名保管し てください。下線部と点線枠部分が修正箇所です。 ② select.jsp を p.184 のように修正し、update.jsp と別名保管してください。 ③ 最 後 に web.xml に p.184 の よ う に 新 た に 作 成 し た サ ー ブ レ ッ ト 「DBServletUpdate.java」登録部分を追加します。 作成したら、上の様に動作を確認してください。確認できたら、「指定した口座(ID)に 入金(あるいは引き出し)を行えることを確認しました。」と記述して提出してください。 次の画面で、例えば入金と選択しID と金額を入力して[送信]ボタンをクリックす ると・・・ 指定した口座に所定 の料金が入金されて 表示される。

(15)

ネットワークプログラミング論 平成27 年 12 月 21 日

183 package dbsample;

import java.io.IOException; ・・・

public class DBServletUpdate extends HttpServlet { public void doGet(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

response.setContentType("text/plain;charset=Windows-31J"); request.setCharacterEncoding("Windows-31J");

PrintWriter out= response.getWriter(); String InOut=request.getParameter("InOut");

int ID=Integer.parseInt(request.getParameter("ID")); int Kingaku=

Integer.parseInt(request.getParameter("Kingaku")); String sql="select * from account where ID="+ID;

Connection con=null; Statement smt=null; try { con=DBManager.getConnection(); smt=con.createStatement(); ResultSet rs=smt.executeQuery(sql); rs.next(); if(InOut.equals("Nyukin")) { Kingaku=rs.getInt("Money")+Kingaku; } else { Kingaku=rs.getInt("Money")-Kingaku; } String sql2=

"update account set Money="+Kingaku+" where ID="+ID; smt.executeUpdate(sql2);

sql="select * from account where ID="+ID; ・・・

} catch(SQLException e) {

throw new ServletException(e); } finally { ・・・ } RequestDispatcher dispatcher =・・・(以下変更なし) } }

(16)

184

<%@page contentType="text/html; charset=Windows-31J"%> <HTML> <BODY> <H2>入金・引き出し</H2> 入金あるいは引き出しのいずれかを選択し、ID(口座番号)と金額を入力して下さい。 <BR> <FORM ACTION="../DBServletUpdate">

<INPUT TYPE="RADIO" NAME="InOut" VALUE="Nyukin">入金

<INPUT TYPE="RADIO" NAME="InOut" VALUE="HikiDashi"> 引 き 出 し <BR>

ID<INPUT TYPE="TEXT" NAME="ID">

金額<INPUT TYPE="TEXT" NAME="Kingaku"> <INPUT TYPE="SUBMIT" VALUE="送信"> </FORM> </BODY> </HTML> <web-app> ・・・ <servlet> <servlet-name>DBServletUpdate</servlet-name> <servlet-class>dbsample.DBServletUpdate</servlet-class> </servlet> ・・・ <servlet-mapping> <servlet-name>DBServletUpdate</servlet-name> <url-pattern>/DBServletUpdate</url-pattern> </servlet-mapping> </web-app> <update.jsp> <web.xml> ※追加部分のみ記述しています。

参照

関連したドキュメント

The demographic and geographic factors affecting rural areas, such as their remoteness and dispersed settlement patterns, low population densities, and aging

Microsoft/Windows/SQL Server は、米国 Microsoft Corporation の、米国およびその

WAV/AIFF ファイルから BR シリーズのデータへの変換(Import)において、サンプリング周波 数が 44.1kHz 以外の WAV ファイルが選択されました。.

・Microsoft® SQL Server® 2019 Client Access License (10 User)ライセンス証書 オープン価格. オープン価格 Microsoft SQL

In this diagram, there are the following objects: myFrame of the Frame class, myVal of the Validator class, factory of the VerifierFactory class, out of the PrintStream class,

If the above mentioned goods, exempted from customs duty and internal tax, are offered for use other than the personal use of yourself or your family, within 2 years after the

[r]

This agreement is expected to promote greater freedom in movement of goods, services, and capital between Japan and Chile, and foster comprehensive economic cooperation,