■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 2009年03月15日 Java総合講座 - 初心者から達人へのパスポート vol.144 セルゲイ・ランダウ バックナンバー: http://www.flsi.co.jp/Java_text/ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ [このメールマガジンは、画面を最大化して見てください。] ======================================================== ◆ 01.SOAPのアプリケーション(Webサービス) ======================================================== では、今回は、Propertiesクラスを使ってプロパティー・ファイルを を読み出し、プロパティーの値を取り出す方法を説明します。 まず、プロパティー・ファイルを読み出すためには、Propertiesクラスの load()メソッドを使用します。このメソッドの引数には、InputStream型 のオブジェクトが指定できますので、例えば Properties properties = new Properties(); properties.load(new FileInputStream("nantoka.properties")); のようにして、プロパティー・ファイルを指定することができます。 しかし、このときファイルの置き場所が問題になります。 現在使っているAxisはTomcatのアプリケーションとして実行されますが、 Tomcatのアプリケーションでは、プロパティー・ファイルはclassesディレ クトリーに置くのが標準になっています。ところが、このclassesディレク トリー(現在の絶対パスはC:\Tomcat6.0\webapps\axis\WEB-INF\classesに なっている)の絶対パスはTomcatのインストールの仕方によって異なります から、Webサービスのプログラムの中で明記する訳にはいきません。 しかし、幸いにもclassesディレクトリーはこのWebサービス(Tomcatのアプ リケーション)を起動する際にクラス・ローダーがクラスを探してくる場所 (いわゆるクラスパス)なので、クラス・ローダーが認識しています。 そのため、例えば次のようにして、クラス・ローダーにプロパティー・ファ イルを探させて、Propertiesクラスのload()メソッドで読み出すということ が可能になります。 InputStream inputStream = getClass().getClassLoader().getResourceAsStream("nantoka.properties"); properties.load(inputStream); ここで、getClass()はすべてのオブジェクトのスーパークラスであるObjectクラスの メソッドで、現在のオブジェクトのクラスを表すClassクラスのインスタンスを返し ます。(このClassという名前のクラスは、クラスを管理するクラスで一般には 「メタ・クラス」と呼ばれるものです。Classというクラスは既にvol.023でも 出てきました。このClassというクラスのインスタンスは各クラスを表します。 たとえば、このインスタンスのgetName()メソッドを実行すると、そのオブジェクト のクラス名を返してくれます。) ここでは、そのClassクラスのインスタンスのgetClassLoader()メソッドを実行する ことによって、そのクラスをロードしたクラス・ローダーを呼び出しています。 そして、そのクラス・ローダーのgetResourceAsStream()メソッドを呼び出すこと によって、その引数に指定したファイルをクラスパスから探させて、そのファイルを 読み込むためのInputStreamオブジェクトを作成させています。 そうすれば、あとはPropertiesクラスのload()メソッドの引数にそのInputStreamオブ ジェクトを指定してやれば、そのプロパティー・ファイルを読み込める訳です。 では、この仕組みを使って、"runmode.properties"というファイル名のプロパティー・ファイル を読み込むように、HotelSoapBindingImplクラスを編集してみましょう。 Eclipseを起動してHotelSoapBindingImpl.javaを下記のように編集してください。 -------------------------------------------------------- /** * HotelSoapBindingImpl.java * * このファイルはWSDLから自動生成されました / [en]-(This file was auto-generated from WSDL) * Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java生成器によって / [en]-(by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter.) */ package jp.co.flsi.lecture.webservice.hotel; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.util.Properties; import java.util.Vector; import javax.naming.Context; import javax.naming.InitialContext; import javax.sql.DataSource; import org.apache.log4j.Logger; public class HotelSoapBindingImpl implements jp.co.flsi.lecture.webservice.hotel.Hotel{ Logger logger = Logger.getLogger(HotelSoapBindingImpl.class); public jp.co.flsi.lecture.webservice.hotel.RoomInfo[] findRooms(jp.co.flsi.lecture.webservice.hotel.StayInfoInput stayInfo) throws java.rmi.RemoteException { logger.info("HotelSoapBindingImpl.findRooms()を開始します。 ..............."); Vector<RoomInfo> roomInfoVector = new Vector<RoomInfo>(); InputStream inputStream = getClass().getClassLoader().getResourceAsStream("runmode.properties"); if(inputStream != null) { Properties properties = new Properties(); try { properties.load(inputStream); } catch (IOException e1) { logger.error(e1); } String testValue = properties.getProperty("test"); if (testValue != null && testValue.equals("yes")) { RoomInfo roomInfo0 = new RoomInfo(); roomInfo0.setRoomNum(100); roomInfo0.setCapacity(2); roomInfo0.setRatePerNight(20000); roomInfo0.setRoomType("SINGLE"); roomInfo0.setWebBrowsable(true); roomInfoVector.add(roomInfo0); return roomInfoVector.toArray(new RoomInfo[roomInfoVector.size()]); } } try{ Context initCtx = new InitialContext(); if(initCtx == null) throw new Exception("Error: InitialContext could not be generated!"); DataSource ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/HOTELDB"); if (ds != null) { Connection conn = ds.getConnection(); if(conn != null) { Statement selectSql = conn.createStatement(); ResultSet rs = selectSql.executeQuery("SELECT * FROM ROOMINFO"); while (rs.next()) { RoomInfo roomInfo = new RoomInfo(); roomInfo.setRoomNum(rs.getInt("ROOMNUM")); logger.info("ROOMNUM = " + rs.getInt("ROOMNUM")); roomInfo.setCapacity(rs.getInt("CAPACITY")); roomInfo.setRatePerNight(rs.getInt("RATE")); roomInfo.setRoomType(rs.getString("TYPE")); if ("Y".equals(rs.getString("WEB"))) { roomInfo.setWebBrowsable(true); logger.debug("roomInfo.setWebBrowsable(true);の行が実行されました。"); } else { roomInfo.setWebBrowsable(false); logger.debug("roomInfo.setWebBrowsable(false);の行が実行されました。"); } roomInfoVector.add(roomInfo); } selectSql.close(); conn.close(); } } } catch(Exception e) { logger.error(e); } finally { logger.info("HotelSoapBindingImpl.findRooms()を終了します。 ..............."); } return roomInfoVector.toArray(new RoomInfo[roomInfoVector.size()]); } public boolean reserveRoom(jp.co.flsi.lecture.webservice.hotel.RoomReserveInfo roomReserve) throws java.rmi.RemoteException { return false; } } -------------------------------------------------------- ここで、getProperty()というメソッドは、プロパティーの値を取り出すメソッドで、 引数にはプロパティーの名前(通常、「キー」と呼ぶ)を指定します。 ここでは、"runmode.properties"というプロパティー・ファイルの中に test=yes という指定(つまり、"test"というキーに対して"yes"という値が指定されている場合) があった場合には、データベースにはアクセスせずに、テスト用のデータを返すように findRooms()メソッドを編集しています。 では、C:\Tomcat6.0\webapps\axis\WEB-INF\classesフォルダーの中に、 下記のような内容のファイルを作成し、runmode.propertiesというファイル名 にして下さい。 -------------------------------------------------------- secure=yes test=yes -------------------------------------------------------- ここで実際に読み込みたいプロパティーは2行目なんですが、"test"というキーが ちゃんと読まれることを確認するために、1行目には別のキーを指定しています。 では、これらのファイルの編集が終わったら、保管したあと、前回と同じく 再度、デプロイを行い、再度HotelClientを実行してみて下さい。 今度は、上でHotelSoapBindingImpl.javaを編集した通り、テスト用のデータが 返され、コンソールに ============================================== Room number : 100 Room capacity : 2 Rate per night : 20000 Room type : SINGLE Web browsable : true ============================================== という結果が返ってきますね。 これで、ちゃんとプロパティー・ファイルが読み込まれたことがわかります。 (次回に続く) では、今日はここまでにします。 ================================================ ◆ 02.演習問題 ================================================ 今回はHotelSoapBindingImpl.javaのプログラムを編集して、findRooms()メソッド がデータベースにはアクセスせずに、テスト用のデータを返すようにしましたが、 このテスト用のデータは返さずに、前回と同じようにデータベースのデータを 返すようにするには、runmode.propertiesファイルをどう編集すればいいで しょうか。実際にrunmode.propertiesファイルを編集して試してみて下さい。 ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ★ホームページ: http://www.flsi.co.jp/Java_text/ ★このメールマガジンは 「まぐまぐ(http://www.mag2.com)」 を利用して発行しています。 ★バックナンバーは http://www.flsi.co.jp/Java_text/ にあります。 ★このメールマガジンの登録/解除は下記Webページでできます。 http://www.mag2.com/m/0000193915.html ★このメールマガジンへの質問は下記Webページにて受け付けて います。わからない所がありましたら、どしどしと質問をお寄 せください。 http://www.flsi.co.jp/Java_text/ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ Copyright (C) 2009 Future Lifestyle Inc. 不許無断複製 |