教育サーバーのページ
オンラインテキスト目次
システムプログラミング演習
次のプログラム 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から実行
し、その結果も表示せよ。