フィルタ

「フィルタ」の編集履歴(バックアップ)一覧はこちら

フィルタ」(2009/03/10 (火) 22:56:56) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

*&bold(){<filter>要素と<filter-mapping>要素} 例として「/hello/」で始まるURLでサーブレットが呼ばれた場合に適用するフィルタを作成する場合 <web-app> <filter> <filter-name> filtertest // ←フィルタ名 </filter-name> <filter-class> FilterTest // ←フィルタとして実行するサーブレットクラス名 </filter-class> </filter> <filter-mapping> <filter-name> filtertest // ←フィルタ名 </filter-name> <url-pattern> /hello/* // ←URLパターン </url-pattern> </filter-mapping> </web-app> フィルタを使う場合でも、もちろん<servlet>要素や<servlet-mapping>要素を記述する必要がある。 フィルタの記述する位置は<servlet>要素よりも前に記述する。 *&bold(){Filterインターフェース} "init"メソッド、"destroy"メソッド、"doFilter"メソッドを実装する。 import java.io.*; import javax.servlet.*; import javax.servlet.Filter; import javax.servlet.FilterChain; public class FilterTest implements Filter{ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){ try{ /* フィルタで行う処理 */ }catch (ServletException se){ }catch (IOException e){ } } public void init(FilterConfig filterConfig){ } public void destroy(){ } } 次のサーブレットへ処理を移すには、FilterChainインターフェースで定義されている"doFilter"メソッドを使用する。 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){ try{ /* フィルタで行う処理 */ chain.doFilter(request, response); }catch (ServletException se){ }catch (IOException e){ } } FilterChainインターフェースの"doFilter"メソッドを呼び出さずに、他のサーブレットへフォワードやリダイレクトしてフィルタの流れを切る事も可能。 if (認証が行われている) then{ chain.doFilter(request, response); }else{ ((HttpServletResponse)response).sendRedirect("/Login"); } |URL|http://localhost:8080/filter/helloworld| |アプリケーション配置場所|c:\servlet-sample\filter\| |web.xmlファイル|c:\servlet-sample\filter\WEB-INF\web.xml| |コンテキストファイル|C:\Program Files\Apache Software Foundation\Tomcat 5.5\conf\Catalina\localhost\filter.xml| ※2009.03.01時点でのバージョンは5.1.7 以下の順でダウンロードする。 +ここにアクセス http://dev.mysql.com/downloads/ +Drivers and ConnectorsのMySQL Connector/J — for connecting to MySQL from Javaの「MySQL Connector/J 5.1」 +Source and Binaries (zip)の「Pick a mirror」 +New Usersの「Proceed」 +画面下部の「No thanks, just take me to the downloads!」 +好きなミラーサイトの「HTTP」 +適当な場所にダウンロード -インストール +ダウンロードしたファイルを解凍(mysql-connector-java-5.1.7.zip) +解凍したフォルダ内のmysql-connector-java-5.1.7-bin.jarをTomcatをインストールしたフォルダ\common\lib\にコピーする。 *&bold(){JDBCドライバのロード} MySQLの場合は次のように行う。 try { Class.forName("com.mysql.jdbc.Driver").newInstance(); }catch (ClassNotFoundException e){ }catch (Exception e){ } |URL|http://localhost:8080/database/databasetest| |アプリケーション配置場所|c:\servlet-sample\database\| |web.xmlファイル|c:\servlet-sample\database\WEB-INF\web.xml| |コンテキストファイル|C:\Program Files\Apache Software Foundation\Tomcat 5.5\conf\Catalina\localhost\database.xml| *&bold(){データベースへの接続と切断} データベースへの接続を確立するには「DriverManager」クラスで用意されている"getConnection"メソッドを使う。 引数には接続するデータベースを表すURLと接続用のユーザー名とパスワードを指定する。 MySQLの場合、URLの形式は次のようになる。 jdbc:mysql://(サーバ名)/(データベース名) 例えばローカルホストにある「jdbctestdb」というデータベースに接続する場合は次のようになる。 jdbc:mysql://localhost/jdbctestdb 実際の使用例 Connection conn = null; String url = "jdbc:mysql://localhost/jdbctestdb"; String user = "testuser"; String password = "testpass"; try{ conn = DriverManager.getConnection(url, user, password); // データベースに対する処理 }catch (SQLException e){ } -データベースの切断 いったん接続した後に切断する場合には、接続の際に取得したConnectionインターフェースのオブジェクトに対して、"close"メソッドを使う。 "close"メソッドは何か問題が発生した際に忘れずに行うためにも、次のように"finally"節を使って記述する。 Connection conn = null; String url = "jdbc:mysql://localhost/jdbctestdb"; String user = "testuser"; String password = "testpass"; try{ conn = DriverManager.getConnection(url, user, password); // データベースに対する処理 }catch (SQLException e){ // 例外処理 }finally{ try{ if (conn != null){ conn.close(); } }catch (SQLException e){ // 例外処理 } } *&bold(){データベースの用意} データベース名は「jdbctestdb」とする。 +MySQLへ接続する: mysql -u root -p +パスワード応答 +データベースを作成する: create database jdbctestdb; +テスト用データベースに接続する: use jdbctestdb +テーブルを作成する: create table kabukatable(code int, company varchar(32), primary key(code) ); +ユーザの追加、権限設定: grant select,insert,update,delete on jdbctestdb.* to 'testuser'@'localhost' identified by 'testpass'; +データを追加する: 下記参照 +データを確認する: select * from kabukatable; &u(){データを追加する} ※コマンドプロンプトからINSERTしようとした場合、「ERROR 1366 (HY000): Incorrect string value: '\x83r\x83b\x83N...' for column 'com pany' at row 1」というエラーが発生し追加できない。これはどうやらMySQLインストール時に文字コードをutf-8にしたからの模様。正しい対処かどうかはわからないが、以下のSETコマンドを実行することでINSERTができるようになる。別セッションでSELECTしたりする場合は、毎回このSETを実行しないと文字化けする。 SET character_set_client = sjis; SET character_set_connection = utf8; SET character_set_results = sjis; insert into kabukatable values (3048,'ビックカメラ'), (4689,'ヤフー'), (4755,'RAKUTEN'), (9984,'SoftBank'); *&bold(){データベース接続テスト} |URL|http://localhost:8080/database/databasetest1| *&bold(){データの取得(SELECT)} -ステートメントを作成する Connection」インターフェースで定義されている"createStatement"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); -問い合わせの実行 「Statement」インターフェースで用意されている"executeQuery"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "SELECT * FROM kabukatable"; ResultSet rs = stmt.executeQuery(sql); -結果の取得 カーソルを動かすには「ResultSet」インターフェースで定義されている"next"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "SELECT * FROM kabukatable"; ResultSet rs = stmt.executeQuery(sql); while(rs.next()){ /* 行からデータを取得 */ int code = rs.getInt("code"); String company = rs.getString("company"); } データ型毎の値取得メソッド一覧(一部) boolean getBoolean(String columnName) byte getByte(String columnName) Date getDate(String columnName) double getDouble(String columnName) int getInt(String columnName) long getLong(String columnName) Timestamp getTimestamp(String columnName) -リソースの開放 使わなくなった「ResultSet」オブジェクトは"close"メソッドを使ってリソースを開放する。 また、「Statement」オブジェクトもに"close"メソッドを使ってリソースを開放する。 rs.close(); stmt.close(); |URL|http://localhost:8080/database/databasetest2| *&bold(){データの更新(UPDATE)} 「Statement」インターフェースで用意されている"executeUpdate"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "update kabukatable set company='楽天(株)' where code = 4755"; int num = stmt.executeUpdate(sql); |URL|http://localhost:8080/database/databasetest3| *&bold(){データの追加(INSERT)} 「Statement」インターフェースで用意されている"executeUpdate"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "insert into kabukatable (code, company) values (2491, 'バリューコマース')"; int num = stmt.executeUpdate(sql); *&bold(){データの削除(DELETE)} 「Statement」インターフェースで用意されている"executeUpdate"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "delete from kabukatable where id = 4755"; int num = stmt.executeUpdate(sql); *&bold(){prepareStatementの使用} 「Connection」インターフェースで定義されている"prepareStatement"メソッドを使う。 パラメータとして後から指定する部分には、実際の値を記述する替わりに「?」を記述したSQL文を作成し、そのSQLを元にプリペアドステートメントを作成する。 String sql = "insert into kabukatable (code, company) values (?, ?)"; PreparedStatement pstmt = conn.prepareStatement(sql); この例では実際に挿入する値を記述箇所に「?」を使っている。2箇所使っているので、後からパラメータを2つ指定する必要がある。 -パラメータへ値の設定 「PreparedStatement」インターフェースで用意されている「setInt」メソッドを使う。 パラメータの数だけメソッドを実行する。パラメータはSQL文中に記述された「?」を先頭から順番に1,2,3、・・・と順番に番号が割り当てられる。1番目のメソッドにはパラメータの番号を指定し、2番目の引数にパラメータに設定したい値を記述する。 String sql = "insert into kabukatable (code, company) values (?, ?)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setInt(1, 4755); pstmt.setString(2, "楽天(株)"); パラメータに値を設定するには設定する値のデータ型毎に別々のメソッドが用意されてる。(一部) |メソッド|説明| |void setString(int parameterIndex, String x)|String 値に設定します。| |void setInt(int parameterIndex, int x)|int 値に設定します。| |void setLong(int parameterIndex, long x)|long 値に設定します。| |void setByte(int parameterIndex, byte x)|バイト配列に設定します。| |void setFloat(int parameterIndex, float x)|float 値に設定します。| |void setDouble(int parameterIndex, double x)|double 値に設定します。| |void setDate(int parameterIndex, Date x)|java.sql.Date 値に設定します。| |void setTime(int parameterIndex, Time x)|java.sql.Time 値に設定します。| |void setBoolean(int parameterIndex, boolean x)|boolean 値に設定します。| |void setTimestamp(int parameterIndex, Timestamp x)|java.sql.Timestamp 値に設定します。| -プリペアドステートメントの実行 「PreparedStatement」インターフェースにはSELECTなどのクエリーの結果を取得する場合に使う「executeQuery」メソッドと、INSERTやUPDATEなどの結果が返されない場合に使う「executeUpdate」メソッドがある。この使い方は「Statement」の場合と同じ。 conn = DriverManager.getConnection(url, user, password); String sql = "insert into kabukatable (code, company) values (?, ?)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setInt(1, 4755); pstmt.setString(2, "楽天(株)"); int num = pstmt.executeUpdate(); -パラメータのクリア プリペアドステートメントを複数回続けて実行する場合、値が変更されないパラメータについては改めて設定する必要はない。 次の例では1番目のパラメータは変更が無く、2回目に実行する時には2番目のパラメータだけを設定する。 String sql = "insert into kabukatable (basho, company) values (?, ?)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setInt(1, "東証"); pstmt.setString(2, "ドコモ"); int num = pstmt.executeUpdate(); pstmt.setString(2, "KDDI"); num = pstmt.executeUpdate(); 現在設定されているパラメータを全て一度クリアしたい場合には「PreparedStatement」インターフェースで用意されている「clearParameters」メソッドを使う。 |URL|http://localhost:8080/database/databasetest6|
*&bold(){<filter>要素と<filter-mapping>要素} 例として「/hello/」で始まるURLでサーブレットが呼ばれた場合に適用するフィルタを作成する場合 <web-app> <filter> <filter-name> filtertest // ←フィルタ名 </filter-name> <filter-class> FilterTest // ←フィルタとして実行するサーブレットクラス名 </filter-class> </filter> <filter-mapping> <filter-name> filtertest // ←フィルタ名 </filter-name> <url-pattern> /hello/* // ←URLパターン </url-pattern> </filter-mapping> </web-app> フィルタを使う場合でも、もちろん<servlet>要素や<servlet-mapping>要素を記述する必要がある。 フィルタの記述する位置は<servlet>要素よりも前に記述する。 *&bold(){Filterインターフェース} "init"メソッド、"destroy"メソッド、"doFilter"メソッドを実装する。 import java.io.*; import javax.servlet.*; import javax.servlet.Filter; import javax.servlet.FilterChain; public class FilterTest implements Filter{ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){ try{ /* フィルタで行う処理 */ }catch (ServletException se){ }catch (IOException e){ } } public void init(FilterConfig filterConfig){ } public void destroy(){ } } 次のサーブレットへ処理を移すには、FilterChainインターフェースで定義されている"doFilter"メソッドを使用する。 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){ try{ /* フィルタで行う処理 */ chain.doFilter(request, response); }catch (ServletException se){ }catch (IOException e){ } } FilterChainインターフェースの"doFilter"メソッドを呼び出さずに、他のサーブレットへフォワードやリダイレクトしてフィルタの流れを切る事も可能。 if (認証が行われている) then{ chain.doFilter(request, response); }else{ ((HttpServletResponse)response).sendRedirect("/Login"); } |URL|http://localhost:8080/filter/helloworld| |アプリケーション配置場所|c:\servlet-sample\filter\| |web.xmlファイル|c:\servlet-sample\filter\WEB-INF\web.xml| |コンテキストファイル|C:\Program Files\Apache Software Foundation\Tomcat 5.5\conf\Catalina\localhost\filter.xml| *&bold(){フィルタを多重に設定する} <filter>要素と<filter-mapping>要素を複数記述すればよい。 フィルタの実行順は、<filter-mapping>が定義されている順となる。 <web-app> <filter> <filter-name>filtertest</filter-name> <filter-class>FilterTest</filter-class> </filter> <filter> <filter-name>filtertest2</filter-name> <filter-class>FilterTest2</filter-class> </filter> <filter-mapping> <filter-name>filtertest</filter-name> // ←最初に実行されるフィルタ <url-pattern>/hello/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>filtertest2</filter-name> // ←後に実行されるフィルタ <url-pattern>/hello/*</url-pattern> </filter-mapping> </web-app> *&bold(){<dispatcher>要素} サーブレットから別のサーブレットへフォワードされた時にフィルタが呼び出されるように設定することも可能。 <filter-mapping>要素の子要素の1つに<dispatcher>要素があり、<dispatcher>要素にどのタイミングでフィルタが実行されるのかを指定する。 |値|フィルタのタイミング| |REQUEST|URLがリクエストされた時| |FORWARD|フォワードが行われた時| |INCLUDE|インクルードが行われた時| |ERROR|エラーページへ処理が移る時| 1つの<filter-mapping>要素内で<dispatcher>要素は0回から4回まで設定出来、4つの全てのタイミングを指定することも可能。 <web-app> <filter> <filter-name>filtertest</filter-name> <filter-class>FilterTest</filter-class> </filter> <filter-mapping> <filter-name>filtertest</filter-name> <url-pattern>/hello/*</url-pattern> <dispatcher>FORWARD</dispatcher> </filter-mapping> </web-app>

表示オプション

横に並べて表示:
変化行の前後のみ表示: