教育サーバーのページ
オンラインテキスト目次
システムプログラミング演習
次のプログラム JdbcFruitTable.java
は、指定したWebサーバ下の
ディレクトリ(アプリケーションのルートディレクトリ/WEB-INF/classes)下に格納されているコンパイル済みのServletファイルを実行することで、ブラウザ上にデータベースの検索結果をテキスト表示するプログラムである。
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.sql.*; import javax.servlet.ServletConfig; public class JdbcFruitTable extends HttpServlet { public void init(ServletConfig config) throws ServletException { super.init(config); try { Class.forName("com.mysql.jdbc.Driver"); } catch (Exception e) { e.printStackTrace(); } } protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE html>"); out.println("<html>"); out.println("<head>"); out.println("<title>FRUIT_TBLテーブルの内容</title>"); out.println("</head>"); out.println("<body>"); out.println("<table border=¥"1¥"><tr><th>番号</th><th>名前</th><th>金額</th></tr>"); Connection con = null; Statement stmt = null; ResultSet rs = null; try { con = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "tuis2019system"); stmt = con.createStatement(); rs = stmt.executeQuery("select no, name, price from fruit"); while (rs.next()) { out.println("<tr>"); out.println("<td>" + rs.getInt("no") + "</td>" ); out.println("<td>" + rs.getString("name") + "</td>" ); out.println("<td>" + rs.getInt("price") + "</td>" ); out.println("</tr>"); } } catch (Exception e) { e.printStackTrace(); } finally { try { rs.close(); } catch (Exception e) {} try { stmt.close(); } catch (Exception e) {} try { con.close(); } catch (Exception e) {} } out.println("</table>"); out.println("</body>"); out.println("</html>"); out.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { processRequest(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { processRequest(request, response); } public String getServletInfo() { return "Short description"; } }
たとえば、Webサーバが動いているホストlocalhostのWebアプリケーション
のルートディレクトリ下の WEB-INF/classesディレクトリに格納されている
コンパイル済みのServletファイルJdbcFruitTable.class(テキストファイルは
JdbcFruitTable.java
)を実行する。そうすると、指定された
データベースに接続され、SQL文により検索がおこなわれ、その結果がブラウザ上
に表示される。
プログラム JdbcFruitTable.java の説明:
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.sql.*; import javax.servlet.ServletConfig;では、
JdbcFruitTable.java
において、Servlet APIならびに
JDBC APIを構成するクラスライブラリ(パッケージ)を使えるように
宣言している。
クラス定義は、次のようにおこなわれる。
public class JdbcFruitTable extends HttpServlet {ここでは、JdbcFruitTableクラスが定義される。通常のServletは、 HttpServletクラスを拡張して定義することが多く、 JdbcFruitTable.javaでも、HttpServletクラスを拡張する。
Servletのクラス内では、以下のようなinitメソッドが定義される。 initメソッドは、Servletがロードされた後で、Servletコンテナ から一度だけ呼び出され、Servletの初期化をおこなう。 次に、NetBeansに組み込まれたデータベース管理システムMySQLの JDBCドライバのロードをおこなう。JDBCドライバは、MySQL用の com.mysql.jdbc.Driverを用いる。
public void init(ServletConfig config) throws ServletException { super.init(config); try { Class.forName("com.mysql.jdbc.Driver"); } catch (Exception e) { e.printStackTrace(); } }
destroyメソッドでは、Servletが破棄される前に、Servletコンテナ から呼び出される。このメソッドも、initメソッドと同様に、行う 処理がなければ、メソッドをオーバーライドする必要はない。
public void destroy() { }
JdbcFruitTable.java
では、クライアントからの要求を
GETメソッドで受け取るために、doGetメソッドに処理を記述する。
POSTメソッドの場合には、doPostメソッドに処理を記述する。
processRequestメソッドは、doGetメソッドとdoPostメソッドで
呼び出されるメソッドを定義している。両者のメソッドでおこなう
処理を共通にするために、processRequestメソッドとしてひとつの
メソッドとして実装している。このメソッドでは、本プログラムの
主処理が以下のようにおこなわれる。
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE html>"); out.println("<html>"); out.println("<head>"); out.println("<title>FRUIT_TBLテーブルの内容</title>"); out.println("</head>"); out.println("<body>"); out.println("<table border=¥"1¥"><tr><th>番号</th><th>名前</th><th>金額</th></tr>"); Connection con = null; Statement stmt = null; ResultSet rs = null; try { con = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "tuis2019system"); stmt = con.createStatement(); rs = stmt.executeQuery("select no, name, price from fruit"); while (rs.next()) { out.println("<tr>"); out.println("<td>" + rs.getInt("no") + "</td>"); out.println("<td>" + rs.getString("name") + "</td>"); out.println("<td>" + rs.getInt("price") + "</td>"); out.println("</tr>"); } } catch (Exception e) { e.printStackTrace(); } finally { try { rs.close(); } catch (Exception e) {} try { stmt.close(); } catch (Exception e) {} try { con.close(); } catch (Exception e) {} } out.println("</table>"); out.println("</body>"); out.println("</html>"); out.close(); }
まず、Servletからの出力データ(ここでは、 HTML文書)の形式を指定するために、以下のように、 HttpServletResponseオブジェクトのsetContentTypeメソッドを 呼び出す。
response.setContentType("text/html; charset=UTF-8");
次に、setContentTypeメソッドで設定した後、以下のように、 getWriterメソッドを呼び出して、ブラウザへの表示に使う PrintWriterオブジェクトを取得する。
java.io.PrintWriter out = response.getWriter();
そして、以下では、上記で取得したPrintWriterオブジェクトの printlnメソッドが呼び出され、引数で渡したメッセージが ブラウザに表示される。
out.println("<!DOCTYPE html>"); out.println("<html>"); out.println("<head>"); out.println("<title>FRUIT_TBLテーブルの内容</title>"); out.println("</head>"); out.println("<body>"); out.println("<table border=¥"1¥"><tr><th>番号</th><th>名前</th><th>金額</th></tr>");
以下では、データベータのアクセスに必要な処理をおこなう。 まず、必要な変数の初期化をおこなう。
Connection con = null; Statement stmt = null; ResultSet rs = null;
try節の中では、データベースに接続するConnectionオブジェクトの取得 をおこなう。ここでは、接続するデータベースのURLを"jdbc:mysql://localhost/test"、ユーザ名が"root"を、パスワードを"tuis2019system"としている。
con = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "tuis2019system");それから、データベース操作を行うためのStatementオブジェクトの取得 をおこなう。
stmt = con.createStatement();
さらに、SQL文を実行して、結果を得るために、以下のような 処理をおこなう。
rs = stmt.executeQuery( "select no, name, price from fruit");
そして、得られた結果をレコードごとに表示するために、 以下の処理を実行する。具体的には、レコードのno フィールド、nameフィールド、priceフィールドを順番に表示する。 ここでは、検索結果が格納されたResultSetオブジェクトから、 指定されたフィールド名に対応する値が表示される。
while (rs.next()) { out.println("<tr>"); // レコードのCUSTOMER_NUMフィールドを表示 out.println("<td>" + rs.getInt("no") + "</td>"); // レコードのNAMEフィールドを表示 out.println("<td>" + rs.getString("name") + "</td>"); // レコードのPHONEフィールドを表示 out.println("<td>" + rs.getInt("price") + "</td>"); out.println("</tr>"); }
finally節では、最終的におこなわれるデータベースとの接続が クローズが記述されている。
try { rs.close(); } catch (Exception e) {} try { stmt.close(); } catch (Exception e) {} try { con.close(); } catch (Exception e) {}通常、Servletでは、doGetメソッドとdoPostメソッドのどちら かは必ず存在すると考えられる。
JdbcFruitTable.java
では、Servletでおこなう処理の内容を共通化して、同じ処理が
doGetメソッドとdoPostメソッドでおこなわれるようにしている。
doGetメソッドは、上述したJdbcFruitTable.java
の
doGetメソッドと同様に、引数にHttpServletRequestオブジェクトと
HttpServletRequestオブジェクトを取る。前者のオブジェクトには、
Servletへの入力が、後者のオブジェクトにはServletからの出力が
格納される。doGetメソッドの処理では、上述したprocessRequest
メソッドを呼び出す。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { processRequest(request, response); }
doPostメソッドは、ServletにHTTPリクエストのPOSTメソッドで アクセスされた時に、Servletコンテナから呼び出される。 通常、HTMLフォームを使ってブラウザからアクセスする時に、 このメソッドが呼び出される。doPostメソッドの処理でも、doGet メソッドと同様に、上述したprocessRequestメソッドを呼び出す。
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { processRequest(request, response); }
getServletInfoメソッドは、Servletに関する説明を表示する 場合に用いる。
public String getServletInfo() { return "Short description"; }
以下のJdbcUpdate.html
では、Formタグのaction属性の値には、
送信ボタンが押された時に、テキスト入力フィールドに入力された文字列を
ServletであるJdbcUpdate.javaに渡すことを指定している。
<!DOCTYPE HTML> <HTML> <HEAD> <TITLE>データベースの変更</TITLE> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </HEAD> <BODY> <FORM method=POST action='JdbcUpdate'> <TABLE border='1'> <TR><TH>NO</TH><TD><INPUT type=text name='no'/></TD></TR> <TR><TH>NAME</TH><TD><INPUT type=text name='name'/></TD></TR> <TR><TH>PRICE</TH><TD><INPUT type=text name='price'/></TD></TR> <TR><TD><INPUT type=submit value='送信'/></TD></TR> </TABLE> </FORM> </BODY> </HTML>
次のプログラム JdbcUpdate.java
は、指定したWebサーバ下の
ディレクトリ(アプリケーションのルートディレクトリ/WEB-INF/classes)下に
格納されているコンパイル済みのServletファイルを実行することで、
ブラウザ上にデータベースの変更結果をテキスト表示するプログラムである。
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletContext; import javax.servlet.RequestDispatcher; import java.sql.*; import javax.servlet.ServletConfig; public class JdbcUpdate extends HttpServlet { public void init(ServletConfig config) throws ServletException { super.init(config); try { Class.forName("com.mysql.jdbc.Driver"); } catch (Exception e) { e.printStackTrace(); } } public void destroy() { } protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { Connection con = null; Statement stmt = null; try { con = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "tuis2019system"); stmt = con.createStatement(); String no = request.getParameter("no"); String name = request.getParameter("name"); String price = request.getParameter("price"); StringBuffer buf = new StringBuffer(); buf.append("update fruit set "); buf.append("name = '"); buf.append(name); buf.append("', price = '"); buf.append(price); buf.append("' where no = "); buf.append(no); stmt.executeUpdate(buf.toString()); try { stmt.close(); } catch (Exception e) {} try { con.close(); } catch (Exception e) {} ServletContext cx = getServletContext(); RequestDispatcher rd = cx.getRequestDispatcher("/JdbcFruitTable"); rd.forward(request, response); } catch (Exception e) { e.printStackTrace(); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { processRequest(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { processRequest(request, response); } public String getServletInfo() { return "Short description"; } }
たとえば、Webサーバが動いているホストlocalhostのWebアプリケーションの
ルートディレクトリ下の WEB-INF/classesディレクトリに格納されている
コンパイル済みのServletファイルJdbcUpdate.class(テキストファイルは
JdbcUpdate.java
)を実行する。そうすると、指定された
データベースに接続され、SQL文によりデータの変更がおこなわれ、
その結果がブラウザ上に表示される。
プログラム JdbcUpdate.java の説明:
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletContext; import javax.servlet.RequestDispatcher; import java.sql.*; import javax.servlet.ServletConfig;では、
JdbcUpdate.java
において、Servlet APIならびに
JDBC APIを構成するクラスライブラリ(パッケージ)を使えるように
宣言している。
クラス定義は、次のようにおこなわれる。
public class JdbcUpdate extends HttpServlet {ここでは、JdbcUpdateクラスが定義される。通常のServletは、 HttpServletクラスを拡張して定義することが多く、 JdbcUpdate.javaでも、HttpServletクラスを拡張する。
Servletのクラス内では、以下のようなinitメソッドが定義される。 initメソッドは、Servletがロードされた後で、Servletコンテナ から一度だけ呼び出され、Servletの初期化をおこなう。 次に、データベース管理システムMySQLのJDBCドライバのロード をおこなう。JDBCドライバは、MySQL用の com.mysql.jdbc.lDriverを用いる。
public void init(ServletConfig config) throws ServletException { super.init(config); try { Class.forName("com.mysql.jdbc.Driver"); } catch (Exception e) { e.printStackTrace(); } }
destroyメソッドでは、Servletが破棄される前に、Servletコンテナ から呼び出される。このメソッドも、initメソッドと同様に、行う 処理がなければ、メソッドをオーバーライドする必要はない。
public void destroy() { }
JdbcUpdate.java
では、クライアントからの要求を
GETメソッドで受け取るために、doGetメソッドに処理を記述する。
POSTメソッドの場合には、doPostメソッドに処理を記述する。
processRequestメソッドは、doGetメソッドとdoPostメソッドで
呼び出されるメソッドを定義している。両者のメソッドでおこなう
処理を共通にするために、processRequestメソッドとしてひとつの
メソッドとして実装している。以下では、processRequestメソッドの
動作について説明する。
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { Connection con = null; Statement stmt = null; try { con = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "tuis2019system"); stmt = con.createStatement(); String no = request.getParameter("no"); String name = request.getParameter("name"); String price = request.getParameter("price"); StringBuffer buf = new StringBuffer(); buf.append("update fruit set "); buf.append("name = '"); buf.append(name); buf.append("', price = '"); buf.append(price); buf.append("' where no = "); buf.append(no); stmt.executeUpdate(buf.toString()); try { stmt.close(); } catch (Exception e) {} try { con.close(); } catch (Exception e) {} ServletContext cx = getServletContext(); RequestDispatcher rd = cx.getRequestDispatcher("/JdbcFruitTable"); rd.forward(request, response); } catch (Exception e) { e.printStackTrace(); } }
このメソッドでは、データベータのアクセス処理がおこなわれる。 まず、必要な変数の初期化をおこなう。
Connection con = null; Statement stmt = null;
try節の中では、データベースに接続するConnectionオブジェクトの取得 をおこなう。ここでは、接続するデータベースのURLを "jdbc:mysql://localhost/test"、ユーザ名が"root"を、 パスワードを"tuis2019system"とする。
con = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "tuis2019system");それから、データベース操作を行うためのStatementオブジェクトの取得 をおこなう。
stmt = con.createStatement();
さらに、データベース操作に必要な値をrequestオブジェクトから 取得する。
String no = request.getParameter("no"); String name = request.getParameter("name"); String price = request.getParameter("price");
そして、実行するためのSQL文を作成する。
StringBuffer buf = new StringBuffer(); buf.append("update fruit set "); buf.append("name = '"); buf.append(name); buf.append("', price = '"); buf.append(price); buf.append("' where no = "); buf.append(no);
上記で作成されたSQL文を実行して、結果を得るために、以下のような 処理をおこなう。
stmt.executeUpdate(buf.toString());
finally節では、最終的におこなわれるデータベースとの接続が クローズが記述されている。
try { stmt.close(); } catch (Exception e) {} try { con.close(); } catch (Exception e) {}
そして、前述したデータベースを検索するServet
JdbcFruitTable.java
を呼び出すために、
RequestDispatcherオブジェクトを取得する。
ServletContext cx = getServletContext(); RequestDispatcher rd = cx.getRequestDispatcher("/JdbcFruitTable");
RequestDispatcherオブジェクトのforwardメソッドを呼び出すことで、 JdbcFruitTable.javaサーブレットを呼び出し、データベースの 検索をおこなう。
rd.forward(request, response);
通常、Servletでは、doGetメソッドとdoPostメソッドのどちら
かは必ず存在すると考えられる。JdbcUpdate.java
では、Servletでおこなう処理の内容を共通化して、同じ処理が
doGetメソッドとdoPostメソッドでおこなわれるようにしている。
doGetメソッドは、上述したJdbcFruitTable.java
の
doGetメソッドと同様に、引数にHttpServletRequestオブジェクトと
HttpServletRequestオブジェクトを取る。前者のオブジェクトには、
Servletへの入力が、後者のオブジェクトにはServletからの出力が
格納される。doGetメソッドの処理では、上述したprocessRequest
メソッドを呼び出す。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { processRequest(request, response); }
doPostメソッドは、ServletにHTTPリクエストのPOSTメソッドで アクセスされた時に、Servletコンテナから呼び出される。 通常、HTMLフォームを使ってブラウザからアクセスする時に、 このメソッドが呼び出される。doPostメソッドの処理でも、doGet メソッドと同様に、上述したprocessRequestメソッドを呼び出す。
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { processRequest(request, response); }
getServletInfoメソッドは、Servletに関する説明を表示する 場合に用いる。
public String getServletInfo() { return "Short description"; }
問題-1
JdbcFruitTable.java
を実行し、その結果も表示せよ。
問題-2
JdbcFruitTable.java
を参考にして、
"fruit"テーブルを、降順にpriceでソートし、no、
name、priceからなるテーブルを表示するプログラム
JdbcFruitTable1.java
を作成・実行し、その結果を表示せよ。
問題-3
JdbcFruitTable.java
を参考にして、
"fruit"テーブルから、noが4以上、またはnameがmeronであるレコードを検索し、
その結果を、no、name、priceからなるテーブルとして表示する
プログラムJdbcFruitTable2.java
を作成・実行し、
その結果を表示せよ。なお、このプログラムでは、表示されたテーブルの
レコード数も求めるものとする。
問題-4
JdbcFruitTable.java
を参考にして、
"fruit"テーブルから、priceが100から200までのレコードを
検索し、さらにpriceで昇順にソートした結果を、no、name、proceから
なるテーブルとして表示するプログラムJdbcFruitTable3.java
を作成・実行し、その結果を表示せよ。
問題-5
JdbcUpdate.java
を、上のJdbcUpdate.htmlから実行
し、その結果も表示せよ。