JavaSer/javadrive/config

Last-modified: 2010-10-15 (金) 18:01:11

Tomcatで以下のエラーが出た時の対処法

 アクセスが拒否されました。
 Unable to open the service 'Tomcat6'

 http://www.javadrive.jp/servlet/install/index8.html

Javaのクラスパスについて

 クラスパスに半角が入っている( ...\Program Files\...) ため、
 サーブレットのプログラムがコンパイルエラーになってしまった。
 対処法としては、8.3形式のファイル名を使う方法があるらしい。
 8.3形式の名前は、cmdから "dir /x"で調べることができる。
 http://www.atmarkit.co.jp/fwin2k/win2ktips/606dirx/dirx.html

 ※ただし、NTFSのチューニングで8.3ファイル名が無効になっていたりする
  環境もあるので注意
  #無効にしたほうがパフォーマンスが良いので

システムにCLASSPATHを設定しても、eclipseには設定されない?

 ウィンドウ(W)→設定(P)→Java→ビルドパス→クラスパス変数
 から設定するか、
 プロジェクト名を右クリックして、ビルドパスを追加する(外部Jarの追加)

Tomcatのeclipseへの登録方法

 
 http://www.javadrive.jp/eclipse3/tomcat/

 eclipseのビューで、[サーバー]を表示しておくと、
 ビューの右上にある再生ボタンからTomcatの起動ができる。
 ※画面中央上の再生ボタン(プログラム実行ボタン)ではないので注意

 Tomcatはシステムで使用していると使えないので、
 PC起動時にTomcatを起動するようにしている場合は、
 [管理ツール]⇒[サービス]のApache Tomcatから[停止]し、
 また[手動]で起動するようにしておくとよい。

 また、eclipseのビューの[サーバー]から、
 サーバー・ロケーションを設定することができる。
 [Tomcatインストールを使用]にチェックを入れておくと、
 [サービス]からApache Tomcatを開始したときと同じ状況を再現できる

サーブレット動作時に必要なxmlファイル

(1)web.xml
 web.xmlは、設定しなくても静的なウェブページは見ることが可能だが、
 動的なページ(サーブレット)を動かすためには、web.xmlの設定が必要。

(2)xxx.xml
 これとは、別にコンテキストファイルというのが必要で、
  <Context path="/hello" docBase="d:/servlet-sample/helloworld"/>
 とすると、docBaseで示したフォルダに、http://localhost:8080/hello
 でアクセス可能になる(エイリアス?のようなもの)
 ファイル名は、pathの値と同じhello.xmlとする。

 配置は、web.xmlはサーブレットプログラムのWEB-INFの中で、
 コンテキストファイルは、
 [Tomcatインストールフォルダ]-[conf]-[Catalina]-[localhost]
 の中に配置する。

web.xmlの書き方

 
 作ったプログラムがHelloWorld.classのとき
 <servlet>
  <servlet-name>helloworld</servlet-name>
 <servlet-class>HelloWorld</servlet-class>
 </servlet>

 のようにすると、プログラムに名前をつけられる。
 この名前は下記のURLマッピングに使う。

 <servlet-mapping>
  <servlet-name>helloworld</servlet-name>
 <url-pattern>/hogehoge</url-pattern>
 </servlet-mapping>

 先ほど、付けた名前のサーブレットを、
 /hogehogeというURLで呼び出せるようにできる。

Tomcat開発で遭遇したミス

 1.index.htmlのパスを変えたのに内容が変わらない。
   →ブラウザのキャッシュのせい。F5を押下

 2.localhostのxmlを編集しても反映されない
   →Windows7が悪さしている?
    xmlファイルはCtrl+ドラッグでコピーしないで、
    新しくメモ帳を作ってカット&ペーストしたほうがよい。

サーブレットを呼び出したときに呼ばれるメソッド

 Javaサーブレットのパスを指定して呼び出したときは、
 サーブレットプログラム内のdoGetメソッドが呼ばれる。

サーブレットのライフサイクル

 サーブレットは最初に呼ばれたときにインスタンスが生成される。
 それ以降のリクエストは、すべてマルチスレッドで動作する。
 したがって、インスタンス変数は、それぞれのリクエストで共有される。
  →訪問数などを表示するときに使える

 対して、メソッド内に記述したローカル変数はスレッド毎に独立しており、
 別のスレッドはアクセスすることができない。

 上記の理由により、
 インスタンス変数の初期化はメソッド内で行ってはいけない。
 スレッドが新しく作られるたびに、初期化されてしまう。

 Tomcatを落としたりすると、インスタンスが破棄される

logを使う

 サーブレット中で
   log("カウント開始します");
 のようにすると、ログにコメントを書き出すことができる。
 logは、「(Tomcatをインストールしたディレクトリ)\Tomcat 6.0\logs」
 の中のテキストファイルである。(localhost.日付.log)

サーブレット中で文字コードを指定しなければ、

 latin1として認識されて、日本語は文字化けしてしまう。

フォームなどから送られてくるリクエストパラメータは、

 すべてString型として受信する。必要に応じて変換する。

 String vals[] = request.getParameterValues("name");
 のようにすると、名前に対応したすべての値を取得することが可能。

フォームから得た日本語文字列は、そのままでは文字化けしてしまう。

 ※サーブレット側がデフォルトでは、latin1として解釈しようとするため
 ※クライアント側が
  <meta http-equiv="Content-Type" Content="text/html;charset=Shift_JIS">
  のようにしてShift-JISを指定していても、
  サーブレット側に指定していないと文字化けする

文字化け対策

 対策として以下の方法がある。

 1)事前に文字コードを指定する方法
 2)一度誤って処理された文字列をバイト列に戻してから改めて
   正しい文字コードで文字列に戻す方法

(1)は「setCharacterEncoding」メソッドを使う
 request.setCharacterEncoding("Shift_JIS");
 requestはdoGetの第一引数
 簡易的な方法だが、リクエストボディに含まれる
 データの文字コードしか設定できない
 →POSTなら問題ないが、GETはURIにリクエストが含まれているため、
  文字コードの設定はできない。

(2)は
String val = request.getParameter("name");
byte[] byteData = val.getBytes("ISO_8859_1");

 のようにして、バイト列に戻す。ISO_8859_1は、latin1のこと。

val = new String(byteData, "Shift_JIS");

 のようにすれば、Shift_JISに直して、文字列になる。

 ※JISAutoDetectという自動判定もあるが、あまりアテにならない。
 ※クライアント側のHTMLページの文字コードを決めておき、
  サーブレット側でも特定の文字コードを指定したほうが無難

パラメータ名の取得

  request.getParameterNames();
 で、パラメータ名を取得することが可能。
 あまり必要性はないが、デバッグなどに有効

リクエストしたURIの取得

 getRequestURLやgetRequestURIでリクエストURIの取得

リクエスト方法の取得(プロトコルやGET/POSTなど)

 getScheme, getProtocol, getMethodでリクエスト方法の取得。
 HTTPやHTTPSなどが取得できるので、SSL通信が行われているかの判別に使用可能。

ヘッダーの名前や値も取得可能(クライアントによって値は異なる)

invoker

 Tomcat5より前のバージョンではweb.xmlを指定しなくても
 サーブレットを呼び出すことができたという仕組みのこと。

 しかし、クラスファイル名やディレクトリ構成が分かってしまうという
 セキュリティの問題上もあり、Tomcat5ではデフォルトで使えなくなっている。
 
 http://www.javadrive.jp/servlet/webxml/index3.html
 Tomcatフォルダのconf\web.xmlを編集することでinvokerを有効化する手順
 (ただし、テスト中などに限定して使用したほうが良い)

 個々のweb.xmlを編集して、個々にinvokerの有効無効を設定することも可能。
 使用はテスト時などに限ったほうが良い

web.xmlの<servlet-mapping>には、拡張子を含めたURIを指定してもよい。

 したがって、/index.htmlと見せかけてサーブレットを呼び出すことも可能。

URLパターンは、/hello*

 のように指定することが可能。
 
 /hello/index.html
 /hello/HelloWorld
 /hello/foofoo/hogehoge/hogehoge.jpg
 など、どのように指定しても同じサーブレットが呼ばれる。

 *.gifのようにして呼び出すことも可能

 '/'と"/*"という指定は異なる。
 前者をデフォルトマッピング、後者をパスマッピングといい、
 前者は優先順位が低いので、マッチしなかった場合に呼び出すサーブレットを
指定するのに適している

<servlet>には、子要素として、<init-param>を与えることが可能

 <init-param>
 <param-name>
 パラメータ名
 </param-name>

 <param-value>
 パラメータ値
 </param-value>
 </init-param>
 で指定が可能

 String ini = getInitParameter("パラメータ名");
 で取得が可能

 プログラムで初期値を指定する場合と違い、再コンパイルが必要ない。