2006年03月17日

●Tomcat アプリケーションの日本語化

今回は日本語をプロジェクトで扱えるようにしてみます。
strutsのAction Formはブラウザからのリクエストデータを格納する際、何もエンコード処理をしてくれませんので、何らかの方策をとらないと日本語がAction Formに文字化けして格納されてしまいます。


Servlet2.3から、Filter機能が実装されましたのでこれを利用しましょう。Tomcat5.0はServlet2.3に対応しています。Filterはリクエストデータがサーブレット(strutsの場合はAction Servlet)に届く前に処理される機能なので、ここでエンコード処理をほどこしていれば、Action以降のプログラムでいちいちエンコード用のプログラミングをする必要がなくなるわけです。(Filter機能がもしなかったら、Action Formのresetメソッドなりgetterなりで全部エンコードプログラミングしなきゃならないわけで…うぇ〜)


Filterとして登録するエンコード用クラスは、Tomcatでサンプルアプリケーションをインストールしていれば、<tomcatインストール先>webapps/examples/WEB-INF/classes/filters にSetCharacterEncodingFilter.javaがあるそうなのでそれを使います。ない場合は、ここからダウンロードしてください。


「filters」というパッケージを作成して、そこにSetCharacterEncodingFilter.javaを配置しましょう。


次に配置したフィルタがコンテナに使用されるように、web.xmlを編集します。WEB-INF/web.xmlをエディタで開いて、
<web-app>のすぐ下あたりに以下の記述をします。


  <!-- Jananese Encoding Filter Setting -->

  <filter>

    <filter-name>encodingFilter</filter-name>

    <filter-class>filters.SetCharacterEncodingFilter</filter-class>

    <init-param>

      <param-name>encoding</param-name>

      <param-value>Windows-31J</param-value>

    </init-param>

  </filter>



  <filter-mapping>

    <filter-name>encodingFilter</filter-name>

    <servlet-name>action</servlet-name>

  </filter-mapping>


また、struts-blankのコピーからアプリケーションを作成している場合、web.xmlのdtd定義が
古いです。Filterが利用できるよう、以下のようにヘッダーを編集しましょう。

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">


他にもいくつか約束事が。


1.作成するJSPファイルは全てエンコード「MS932」で保存してください。(eclipseのデフォルト・テキストファイル・エンコード)

2.JSPファイルの1行目には必ず以下の内容を記述してください。


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

3.<head>タグの中に以下のタグを記述してください。


<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">

これで準備完了。日本語文字をPOSTしてみてください。機種依存文字もかなりいけるはずです。(まるいち、とか、
かっこかぶ、とか)


…じゃGETは?というと、ここまでの対処じゃまだ化けてしまいます。

まずtomcatにGETリクエストの場合でもFilterを経由するように設定しなければなりません。
<tomcatインストール先>conf/server.xmlをエディタで開き、
「<Connector port="8009"…」で始まる箇所を探します。
「protocol="AJP/1.3"」の後ろ辺りに、


useBodyEncodingForURI="true"

を付加してください。(/>の前)


さらに、先ほど配置したSetCharacterEncodingFilterクラスを編集します。doFilterメソッドを以下のように書き換えてください。


public void doFilter(ServletRequest request, ServletResponse response,

    FilterChain chain) throws IOException, ServletException {



  // Conditionally select and set the character encoding to be used

  if (ignore || (request.getCharacterEncoding() == null)) {

    // リクエストがGETメソッドなら、UTF-8エンコーディングを使用

    if (request instanceof HttpServletRequest

        && "GET".equalsIgnoreCase(((HttpServletRequest) request)

            .getMethod())) {

      request.setCharacterEncoding("UTF-8");

    // リクエストがPOSTメソッドなら、web.xmlに指定した文字エンコーディングを使用

    } else {

      String encoding = selectEncoding(request);

      if (encoding != null)

        request.setCharacterEncoding(encoding);

    }

  }



  // Pass control on to the next filter

  chain.doFilter(request, response);



}


おまけ:
ブラウザからのリクエストデータを、データベースに格納する際、以下の注意が必要です。
・データベースがPostgreSQLでかつ、データ文字コードがEUC-JP
  =>問題無し

・データベースがOracleでかつ、データ文字コードがJA16SJIS、またはJA16EUCの場合
  =>「〜」が化ける


詳細は、翔泳社のDBマガジン2006年2月号の特集記事を参照ください。
で、Oracleの「〜」が化け対処方法は、
・データ文字コードJA16SJISTILDEにするか、JA16EUCTILDEにすることです。


一度作成したデータベースの文字コードは変更できませんので、expユーティリティでデータ退避の上再作成しかないですね…

2006年02月10日

●Tomcatプロジェクトの作成

インストールしたSysdeo Tomcat プラグインで簡単なアプリケーションを作成してみましょう。


シナリオはこんな感じです
1.hello.htmlで名前をテキストに入力
2.送信ボタンでhelloサーブレットに送信
3.helloサーブレットは「こんにちは **さん」というHTMLを表示


ではまずプロジェクトを作成しましょう。パッケージ・エクスプローラー上で右クリックし、表示されたメニューから「新規」-「プロジェクト」を選択します。「ウィザードを選択」では、「Java」-「Tomcat プロジェクト」を選択して「次へ」ボタンを押します。


プロジェクト名と、保存先を設定します。

ここではプロジェクト名を「sampleapp」とします。また、Tomcatのアプリケーションコンテキスト名となります。

保存先はデフォルトで <eclipseインストール先>workspace\プロジェクト名 となっています。変更したい場合は「デフォルトの使用」チェックを外して「ディレクトリー」テキストに場所を指定します。変更する場合は、パス末尾のディレクトリ名がプロジェクト名となるようにしましょう。


Tomcat プロジェクトの設定をおこないます。デフォルトのままでよいでしょう。


パッケージ・エクスプローラーに作成したプロジェクトが表示されます。

実際に指定したディレクトリ下に、Tomcatアプリケーションに必要なディレクトリ(WEB-INFとか)が作成され、各種ライブラリに対してのクラスパスも設定されています。


ではサーブレットを作りましょう。Javaクラスはパッケージエクスプローラーの「WEB-INF/src」下に作成します。また、パッケージ・エクスプロ−ラーではフィルタリングされ表示されませんが、「WEB-INF/src」に作成したJavaクラスソースは保存・更新のたびに「WEB-INF/classes」にコンパイルされて保存されます。

とりあえずサーブレットクラスを収めるために一つパッケージを作りましょう。「WEB-INF/src」の上で右クリックしてメニューを出し、「新規」-「パッケージ」を選択します。

パッケージ名は「hello」とでもしてOKボタンを押します。


次に作成された「hello」パッケージの上で右クリックしてメニューを出し、「新規」-「クラス」を選択します。


名前に「HelloServlet」と入力します。また、サーブレットなのでHttpServletクラスを継承する必要があります。eclipseでは親クラスを簡単に指定できます。「スーパークラス」行の「参照」ボタンを押します。


「スーパークラスの選択」ダイアログで、「型を選択してください」というテキストに、頭の「httpse」くらいまでで入力します。そうすると1文字入力するごとに、下の「一致する型」リストに入力文字でフィルタリングされたクラスが表示されます。リスト内で目的のクラスが特定できたら、クリックして青色反転させOKボタンを押します。

長いクラス名を入力する手間が省けるとともに、TYPOの抑制にもなりますね。


作成されたサーブレットのクラス名に警告の黄色い破線が表示されているかもしれません。HttpServletクラスはjava.io.Serializableインターフェイスをインクリメントしているため、serialVersionUIDを設定しないとこの警告が出ます。
要件にもよりますが、警告を止めてもかまわない場合は、メニュー「ウィンドウ」-「設定」で設定ダイアログを表示し、「Java」-「コンパイラー」-「エラー/警告」の、「潜在的なプログラミングの問題」の一番上「serialVersionUIDなしのシリアライズ可能クラス」の設定を「無視」にします。

これ出たらOKボタン。


今回はHTMLからサーブレットに対してPOSTさせるシナリオですので、doPostメソッドを実装しなければなりません。eclipseではメソッドのオーバーライド指定も簡単です。クラスソース内で右クリックして表示されるメニューから、「ソース」-「メソッドのオーバーライド/実装」を選択します。


スーパークラスのメソッドが一覧で表示されるので、オーバーライドしたいメソッドのチェックを押し、OKボタンを押します。


メソッドが貼りつきました。まぁ実装は自分で書かなければならないわけなんですが、引数や戻り値の型などでTYPOすることは無くなるわけです。引数の変数名は親クラスの実装のまま(doPostメソッドであれば、HttpServletRequest型の第1引数が「arg0」、HttpServletResponse型の第2引数が「arg1」)なので、お好みで変更します。今回は、「req」「res」としました。

タブとして表示されているクラス名の左に「*」が表示されていますが、これは「編集中」である、ということを表しています。ショートカットキー「Ctrl」+「S」で保存できます。


POST値を表示するコードを書きます。下の例ではまだ PriterWriter クラスをインポートしていないため、赤破線のエラーがついています。エラー個所にマウスカーソルを持っていくと、エラー内容がツールチップ表示されます。


ソースファイル上で右クリック(どこでも)して表示されるメニューから「ソース」-「インポートの編成」を選択します。これで自動的に必要なimport文が追加されます。複数箇所ある場合も一括で解決されます。クラスパスが通っているライブラリ中に複数の同名クラスがある場合は、一覧選択するダイアログが表示されます。


次にHTMLファイルを作成します。アプリケーションコンテキストルート下ならどこでも良いですが、「WEB-INF」や「WEB-INF/src」の下はJavaクラスだけを置くので避けましょう。また、ルート直下でも良いですが、数が増えてくると管理しずらくなるので、HTML用のディレクトリを作成しましょう。
「sampleapp」上で右クリックしてメニューを表示し、「新規」-「フォルダー」を選択します。

フォルダ名は「hello」とでもしてOKボタンを押します。

同様に、「sampleapp\pages」下に「hello」ディレクトリを作成しました。
また、ディレクトリの作成と同じ要領で、作成された「hello」ディレクトリ上で右クリックし、メニューの「新規」-「ファイル」を選択し、「hello.html」を作成しました。


作成された「hello.html」を編集しましょう。拡張子「.html」はデフォルトで、eclipse内部ブラウザに関連付けられているため、エディターで開くように指定します。「hello.html」ファイルを右クリックし、メニューの「アプリケーションから開く」-「テキスト・エディター」を選択します。


送信用のHTMLファイルを記述します。今はただのテキストエディターなので、タグによる色分けやコード・アシスタント機能はありません。今後のエントリーで、HTMLやJSPファイル用のプラグインを紹介していく予定です。


最後にアプリケーション用のweb.xmlファイルを作成します。「WEB-INF」上で右クリックし、表示されるメニューから「新規」-「ファイル」を選択します。(WEB-INF/src にしないように注意!)
ファイル名に「web.xml」を入力しOKボタンを押します。


web.xmlファイルに、サーブレットのマッピング情報を記述します。ここでもただのテキストエディターなので、そっけない感じですが、プラグインを入れれば管理しやすくできます。(今後のエントリー参照)


最後にデバッグの準備として「デバッグ」パースペクティブを表示しておきましょう。メニュー「ウィンドウ」-「パースペクティブを開く」-「デバッグ」です。一度開くとeclipseは状態を記憶し、再起動してもパースペクティブの表示は残ります。


ではTomcatを起動しましょう。既にTomcatが起動している場合は必ず終了させてから、ecilpse&Sysdeo Tomcat プラグインによるTomcat起動をおこなってください。起動は簡単、ツールボタンのにゃんこちゃんを押すだけです。左のボタンから、開始・停止・再起動となっています。


コンソールビューにわらわら〜、と起動状態が標準出力されます。「情報:Server startup」で起動完了です。


新しくTomcatアプリケーションが作成されたので、JK2設定も追加しておきます。<Apacheインストール先>\conf\workers2.properties ファイルをエディタで開き、uri設定を追加します。今回のアプリケーションは「sampleapp」なので、以下のとおりとなります。

workers2.properties を編集したら忘れずにApacheを再起動してください。


では、ブラウザからhtmlファイルを開きましょう。今回のサンプルだと「http://localhost/sampleapp/pages/hello/hello.html」となります。


名前を入力して送信ボタンを押すと…
表示されましたね?

2006年01月31日

●Tomcat5.0のインストール

Tomcatのインストールをおこないます。5.5系もリリースされていますが、ここでは5.0のインストールをおこないます。
事前にJ2SE SDKのインストールがおこなわれている必要があります。


Apache jakarta Projectのダウンロードサイトにアクセスし、下の方「5.0.X」-「Binary Distributions」-「Core」-「zip Windows Executable」リンクをクリックします。


ダウンロード先を指定して(どこでも)、「jakarta-tomcat-5.0.*.exe」を保存します。


保存したインストーラーを実行します。


使用許諾契約条項に同意します。


インストールする機能を選択します。

「Documentation」と「Examples」は必要なければ外します(ケチくさい?)


インストール先を指定します。

どこでもいいのですが、あまり深い階層になりすぎないようにするのと、フォルダ名に半角スペースが入らないように注意しましょう。Tomcat自身は半角スペースがあっても問題ないようですが、他関連ソフトウェアを考慮してのことです。初期値としてのインストール先は、「Apache Software Foundation」「Tomcat 5.0」と、半角スペースが入っていますのでご注意を。


ポート番号および、Tomcat管理者のアカウントを設定します。

後でApacheと連携させるので、Tomcatの8080ポートはリスニングを止めるわけですが、ま、ここはこれで。


JAVA_HOME環境変数が設定されていれば、ここで正しく表示されるはずです。

表示されない場合は、J2SE SDKのインストールをもう一度確認しましょう。


インストール開始。しばらく待ちます。


インストール完了。

Readmeは後でじっくり読むとして、早速Tomcatを起動してみましょう。ワクワク。
「Run Apache Tomcat」だけチェックをONにして「Finish」ボタンを押します。


右下タスクトレイに、Tomcatのアイコンが現れます。


アイコンを右クリックして表示されるメニューから「Start service」を選択します。


ブラウザから「http://localhost:8080」にアクセスしてみましょう。

にゃんこちゃんが現れれば完了です。

2006年01月27日

●struts-config.xmlの再ロード

strutsフレームワークを利用しての開発で困りものなのが、struts-config.xml編集後に変更を反映させること。tomcatの再起動時間かかるもんなぁ。
ちょい調べたら、tomcat管理メニューから再起動することなく設定ファイルの再ロードができることがわかりました。もちvalidation.xmlとかも。

1.<tomcat home>/conf/tomcat-users.xml をエディタで開き
 「manager」「admin」ロールを持つユーザーを追加
 ex. <user username="takeshi" password="passpass" roles="admin,manager"/>

2.ブラウザから <managerコンテキストルート>/htmlにアクセス
ex. http://localhost/manager/html

3.上で設定したユーザーでログイン

4.アプリケーションの一覧から、再ロードさせたいアプリケーションの
 「再ロード」リンクをクリック

当然ながら、<tomcat home>/server/webapps/manager のアプリケーションが
動く状態でなければなりません。